xref: /openbsd-src/sys/arch/i386/i386/bus_space.c (revision f4e7063748a2ac72b2bab4389c0a7efc72d82189)
1 /*	$OpenBSD: bus_space.c,v 1.10 2023/01/30 10:49:04 jsg Exp $ */
2 /*-
3  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to The NetBSD Foundation
7  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
8  * NASA Ames Research Center.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
34  * Copyright (c) 1996 Jason R. Thorpe.  All rights reserved.
35  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. All advertising materials mentioning features or use of this software
46  *    must display the following acknowledgement:
47  *	This product includes software developed by Christopher G. Demetriou
48  *	for the NetBSD Project.
49  * 4. The name of the author may not be used to endorse or promote products
50  *    derived from this software without specific prior written permission
51  *
52  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
54  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
55  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
56  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
57  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
61  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62  */
63 
64 #include <sys/param.h>
65 
66 #include <machine/bus.h>
67 
68 u_int8_t	i386_bus_space_io_read_1(bus_space_handle_t, bus_size_t);
69 u_int16_t	i386_bus_space_io_read_2(bus_space_handle_t, bus_size_t);
70 u_int32_t	i386_bus_space_io_read_4(bus_space_handle_t, bus_size_t);
71 
72 void		i386_bus_space_io_read_multi_1(bus_space_handle_t, bus_size_t,
73 		    u_int8_t *, bus_size_t);
74 void		i386_bus_space_io_read_multi_2(bus_space_handle_t, bus_size_t,
75 		    u_int16_t *, bus_size_t);
76 void		i386_bus_space_io_read_multi_4(bus_space_handle_t, bus_size_t,
77 		    u_int32_t *, bus_size_t);
78 
79 void		i386_bus_space_io_read_region_1(bus_space_handle_t, bus_size_t,
80 		    u_int8_t *, bus_size_t);
81 void		i386_bus_space_io_read_region_2(bus_space_handle_t, bus_size_t,
82 		    u_int16_t *, bus_size_t);
83 void		i386_bus_space_io_read_region_4(bus_space_handle_t, bus_size_t,
84 		    u_int32_t *, bus_size_t);
85 
86 void		i386_bus_space_io_write_1(bus_space_handle_t, bus_size_t,
87 		    u_int8_t);
88 void		i386_bus_space_io_write_2(bus_space_handle_t, bus_size_t,
89 		    u_int16_t);
90 void		i386_bus_space_io_write_4(bus_space_handle_t, bus_size_t,
91 		    u_int32_t);
92 
93 void		i386_bus_space_io_write_multi_1(bus_space_handle_t,
94 		    bus_size_t, const u_int8_t *, bus_size_t);
95 void		i386_bus_space_io_write_multi_2(bus_space_handle_t,
96 		    bus_size_t, const u_int16_t *, bus_size_t);
97 void		i386_bus_space_io_write_multi_4(bus_space_handle_t,
98 		    bus_size_t, const u_int32_t *, bus_size_t);
99 
100 void		i386_bus_space_io_write_region_1(bus_space_handle_t,
101 		    bus_size_t, const u_int8_t *, bus_size_t);
102 void		i386_bus_space_io_write_region_2(bus_space_handle_t,
103 		    bus_size_t, const u_int16_t *, bus_size_t);
104 void		i386_bus_space_io_write_region_4(bus_space_handle_t,
105 		    bus_size_t, const u_int32_t *, bus_size_t);
106 
107 void		i386_bus_space_io_set_multi_1(bus_space_handle_t, bus_size_t,
108 		    u_int8_t, size_t);
109 void		i386_bus_space_io_set_multi_2(bus_space_handle_t, bus_size_t,
110 		    u_int16_t, size_t);
111 void		i386_bus_space_io_set_multi_4(bus_space_handle_t, bus_size_t,
112 		    u_int32_t, size_t);
113 
114 void		i386_bus_space_io_set_region_1(bus_space_handle_t, bus_size_t,
115 		    u_int8_t, size_t);
116 void		i386_bus_space_io_set_region_2(bus_space_handle_t, bus_size_t,
117 		    u_int16_t, size_t);
118 void		i386_bus_space_io_set_region_4(bus_space_handle_t, bus_size_t,
119 		    u_int32_t, size_t);
120 
121 void		i386_bus_space_io_copy_1(bus_space_handle_t, bus_size_t,
122 		    bus_space_handle_t, bus_size_t, size_t);
123 void		i386_bus_space_io_copy_2(bus_space_handle_t, bus_size_t,
124 		    bus_space_handle_t, bus_size_t, size_t);
125 void		i386_bus_space_io_copy_4(bus_space_handle_t, bus_size_t,
126 		    bus_space_handle_t, bus_size_t, size_t);
127 
128 void *		i386_bus_space_io_vaddr(bus_space_handle_t);
129 paddr_t		i386_bus_space_io_mmap(bus_addr_t, off_t, int, int);
130 
131 const struct i386_bus_space_ops i386_bus_space_io_ops = {
132 	i386_bus_space_io_read_1,
133 	i386_bus_space_io_read_2,
134 	i386_bus_space_io_read_4,
135 	i386_bus_space_io_read_multi_1,
136 	i386_bus_space_io_read_multi_2,
137 	i386_bus_space_io_read_multi_4,
138 	i386_bus_space_io_read_region_1,
139 	i386_bus_space_io_read_region_2,
140 	i386_bus_space_io_read_region_4,
141 	i386_bus_space_io_write_1,
142 	i386_bus_space_io_write_2,
143 	i386_bus_space_io_write_4,
144 	i386_bus_space_io_write_multi_1,
145 	i386_bus_space_io_write_multi_2,
146 	i386_bus_space_io_write_multi_4,
147 	i386_bus_space_io_write_region_1,
148 	i386_bus_space_io_write_region_2,
149 	i386_bus_space_io_write_region_4,
150 	i386_bus_space_io_set_multi_1,
151 	i386_bus_space_io_set_multi_2,
152 	i386_bus_space_io_set_multi_4,
153 	i386_bus_space_io_set_region_1,
154 	i386_bus_space_io_set_region_2,
155 	i386_bus_space_io_set_region_4,
156 	i386_bus_space_io_copy_1,
157 	i386_bus_space_io_copy_2,
158 	i386_bus_space_io_copy_4,
159 	i386_bus_space_io_vaddr,
160 };
161 
162 u_int8_t	i386_bus_space_mem_read_1(bus_space_handle_t, bus_size_t);
163 u_int16_t	i386_bus_space_mem_read_2(bus_space_handle_t, bus_size_t);
164 u_int32_t	i386_bus_space_mem_read_4(bus_space_handle_t, bus_size_t);
165 
166 void		i386_bus_space_mem_read_multi_1(bus_space_handle_t, bus_size_t,
167 		    u_int8_t *, bus_size_t);
168 void		i386_bus_space_mem_read_multi_2(bus_space_handle_t, bus_size_t,
169 		    u_int16_t *, bus_size_t);
170 void		i386_bus_space_mem_read_multi_4(bus_space_handle_t, bus_size_t,
171 		    u_int32_t *, bus_size_t);
172 
173 void		i386_bus_space_mem_read_region_1(bus_space_handle_t, bus_size_t,
174 		    u_int8_t *, bus_size_t);
175 void		i386_bus_space_mem_read_region_2(bus_space_handle_t, bus_size_t,
176 		    u_int16_t *, bus_size_t);
177 void		i386_bus_space_mem_read_region_4(bus_space_handle_t, bus_size_t,
178 		    u_int32_t *, bus_size_t);
179 
180 void		i386_bus_space_mem_write_1(bus_space_handle_t, bus_size_t,
181 		    u_int8_t);
182 void		i386_bus_space_mem_write_2(bus_space_handle_t, bus_size_t,
183 		    u_int16_t);
184 void		i386_bus_space_mem_write_4(bus_space_handle_t, bus_size_t,
185 		    u_int32_t);
186 
187 void		i386_bus_space_mem_write_multi_1(bus_space_handle_t,
188 		    bus_size_t, const u_int8_t *, bus_size_t);
189 void		i386_bus_space_mem_write_multi_2(bus_space_handle_t,
190 		    bus_size_t, const u_int16_t *, bus_size_t);
191 void		i386_bus_space_mem_write_multi_4(bus_space_handle_t,
192 		    bus_size_t, const u_int32_t *, bus_size_t);
193 
194 void		i386_bus_space_mem_write_region_1(bus_space_handle_t,
195 		    bus_size_t, const u_int8_t *, bus_size_t);
196 void		i386_bus_space_mem_write_region_2(bus_space_handle_t,
197 		    bus_size_t, const u_int16_t *, bus_size_t);
198 void		i386_bus_space_mem_write_region_4(bus_space_handle_t,
199 		    bus_size_t, const u_int32_t *, bus_size_t);
200 
201 void		i386_bus_space_mem_set_multi_1(bus_space_handle_t, bus_size_t,
202 		    u_int8_t, size_t);
203 void		i386_bus_space_mem_set_multi_2(bus_space_handle_t, bus_size_t,
204 		    u_int16_t, size_t);
205 void		i386_bus_space_mem_set_multi_4(bus_space_handle_t, bus_size_t,
206 		    u_int32_t, size_t);
207 
208 void		i386_bus_space_mem_set_region_1(bus_space_handle_t, bus_size_t,
209 		    u_int8_t, size_t);
210 void		i386_bus_space_mem_set_region_2(bus_space_handle_t, bus_size_t,
211 		    u_int16_t, size_t);
212 void		i386_bus_space_mem_set_region_4(bus_space_handle_t, bus_size_t,
213 		    u_int32_t, size_t);
214 
215 void		i386_bus_space_mem_copy_1(bus_space_handle_t, bus_size_t,
216 		    bus_space_handle_t, bus_size_t, size_t);
217 void		i386_bus_space_mem_copy_2(bus_space_handle_t, bus_size_t,
218 		    bus_space_handle_t, bus_size_t, size_t);
219 void		i386_bus_space_mem_copy_4(bus_space_handle_t, bus_size_t,
220 		    bus_space_handle_t, bus_size_t, size_t);
221 
222 void *		i386_bus_space_mem_vaddr(bus_space_handle_t);
223 paddr_t		i386_bus_space_mem_mmap(bus_addr_t, off_t, int, int);
224 
225 const struct i386_bus_space_ops i386_bus_space_mem_ops = {
226 	i386_bus_space_mem_read_1,
227 	i386_bus_space_mem_read_2,
228 	i386_bus_space_mem_read_4,
229 	i386_bus_space_mem_read_multi_1,
230 	i386_bus_space_mem_read_multi_2,
231 	i386_bus_space_mem_read_multi_4,
232 	i386_bus_space_mem_read_region_1,
233 	i386_bus_space_mem_read_region_2,
234 	i386_bus_space_mem_read_region_4,
235 	i386_bus_space_mem_write_1,
236 	i386_bus_space_mem_write_2,
237 	i386_bus_space_mem_write_4,
238 	i386_bus_space_mem_write_multi_1,
239 	i386_bus_space_mem_write_multi_2,
240 	i386_bus_space_mem_write_multi_4,
241 	i386_bus_space_mem_write_region_1,
242 	i386_bus_space_mem_write_region_2,
243 	i386_bus_space_mem_write_region_4,
244 	i386_bus_space_mem_set_multi_1,
245 	i386_bus_space_mem_set_multi_2,
246 	i386_bus_space_mem_set_multi_4,
247 	i386_bus_space_mem_set_region_1,
248 	i386_bus_space_mem_set_region_2,
249 	i386_bus_space_mem_set_region_4,
250 	i386_bus_space_mem_copy_1,
251 	i386_bus_space_mem_copy_2,
252 	i386_bus_space_mem_copy_4,
253 	i386_bus_space_mem_vaddr,
254 };
255 
256 u_int8_t
i386_bus_space_io_read_1(bus_space_handle_t h,bus_size_t o)257 i386_bus_space_io_read_1(bus_space_handle_t h, bus_size_t o)
258 {
259 	return (inb(h + o));
260 }
261 
262 u_int16_t
i386_bus_space_io_read_2(bus_space_handle_t h,bus_size_t o)263 i386_bus_space_io_read_2(bus_space_handle_t h, bus_size_t o)
264 {
265 	return (inw(h + o));
266 }
267 
268 u_int32_t
i386_bus_space_io_read_4(bus_space_handle_t h,bus_size_t o)269 i386_bus_space_io_read_4(bus_space_handle_t h, bus_size_t o)
270 {
271 	return (inl(h + o));
272 }
273 
274 void
i386_bus_space_io_read_multi_1(bus_space_handle_t h,bus_size_t o,u_int8_t * a,bus_size_t cnt)275 i386_bus_space_io_read_multi_1(bus_space_handle_t h, bus_size_t o,
276     u_int8_t *a, bus_size_t cnt)
277 {
278 	insb(h + o, a, cnt);
279 }
280 
281 void
i386_bus_space_io_read_multi_2(bus_space_handle_t h,bus_size_t o,u_int16_t * a,bus_size_t cnt)282 i386_bus_space_io_read_multi_2(bus_space_handle_t h, bus_size_t o,
283     u_int16_t *a, bus_size_t cnt)
284 {
285 	insw(h + o, a, cnt);
286 }
287 
288 void
i386_bus_space_io_read_multi_4(bus_space_handle_t h,bus_size_t o,u_int32_t * a,bus_size_t cnt)289 i386_bus_space_io_read_multi_4(bus_space_handle_t h, bus_size_t o,
290     u_int32_t *a, bus_size_t cnt)
291 {
292 	insl(h + o, a, cnt);
293 }
294 
295 void
i386_bus_space_io_read_region_1(bus_space_handle_t h,bus_size_t o,u_int8_t * a,bus_size_t cnt)296 i386_bus_space_io_read_region_1(bus_space_handle_t h,
297     bus_size_t o, u_int8_t *a, bus_size_t cnt)
298 {
299 	int _cnt = cnt;
300 	void *_addr = a;
301 	int _port = h + o;
302 
303 	__asm volatile(
304 	"1:	inb %w2,%%al				;"
305 	"	stosb					;"
306 	"	incl %2					;"
307 	"	loop 1b"				:
308 	    "+D" (_addr), "+c" (_cnt), "+d" (_port)	::
309 	    "%eax", "memory", "cc");
310 }
311 
312 void
i386_bus_space_io_read_region_2(bus_space_handle_t h,bus_size_t o,u_int16_t * a,bus_size_t cnt)313 i386_bus_space_io_read_region_2(bus_space_handle_t h,
314     bus_size_t o, u_int16_t *a, bus_size_t cnt)
315 {
316 	int _cnt = cnt;
317 	void *_addr = a;
318 	int _port = h + o;
319 
320 	__asm volatile(
321 	"1:	inw %w2,%%ax				;"
322 	"	stosw					;"
323 	"	addl $2,%2				;"
324 	"	loop 1b"				:
325 	    "+D" (_addr), "+c" (_cnt), "+d" (_port)	::
326 	    "%eax", "memory", "cc");
327 }
328 
329 void
i386_bus_space_io_read_region_4(bus_space_handle_t h,bus_size_t o,u_int32_t * a,bus_size_t cnt)330 i386_bus_space_io_read_region_4(bus_space_handle_t h,
331     bus_size_t o, u_int32_t *a, bus_size_t cnt)
332 {
333 	int _cnt = cnt;
334 	void *_addr = a;
335 	int _port = h + o;
336 
337 	__asm volatile(
338 	"1:	inl %w2,%%eax				;"
339 	"	stosl					;"
340 	"	addl $4,%2				;"
341 	"	loop 1b"				:
342 	    "+D" (_addr), "+c" (_cnt), "+d" (_port)	::
343 	    "%eax", "memory", "cc");
344 }
345 
346 void
i386_bus_space_io_write_1(bus_space_handle_t h,bus_size_t o,u_int8_t v)347 i386_bus_space_io_write_1(bus_space_handle_t h, bus_size_t o, u_int8_t v)
348 {
349 	outb(h + o, v);
350 }
351 
352 void
i386_bus_space_io_write_2(bus_space_handle_t h,bus_size_t o,u_int16_t v)353 i386_bus_space_io_write_2(bus_space_handle_t h, bus_size_t o, u_int16_t v)
354 {
355 	outw(h + o, v);
356 }
357 
358 void
i386_bus_space_io_write_4(bus_space_handle_t h,bus_size_t o,u_int32_t v)359 i386_bus_space_io_write_4(bus_space_handle_t h, bus_size_t o, u_int32_t v)
360 {
361 	outl(h + o, v);
362 }
363 
364 void
i386_bus_space_io_write_multi_1(bus_space_handle_t h,bus_size_t o,const u_int8_t * a,bus_size_t cnt)365 i386_bus_space_io_write_multi_1(bus_space_handle_t h,
366     bus_size_t o, const u_int8_t *a, bus_size_t cnt)
367 {
368 	outsb(h + o, a, cnt);
369 }
370 
371 void
i386_bus_space_io_write_multi_2(bus_space_handle_t h,bus_size_t o,const u_int16_t * a,bus_size_t cnt)372 i386_bus_space_io_write_multi_2(bus_space_handle_t h,
373     bus_size_t o, const u_int16_t *a, bus_size_t cnt)
374 {
375 	outsw(h + o, a, cnt);
376 }
377 
378 void
i386_bus_space_io_write_multi_4(bus_space_handle_t h,bus_size_t o,const u_int32_t * a,bus_size_t cnt)379 i386_bus_space_io_write_multi_4(bus_space_handle_t h,
380     bus_size_t o, const u_int32_t *a, bus_size_t cnt)
381 {
382 	outsl(h + o, a, cnt);
383 }
384 
385 void
i386_bus_space_io_write_region_1(bus_space_handle_t h,bus_size_t o,const u_int8_t * a,bus_size_t cnt)386 i386_bus_space_io_write_region_1(bus_space_handle_t h,
387     bus_size_t o, const u_int8_t *a, bus_size_t cnt)
388 {
389 	int _port = h + o;
390 	const void *_addr = a;
391 	int _cnt = cnt;
392 
393 	__asm volatile(
394 	"1:	lodsb					;"
395 	"	outb %%al,%w0				;"
396 	"	incl %0					;"
397 	"	loop 1b"				:
398 	    "+d" (_port), "+S" (_addr), "+c" (_cnt)	::
399 	    "%eax", "memory", "cc");
400 }
401 
402 void
i386_bus_space_io_write_region_2(bus_space_handle_t h,bus_size_t o,const u_int16_t * a,bus_size_t cnt)403 i386_bus_space_io_write_region_2(bus_space_handle_t h,
404     bus_size_t o, const u_int16_t *a, bus_size_t cnt)
405 {
406 	int _port = h + o;
407 	const void *_addr = a;
408 	int _cnt = cnt;
409 
410 	__asm volatile(
411 	"1:	lodsw					;"
412 	"	outw %%ax,%w0				;"
413 	"	addl $2,%0				;"
414 	"	loop 1b"				:
415 	    "+d" (_port), "+S" (_addr), "+c" (_cnt)	::
416 	    "%eax", "memory", "cc");
417 }
418 
419 void
i386_bus_space_io_write_region_4(bus_space_handle_t h,bus_size_t o,const u_int32_t * a,bus_size_t cnt)420 i386_bus_space_io_write_region_4(bus_space_handle_t h,
421     bus_size_t o, const u_int32_t *a, bus_size_t cnt)
422 {
423 	int _port = h + o;
424 	const void *_addr = a;
425 	int _cnt = cnt;
426 
427 	__asm volatile(
428 	"1:	lodsl					;"
429 	"	outl %%eax,%w0				;"
430 	"	addl $4,%0				;"
431 	"	loop 1b"				:
432 	    "+d" (_port), "+S" (_addr), "+c" (_cnt)	::
433 	    "%eax", "memory", "cc");
434 }
435 
436 void
i386_bus_space_io_set_multi_1(bus_space_handle_t h,bus_size_t o,u_int8_t v,size_t cnt)437 i386_bus_space_io_set_multi_1(bus_space_handle_t h,
438     bus_size_t o, u_int8_t v, size_t cnt)
439 {
440 	int _cnt = cnt;
441 
442 	__asm volatile(
443 	"1:	outb %b2, %w1				;"
444 	"	loop 1b"				:
445 	    "+c" (_cnt) : "d" (h + o), "a" (v)		:
446 	    "cc");
447 }
448 
449 void
i386_bus_space_io_set_multi_2(bus_space_handle_t h,bus_size_t o,u_int16_t v,size_t cnt)450 i386_bus_space_io_set_multi_2(bus_space_handle_t h,
451     bus_size_t o, u_int16_t v, size_t cnt)
452 {
453 	int _cnt = cnt;
454 
455 	__asm volatile(
456 	"1:	outw %w2, %w1				;"
457 	"	loop 1b"				:
458 	    "+c" (_cnt) : "d" (h + o), "a" (v)	:
459 	    "cc");
460 }
461 
462 void
i386_bus_space_io_set_multi_4(bus_space_handle_t h,bus_size_t o,u_int32_t v,size_t cnt)463 i386_bus_space_io_set_multi_4(bus_space_handle_t h,
464     bus_size_t o, u_int32_t v, size_t cnt)
465 {
466 	int _cnt = cnt;
467 
468 	__asm volatile(
469 	"1:	outl %2,%w1				;"
470 	"	loop 1b"				:
471 	    "+c" (_cnt) : "d" (h + o), "a" (v)	:
472 		    "cc");
473 }
474 
475 void
i386_bus_space_io_set_region_1(bus_space_handle_t h,bus_size_t o,u_int8_t v,size_t cnt)476 i386_bus_space_io_set_region_1(bus_space_handle_t h,
477     bus_size_t o, u_int8_t v, size_t cnt)
478 {
479 	int _port = h + o;
480 	int _cnt = cnt;
481 
482 	__asm volatile(
483 	"1:	outb %%al,%w0				;"
484 	"	incl %0					;"
485 	"	loop 1b"				:
486 	    "+d" (_port), "+c" (_cnt) : "a" (v)	:
487 		    "cc");
488 }
489 
490 void
i386_bus_space_io_set_region_2(bus_space_handle_t h,bus_size_t o,u_int16_t v,size_t cnt)491 i386_bus_space_io_set_region_2(bus_space_handle_t h,
492     bus_size_t o, u_int16_t v, size_t cnt)
493 {
494 	int _port = h + o;
495 	int _cnt = cnt;
496 
497 	__asm volatile(
498 	"1:	outw %%ax,%w0				;"
499 	"	addl $2, %0				;"
500 	"	loop 1b"				:
501 	    "+d" (_port), "+c" (_cnt) : "a" (v)		:
502 		    "cc");
503 }
504 
505 void
i386_bus_space_io_set_region_4(bus_space_handle_t h,bus_size_t o,u_int32_t v,size_t cnt)506 i386_bus_space_io_set_region_4(bus_space_handle_t h,
507     bus_size_t o, u_int32_t v, size_t cnt)
508 {
509 	int _port = h + o;
510 	int _cnt = cnt;
511 
512 	__asm volatile(
513 	"1:	outl %%eax,%w0				;"
514 	"	addl $4, %0				;"
515 	"	loop 1b"				:
516 	    "+d" (_port), "+c" (_cnt) : "a" (v)		:
517 	    "cc");
518 }
519 
520 void
i386_bus_space_io_copy_1(bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t cnt)521 i386_bus_space_io_copy_1(bus_space_handle_t h1, bus_size_t o1,
522      bus_space_handle_t h2, bus_size_t o2, bus_size_t cnt)
523 {
524 	int _port1 = h1 + o1;
525 	int _port2 = h2 + o2;
526 	int _cnt = cnt;
527 
528 	__asm volatile(
529 	"1:	movl %k1,%%edx				;"
530 	"	inb  %%dx,%%al				;"
531 	"	movl %k0,%%edx				;"
532 	"	outb %%al,%%dx				;"
533 	"	incl %0					;"
534 	"	incl %1					;"
535 	"	loop 1b"				:
536 	    "+D" (_port2), "+S" (_port1), "+c" (_cnt)	::
537 	    "%edx", "%eax", "cc");
538 }
539 
540 void
i386_bus_space_io_copy_2(bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t cnt)541 i386_bus_space_io_copy_2(bus_space_handle_t h1, bus_size_t o1,
542      bus_space_handle_t h2, bus_size_t o2, bus_size_t cnt)
543 {
544 	int _port1 = h1 + o1;
545 	int _port2 = h2 + o2;
546 	int _cnt=cnt;
547 
548 	__asm volatile(
549 	"1:	movl %k1,%%edx				;"
550 	"	inw  %%dx,%%ax				;"
551 	"	movl %k0,%%edx				;"
552 	"	outw %%ax,%%dx				;"
553 	"	addl $2, %0				;"
554 	"	addl $2, %1				;"
555 	"	loop 1b"				:
556 	    "+D" (_port2), "+S" (_port1), "+c" (_cnt)	::
557 	    "%edx", "%eax", "cc");
558 }
559 
560 void
i386_bus_space_io_copy_4(bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t cnt)561 i386_bus_space_io_copy_4(bus_space_handle_t h1, bus_size_t o1,
562      bus_space_handle_t h2, bus_size_t o2, bus_size_t cnt)
563 {
564 	int _port1 = h1 + o1;
565 	int _port2 = h2 + o2;
566 	int _cnt = cnt;
567 
568 	__asm volatile(
569 	"1:	movl %k1,%%edx				;"
570 	"	inl  %%dx,%%eax				;"
571 	"	movl %k0,%%edx				;"
572 	"	outl %%eax,%%dx				;"
573 	"	addl $4, %0				;"
574 	"	addl $4, %1				;"
575 	"	loop 1b"				:
576 	    "+D" (_port2), "+S" (_port1), "+c" (_cnt)	::
577 	    "%edx", "%eax", "cc");
578 }
579 
580 void *
i386_bus_space_io_vaddr(bus_space_handle_t h)581 i386_bus_space_io_vaddr(bus_space_handle_t h)
582 {
583 	return (NULL);
584 }
585 
586 paddr_t
i386_bus_space_io_mmap(bus_addr_t addr,off_t off,int prot,int flags)587 i386_bus_space_io_mmap(bus_addr_t addr, off_t off, int prot, int flags)
588 {
589 	/* Can't mmap I/O space. */
590 	return (-1);
591 }
592 
593 u_int8_t
i386_bus_space_mem_read_1(bus_space_handle_t h,bus_size_t o)594 i386_bus_space_mem_read_1(bus_space_handle_t h, bus_size_t o)
595 {
596 	return (*(volatile u_int8_t *)((h) + (o)));
597 }
598 
599 u_int16_t
i386_bus_space_mem_read_2(bus_space_handle_t h,bus_size_t o)600 i386_bus_space_mem_read_2(bus_space_handle_t h, bus_size_t o)
601 {
602 	return (*(volatile u_int16_t *)((h) + (o)));
603 }
604 
605 u_int32_t
i386_bus_space_mem_read_4(bus_space_handle_t h,bus_size_t o)606 i386_bus_space_mem_read_4(bus_space_handle_t h, bus_size_t o)
607 {
608 	return (*(volatile u_int32_t *)((h) + (o)));
609 }
610 
611 void
i386_bus_space_mem_read_multi_1(bus_space_handle_t h,bus_size_t o,u_int8_t * a,bus_size_t cnt)612 i386_bus_space_mem_read_multi_1(bus_space_handle_t h, bus_size_t o,
613     u_int8_t *a, bus_size_t cnt)
614 {
615 	void *_addr=a;
616 	int _cnt=cnt;
617 	__asm volatile(
618 	"1:	movb (%2),%%al				;"
619 	"	stosb					;"
620 	"	loop 1b"				:
621 	    "+D" (_addr), "+c" (_cnt) : "r" (h + o)	:
622 	    "%eax", "memory", "cc");
623 }
624 
625 void
i386_bus_space_mem_read_multi_2(bus_space_handle_t h,bus_size_t o,u_int16_t * a,bus_size_t cnt)626 i386_bus_space_mem_read_multi_2(bus_space_handle_t h, bus_size_t o,
627     u_int16_t *a, bus_size_t cnt)
628 {
629 	void *_addr=a;
630 	int _cnt=cnt;
631 	__asm volatile(
632 	"1:	movw (%2),%%ax				;"
633 	"	stosw					;"
634 	"	loop 1b"				:
635 	    "+D" (_addr), "+c" (_cnt) : "r" ((h) + (o))	:
636 	    "%eax", "memory", "cc");
637 }
638 
639 void
i386_bus_space_mem_read_multi_4(bus_space_handle_t h,bus_size_t o,u_int32_t * a,bus_size_t cnt)640 i386_bus_space_mem_read_multi_4(bus_space_handle_t h, bus_size_t o,
641     u_int32_t *a, bus_size_t cnt)
642 {
643 	void *_addr=a;
644 	int _cnt=cnt;
645 	__asm volatile(
646 	"1:	movl (%2),%%eax				;"
647 	"	stosl					;"
648 	"	loop 1b"				:
649 	    "+D" (_addr), "+c" (_cnt) : "r" (h + o)	:
650 	    "%eax", "memory", "cc");
651 }
652 
653 void
i386_bus_space_mem_read_region_1(bus_space_handle_t h,bus_size_t o,u_int8_t * a,bus_size_t cnt)654 i386_bus_space_mem_read_region_1(bus_space_handle_t h,
655     bus_size_t o, u_int8_t *a, bus_size_t cnt)
656 {
657 	int _cnt = cnt;
658 	void *_addr = a;
659 	int _port = h + o;
660 
661 	i386_space_copy(_port, _addr, 1, _cnt);
662 }
663 
664 void
i386_bus_space_mem_read_region_2(bus_space_handle_t h,bus_size_t o,u_int16_t * a,bus_size_t cnt)665 i386_bus_space_mem_read_region_2(bus_space_handle_t h,
666     bus_size_t o, u_int16_t *a, bus_size_t cnt)
667 {
668 	int _cnt = cnt;
669 	void *_addr = a;
670 	int _port = h + o;
671 
672 	i386_space_copy(_port, _addr, 2, _cnt);
673 }
674 
675 void
i386_bus_space_mem_read_region_4(bus_space_handle_t h,bus_size_t o,u_int32_t * a,bus_size_t cnt)676 i386_bus_space_mem_read_region_4(bus_space_handle_t h,
677     bus_size_t o, u_int32_t *a, bus_size_t cnt)
678 {
679 	int _cnt = cnt;
680 	void *_addr = a;
681 	int _port = h + o;
682 
683 	i386_space_copy(_port, _addr, 4, _cnt);
684 }
685 
686 void
i386_bus_space_mem_write_1(bus_space_handle_t h,bus_size_t o,u_int8_t v)687 i386_bus_space_mem_write_1(bus_space_handle_t h, bus_size_t o, u_int8_t v)
688 {
689 	((void)(*(volatile u_int8_t *)(h + o) = v));
690 }
691 
692 void
i386_bus_space_mem_write_2(bus_space_handle_t h,bus_size_t o,u_int16_t v)693 i386_bus_space_mem_write_2(bus_space_handle_t h, bus_size_t o, u_int16_t v)
694 {
695 	((void)(*(volatile u_int16_t *)(h + o) = v));
696 }
697 
698 void
i386_bus_space_mem_write_4(bus_space_handle_t h,bus_size_t o,u_int32_t v)699 i386_bus_space_mem_write_4(bus_space_handle_t h, bus_size_t o, u_int32_t v)
700 {
701 	((void)(*(volatile u_int32_t *)(h + o) = v));
702 }
703 
704 void
i386_bus_space_mem_write_multi_1(bus_space_handle_t h,bus_size_t o,const u_int8_t * a,bus_size_t cnt)705 i386_bus_space_mem_write_multi_1(bus_space_handle_t h,
706     bus_size_t o, const u_int8_t *a, bus_size_t cnt)
707 {
708 	const void *_addr=a;
709 	int _cnt=cnt;
710 
711 	__asm volatile(
712 	"1:	lodsb					;"
713 	"	movb %%al,(%2)				;"
714 	"	loop 1b"				:
715 	    "+S" (_addr), "+c" (_cnt) : "r" (h + o)	:
716 	    "%eax", "memory", "cc");
717 }
718 
719 void
i386_bus_space_mem_write_multi_2(bus_space_handle_t h,bus_size_t o,const u_int16_t * a,bus_size_t cnt)720 i386_bus_space_mem_write_multi_2(bus_space_handle_t h,
721     bus_size_t o, const u_int16_t *a, bus_size_t cnt)
722 {
723 	const void *_addr = a;
724 	int _cnt = cnt;
725 
726 	__asm volatile(
727 	"1:	lodsw					;"
728 	"	movw %%ax,(%2)				;"
729 	"	loop 1b"				:
730 	    "+S" (_addr), "+c" (_cnt) : "r" (h + o)	:
731 	    "%eax", "memory", "cc");
732 }
733 
734 void
i386_bus_space_mem_write_multi_4(bus_space_handle_t h,bus_size_t o,const u_int32_t * a,bus_size_t cnt)735 i386_bus_space_mem_write_multi_4(bus_space_handle_t h,
736     bus_size_t o, const u_int32_t *a, bus_size_t cnt)
737 {
738 	const void *_addr=a;
739 	int _cnt=cnt;
740 
741 	__asm volatile(
742 	"1:	lodsl					;"
743 	"	movl %%eax,(%2)				;"
744 	"	loop 1b"				:
745 	    "+S" (_addr), "+c" (_cnt) : "r" (h + o)	:
746 	    "%eax", "memory", "cc");
747 }
748 
749 void
i386_bus_space_mem_write_region_1(bus_space_handle_t h,bus_size_t o,const u_int8_t * a,bus_size_t cnt)750 i386_bus_space_mem_write_region_1(bus_space_handle_t h,
751     bus_size_t o, const u_int8_t *a, bus_size_t cnt)
752 {
753 	int _port = h + o;
754 	const void *_addr = a;
755 	int _cnt = cnt;
756 
757 	i386_space_copy(_addr, _port, 1, _cnt);
758 }
759 
760 void
i386_bus_space_mem_write_region_2(bus_space_handle_t h,bus_size_t o,const u_int16_t * a,bus_size_t cnt)761 i386_bus_space_mem_write_region_2(bus_space_handle_t h,
762     bus_size_t o, const u_int16_t *a, bus_size_t cnt)
763 {
764 	int _port = h + o;
765 	const void *_addr = a;
766 	int _cnt = cnt;
767 
768 	i386_space_copy(_addr, _port, 2, _cnt);
769 }
770 
771 void
i386_bus_space_mem_write_region_4(bus_space_handle_t h,bus_size_t o,const u_int32_t * a,bus_size_t cnt)772 i386_bus_space_mem_write_region_4(bus_space_handle_t h,
773     bus_size_t o, const u_int32_t *a, bus_size_t cnt)
774 {
775 	int _port = h + o;
776 	const void *_addr = a;
777 	int _cnt = cnt;
778 
779 	i386_space_copy(_addr, _port, 4, _cnt);
780 }
781 
782 void
i386_bus_space_mem_set_multi_1(bus_space_handle_t h,bus_size_t o,u_int8_t v,size_t cnt)783 i386_bus_space_mem_set_multi_1(bus_space_handle_t h,
784     bus_size_t o, u_int8_t v, size_t cnt)
785 {
786 	int _cnt = cnt;
787 
788 	__asm volatile(
789 	"1:	movb %b2, (%1)				;"
790 	"	loop 1b"				:
791 	    "+c" (_cnt) : "D" (h + o), "a" (v)		:
792 	    "cc", "memory");
793 }
794 
795 void
i386_bus_space_mem_set_multi_2(bus_space_handle_t h,bus_size_t o,u_int16_t v,size_t cnt)796 i386_bus_space_mem_set_multi_2(bus_space_handle_t h,
797     bus_size_t o, u_int16_t v, size_t cnt)
798 {
799 	int _cnt = cnt;
800 
801 	__asm volatile(
802 	"1:	movw %w2, (%1)				;"
803 	"	loop 1b"				:
804 	    "+c" (_cnt) : "D" (h + o), "a" (v)		:
805 	    "cc", "memory");
806 }
807 
808 void
i386_bus_space_mem_set_multi_4(bus_space_handle_t h,bus_size_t o,u_int32_t v,size_t cnt)809 i386_bus_space_mem_set_multi_4(bus_space_handle_t h,
810     bus_size_t o, u_int32_t v, size_t cnt)
811 {
812 	int _cnt = cnt;
813 
814 	__asm volatile(
815 	"1:	movl %2,(%1)				;"
816 	"	loop 1b"				:
817 	    "+c" (_cnt) : "D" (h + o), "a" (v)	:
818 	    "cc", "memory");
819 }
820 
821 void
i386_bus_space_mem_set_region_1(bus_space_handle_t h,bus_size_t o,u_int8_t v,size_t cnt)822 i386_bus_space_mem_set_region_1(bus_space_handle_t h,
823     bus_size_t o, u_int8_t v, size_t cnt)
824 {
825 	int _port = h + o;
826 	int _cnt = cnt;
827 
828 	__asm volatile(
829 	"	repne					;"
830 	"	stosb"					:
831 	    "+D" (_port), "+c" (_cnt) : "a" (v)	:
832 	    "memory", "cc");
833 }
834 
835 void
i386_bus_space_mem_set_region_2(bus_space_handle_t h,bus_size_t o,u_int16_t v,size_t cnt)836 i386_bus_space_mem_set_region_2(bus_space_handle_t h,
837     bus_size_t o, u_int16_t v, size_t cnt)
838 {
839 	int _port = h + o;
840 	int _cnt = cnt;
841 
842 	__asm volatile(
843 	"	repne					;"
844 	"	stosw"					:
845 	    "+D" (_port), "+c" (_cnt) : "a" (v)	:
846 	    "memory", "cc");
847 }
848 
849 void
i386_bus_space_mem_set_region_4(bus_space_handle_t h,bus_size_t o,u_int32_t v,size_t cnt)850 i386_bus_space_mem_set_region_4(bus_space_handle_t h,
851     bus_size_t o, u_int32_t v, size_t cnt)
852 {
853 	int _port = h + o;
854 	int _cnt = cnt;
855 
856 	__asm volatile(
857 	"	repne					;"
858 	"	stosl"					:
859 	    "+D" (_port), "+c" (_cnt) : "a" (v)	:
860 	    "memory", "cc");
861 }
862 
863 void
i386_bus_space_mem_copy_1(bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t cnt)864 i386_bus_space_mem_copy_1( bus_space_handle_t h1, bus_size_t o1,
865      bus_space_handle_t h2, bus_size_t o2, bus_size_t cnt)
866 {
867 	int _port1 = h1 + o1;
868 	int _port2 = h2 + o2;
869 	int _cnt = cnt;
870 
871 	i386_space_copy(_port1, _port2, 1, _cnt);
872 }
873 
874 void
i386_bus_space_mem_copy_2(bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t cnt)875 i386_bus_space_mem_copy_2( bus_space_handle_t h1, bus_size_t o1,
876      bus_space_handle_t h2, bus_size_t o2, bus_size_t cnt)
877 {
878 	int _port1 = h1 + o1;
879 	int _port2 = h2 + o2;
880 	int _cnt=cnt;
881 
882 	i386_space_copy(_port1, _port2, 2, _cnt);
883 }
884 
885 void
i386_bus_space_mem_copy_4(bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,bus_size_t cnt)886 i386_bus_space_mem_copy_4( bus_space_handle_t h1, bus_size_t o1,
887      bus_space_handle_t h2, bus_size_t o2, bus_size_t cnt)
888 {
889 	int _port1 = h1 + o1;
890 	int _port2 = h2 + o2;
891 	int _cnt = cnt;
892 
893 	i386_space_copy(_port1, _port2, 4, _cnt);
894 }
895 
896 void *
i386_bus_space_mem_vaddr(bus_space_handle_t h)897 i386_bus_space_mem_vaddr(bus_space_handle_t h)
898 {
899 	return ((void *)h);
900 }
901 
902 paddr_t
i386_bus_space_mem_mmap(bus_addr_t addr,off_t off,int prot,int flags)903 i386_bus_space_mem_mmap(bus_addr_t addr, off_t off, int prot, int flags)
904 {
905 	/*
906 	 * "addr" is the base address of the device we're mapping.
907 	 * "off" is the offset into that device.
908 	 *
909 	 * Note we are called for each "page" in the device that
910 	 * the upper layers want to map.
911 	 */
912 	return (addr + off);
913 }
914