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