1 /* $OpenBSD: bus_space.c,v 1.28 2022/11/29 21:41:39 guenther Exp $ */
2 /* $NetBSD: bus_space.c,v 1.2 2003/03/14 18:47:53 christos Exp $ */
3
4 /*-
5 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
10 * Simulation Facility, NASA Ames Research Center.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/malloc.h>
37 #include <sys/extent.h>
38
39 #include <uvm/uvm_extern.h>
40
41 #include <machine/bus.h>
42
43 #include <dev/isa/isareg.h>
44 #include <machine/isa_machdep.h>
45
46 extern int pmap_initialized;
47
48 /* kernel address of "hole" (location of start of iomem in virtual) */
49 u_long atdevbase = 0;
50
51 /*
52 * Extent maps to manage I/O and memory space. Allocate
53 * storage for 16 regions in each, initially. Later, ioport_malloc_safe
54 * will indicate that it's safe to use malloc() to dynamically allocate
55 * region descriptors.
56 *
57 * N.B. At least two regions are _always_ allocated from the iomem
58 * extent map; (0 -> ISA hole) and (end of ISA hole -> end of RAM).
59 *
60 * The extent maps are not static! Machine-dependent ISA and EISA
61 * routines need access to them for bus address space allocation.
62 */
63 static long ioport_ex_storage[EXTENT_FIXED_STORAGE_SIZE(16) / sizeof(long)];
64 static long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(16) / sizeof(long)];
65 struct extent *ioport_ex;
66 struct extent *iomem_ex;
67 static int ioport_malloc_safe;
68
69 int x86_mem_add_mapping(bus_addr_t, bus_size_t,
70 int, bus_space_handle_t *);
71
72 u_int8_t x86_bus_space_io_read_1(bus_space_handle_t, bus_size_t);
73 u_int16_t x86_bus_space_io_read_2(bus_space_handle_t, bus_size_t);
74 u_int32_t x86_bus_space_io_read_4(bus_space_handle_t, bus_size_t);
75 u_int64_t x86_bus_space_io_read_8(bus_space_handle_t, bus_size_t);
76
77 void x86_bus_space_io_read_multi_1(bus_space_handle_t, bus_size_t,
78 u_int8_t *, bus_size_t);
79 void x86_bus_space_io_read_multi_2(bus_space_handle_t, bus_size_t,
80 u_int16_t *, bus_size_t);
81 void x86_bus_space_io_read_multi_4(bus_space_handle_t, bus_size_t,
82 u_int32_t *, bus_size_t);
83 void x86_bus_space_io_read_multi_8(bus_space_handle_t, bus_size_t,
84 u_int64_t *, bus_size_t);
85
86 void x86_bus_space_io_read_region_1(bus_space_handle_t, bus_size_t,
87 u_int8_t *, bus_size_t);
88 void x86_bus_space_io_read_region_2(bus_space_handle_t, bus_size_t,
89 u_int16_t *, bus_size_t);
90 void x86_bus_space_io_read_region_4(bus_space_handle_t, bus_size_t,
91 u_int32_t *, bus_size_t);
92 void x86_bus_space_io_read_region_8(bus_space_handle_t, bus_size_t,
93 u_int64_t *, bus_size_t);
94
95 void x86_bus_space_io_write_1(bus_space_handle_t, bus_size_t,
96 u_int8_t);
97 void x86_bus_space_io_write_2(bus_space_handle_t, bus_size_t,
98 u_int16_t);
99 void x86_bus_space_io_write_4(bus_space_handle_t, bus_size_t,
100 u_int32_t);
101 void x86_bus_space_io_write_8(bus_space_handle_t, bus_size_t,
102 u_int64_t);
103
104 void x86_bus_space_io_write_multi_1(bus_space_handle_t,
105 bus_size_t, const u_int8_t *, bus_size_t);
106 void x86_bus_space_io_write_multi_2(bus_space_handle_t,
107 bus_size_t, const u_int16_t *, bus_size_t);
108 void x86_bus_space_io_write_multi_4(bus_space_handle_t,
109 bus_size_t, const u_int32_t *, bus_size_t);
110 void x86_bus_space_io_write_multi_8(bus_space_handle_t,
111 bus_size_t, const u_int64_t *, bus_size_t);
112
113 void x86_bus_space_io_write_region_1(bus_space_handle_t,
114 bus_size_t, const u_int8_t *, bus_size_t);
115 void x86_bus_space_io_write_region_2(bus_space_handle_t,
116 bus_size_t, const u_int16_t *, bus_size_t);
117 void x86_bus_space_io_write_region_4(bus_space_handle_t,
118 bus_size_t, const u_int32_t *, bus_size_t);
119 void x86_bus_space_io_write_region_8(bus_space_handle_t,
120 bus_size_t, const u_int64_t *, bus_size_t);
121
122 void x86_bus_space_io_set_multi_1(bus_space_handle_t, bus_size_t,
123 u_int8_t, size_t);
124 void x86_bus_space_io_set_multi_2(bus_space_handle_t, bus_size_t,
125 u_int16_t, size_t);
126 void x86_bus_space_io_set_multi_4(bus_space_handle_t, bus_size_t,
127 u_int32_t, size_t);
128 void x86_bus_space_io_set_multi_8(bus_space_handle_t, bus_size_t,
129 u_int64_t, size_t);
130
131 void x86_bus_space_io_set_region_1(bus_space_handle_t, bus_size_t,
132 u_int8_t, size_t);
133 void x86_bus_space_io_set_region_2(bus_space_handle_t, bus_size_t,
134 u_int16_t, size_t);
135 void x86_bus_space_io_set_region_4(bus_space_handle_t, bus_size_t,
136 u_int32_t, size_t);
137 void x86_bus_space_io_set_region_8(bus_space_handle_t, bus_size_t,
138 u_int64_t, size_t);
139
140 void x86_bus_space_io_copy_1(bus_space_handle_t, bus_size_t,
141 bus_space_handle_t, bus_size_t, size_t);
142 void x86_bus_space_io_copy_2(bus_space_handle_t, bus_size_t,
143 bus_space_handle_t, bus_size_t, size_t);
144 void x86_bus_space_io_copy_4(bus_space_handle_t, bus_size_t,
145 bus_space_handle_t, bus_size_t, size_t);
146 void x86_bus_space_io_copy_8(bus_space_handle_t, bus_size_t,
147 bus_space_handle_t, bus_size_t, size_t);
148
149 void * x86_bus_space_io_vaddr(bus_space_handle_t);
150 paddr_t x86_bus_space_io_mmap(bus_addr_t, off_t, int, int);
151
152 const struct x86_bus_space_ops x86_bus_space_io_ops = {
153 x86_bus_space_io_read_1,
154 x86_bus_space_io_read_2,
155 x86_bus_space_io_read_4,
156 x86_bus_space_io_read_8,
157 x86_bus_space_io_read_multi_1,
158 x86_bus_space_io_read_multi_2,
159 x86_bus_space_io_read_multi_4,
160 x86_bus_space_io_read_multi_8,
161 x86_bus_space_io_read_region_1,
162 x86_bus_space_io_read_region_2,
163 x86_bus_space_io_read_region_4,
164 x86_bus_space_io_read_region_8,
165 x86_bus_space_io_write_1,
166 x86_bus_space_io_write_2,
167 x86_bus_space_io_write_4,
168 x86_bus_space_io_write_8,
169 x86_bus_space_io_write_multi_1,
170 x86_bus_space_io_write_multi_2,
171 x86_bus_space_io_write_multi_4,
172 x86_bus_space_io_write_multi_8,
173 x86_bus_space_io_write_region_1,
174 x86_bus_space_io_write_region_2,
175 x86_bus_space_io_write_region_4,
176 x86_bus_space_io_write_region_8,
177 x86_bus_space_io_set_multi_1,
178 x86_bus_space_io_set_multi_2,
179 x86_bus_space_io_set_multi_4,
180 x86_bus_space_io_set_multi_8,
181 x86_bus_space_io_set_region_1,
182 x86_bus_space_io_set_region_2,
183 x86_bus_space_io_set_region_4,
184 x86_bus_space_io_set_region_8,
185 x86_bus_space_io_copy_1,
186 x86_bus_space_io_copy_2,
187 x86_bus_space_io_copy_4,
188 x86_bus_space_io_copy_8,
189 x86_bus_space_io_vaddr,
190 x86_bus_space_io_mmap
191 };
192
193 u_int8_t x86_bus_space_mem_read_1(bus_space_handle_t, bus_size_t);
194 u_int16_t x86_bus_space_mem_read_2(bus_space_handle_t, bus_size_t);
195 u_int32_t x86_bus_space_mem_read_4(bus_space_handle_t, bus_size_t);
196 u_int64_t x86_bus_space_mem_read_8(bus_space_handle_t, bus_size_t);
197
198 void x86_bus_space_mem_read_multi_1(bus_space_handle_t, bus_size_t,
199 u_int8_t *, bus_size_t);
200 void x86_bus_space_mem_read_multi_2(bus_space_handle_t, bus_size_t,
201 u_int16_t *, bus_size_t);
202 void x86_bus_space_mem_read_multi_4(bus_space_handle_t, bus_size_t,
203 u_int32_t *, bus_size_t);
204 void x86_bus_space_mem_read_multi_8(bus_space_handle_t, bus_size_t,
205 u_int64_t *, bus_size_t);
206
207 void x86_bus_space_mem_read_region_1(bus_space_handle_t, bus_size_t,
208 u_int8_t *, bus_size_t);
209 void x86_bus_space_mem_read_region_2(bus_space_handle_t, bus_size_t,
210 u_int16_t *, bus_size_t);
211 void x86_bus_space_mem_read_region_4(bus_space_handle_t, bus_size_t,
212 u_int32_t *, bus_size_t);
213 void x86_bus_space_mem_read_region_8(bus_space_handle_t, bus_size_t,
214 u_int64_t *, bus_size_t);
215
216 void x86_bus_space_mem_write_1(bus_space_handle_t, bus_size_t,
217 u_int8_t);
218 void x86_bus_space_mem_write_2(bus_space_handle_t, bus_size_t,
219 u_int16_t);
220 void x86_bus_space_mem_write_4(bus_space_handle_t, bus_size_t,
221 u_int32_t);
222 void x86_bus_space_mem_write_8(bus_space_handle_t, bus_size_t,
223 u_int64_t);
224
225 void x86_bus_space_mem_write_multi_1(bus_space_handle_t,
226 bus_size_t, const u_int8_t *, bus_size_t);
227 void x86_bus_space_mem_write_multi_2(bus_space_handle_t,
228 bus_size_t, const u_int16_t *, bus_size_t);
229 void x86_bus_space_mem_write_multi_4(bus_space_handle_t,
230 bus_size_t, const u_int32_t *, bus_size_t);
231 void x86_bus_space_mem_write_multi_8(bus_space_handle_t,
232 bus_size_t, const u_int64_t *, bus_size_t);
233
234 void x86_bus_space_mem_write_region_1(bus_space_handle_t,
235 bus_size_t, const u_int8_t *, bus_size_t);
236 void x86_bus_space_mem_write_region_2(bus_space_handle_t,
237 bus_size_t, const u_int16_t *, bus_size_t);
238 void x86_bus_space_mem_write_region_4(bus_space_handle_t,
239 bus_size_t, const u_int32_t *, bus_size_t);
240 void x86_bus_space_mem_write_region_8(bus_space_handle_t,
241 bus_size_t, const u_int64_t *, bus_size_t);
242
243 void x86_bus_space_mem_set_multi_1(bus_space_handle_t, bus_size_t,
244 u_int8_t, size_t);
245 void x86_bus_space_mem_set_multi_2(bus_space_handle_t, bus_size_t,
246 u_int16_t, size_t);
247 void x86_bus_space_mem_set_multi_4(bus_space_handle_t, bus_size_t,
248 u_int32_t, size_t);
249 void x86_bus_space_mem_set_multi_8(bus_space_handle_t, bus_size_t,
250 u_int64_t, size_t);
251
252 void x86_bus_space_mem_set_region_1(bus_space_handle_t, bus_size_t,
253 u_int8_t, size_t);
254 void x86_bus_space_mem_set_region_2(bus_space_handle_t, bus_size_t,
255 u_int16_t, size_t);
256 void x86_bus_space_mem_set_region_4(bus_space_handle_t, bus_size_t,
257 u_int32_t, size_t);
258 void x86_bus_space_mem_set_region_8(bus_space_handle_t, bus_size_t,
259 u_int64_t, size_t);
260
261 void x86_bus_space_mem_copy_1(bus_space_handle_t, bus_size_t,
262 bus_space_handle_t, bus_size_t, size_t);
263 void x86_bus_space_mem_copy_2(bus_space_handle_t, bus_size_t,
264 bus_space_handle_t, bus_size_t, size_t);
265 void x86_bus_space_mem_copy_4(bus_space_handle_t, bus_size_t,
266 bus_space_handle_t, bus_size_t, size_t);
267 void x86_bus_space_mem_copy_8(bus_space_handle_t, bus_size_t,
268 bus_space_handle_t, bus_size_t, size_t);
269
270 void * x86_bus_space_mem_vaddr(bus_space_handle_t);
271
272 paddr_t x86_bus_space_mem_mmap(bus_addr_t, off_t, int, int);
273
274 const struct x86_bus_space_ops x86_bus_space_mem_ops = {
275 x86_bus_space_mem_read_1,
276 x86_bus_space_mem_read_2,
277 x86_bus_space_mem_read_4,
278 x86_bus_space_mem_read_8,
279 x86_bus_space_mem_read_multi_1,
280 x86_bus_space_mem_read_multi_2,
281 x86_bus_space_mem_read_multi_4,
282 x86_bus_space_mem_read_multi_8,
283 x86_bus_space_mem_read_region_1,
284 x86_bus_space_mem_read_region_2,
285 x86_bus_space_mem_read_region_4,
286 x86_bus_space_mem_read_region_8,
287 x86_bus_space_mem_write_1,
288 x86_bus_space_mem_write_2,
289 x86_bus_space_mem_write_4,
290 x86_bus_space_mem_write_8,
291 x86_bus_space_mem_write_multi_1,
292 x86_bus_space_mem_write_multi_2,
293 x86_bus_space_mem_write_multi_4,
294 x86_bus_space_mem_write_multi_8,
295 x86_bus_space_mem_write_region_1,
296 x86_bus_space_mem_write_region_2,
297 x86_bus_space_mem_write_region_4,
298 x86_bus_space_mem_write_region_8,
299 x86_bus_space_mem_set_multi_1,
300 x86_bus_space_mem_set_multi_2,
301 x86_bus_space_mem_set_multi_4,
302 x86_bus_space_mem_set_multi_8,
303 x86_bus_space_mem_set_region_1,
304 x86_bus_space_mem_set_region_2,
305 x86_bus_space_mem_set_region_4,
306 x86_bus_space_mem_set_region_8,
307 x86_bus_space_mem_copy_1,
308 x86_bus_space_mem_copy_2,
309 x86_bus_space_mem_copy_4,
310 x86_bus_space_mem_copy_8,
311 x86_bus_space_mem_vaddr,
312 x86_bus_space_mem_mmap
313 };
314
315 void
x86_bus_space_init(void)316 x86_bus_space_init(void)
317 {
318 /*
319 * Initialize the I/O port and I/O mem extent maps.
320 * Note: we don't have to check the return value since
321 * creation of a fixed extent map will never fail (since
322 * descriptor storage has already been allocated).
323 *
324 * N.B. The iomem extent manages _all_ physical addresses
325 * on the machine. When the amount of RAM is found, the two
326 * extents of RAM are allocated from the map (0 -> ISA hole
327 * and end of ISA hole -> end of RAM).
328 */
329 ioport_ex = extent_create("ioport", 0x0, 0xffff, M_DEVBUF,
330 (caddr_t)ioport_ex_storage, sizeof(ioport_ex_storage),
331 EX_NOCOALESCE|EX_NOWAIT);
332 iomem_ex = extent_create("iomem", 0x0, 0xffffffffffff, M_DEVBUF,
333 (caddr_t)iomem_ex_storage, sizeof(iomem_ex_storage),
334 EX_NOCOALESCE|EX_NOWAIT);
335 }
336
337 void
x86_bus_space_mallocok(void)338 x86_bus_space_mallocok(void)
339 {
340 ioport_malloc_safe = 1;
341 }
342
343 int
bus_space_map(bus_space_tag_t t,bus_addr_t bpa,bus_size_t size,int flags,bus_space_handle_t * bshp)344 bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags,
345 bus_space_handle_t *bshp)
346 {
347 int error;
348 struct extent *ex;
349
350 /*
351 * Pick the appropriate extent map.
352 */
353 if (t == X86_BUS_SPACE_IO) {
354 ex = ioport_ex;
355 if (flags & BUS_SPACE_MAP_LINEAR)
356 return (EINVAL);
357 } else if (t == X86_BUS_SPACE_MEM)
358 ex = iomem_ex;
359 else
360 panic("bus_space_map: bad bus space tag");
361
362 /*
363 * Before we go any further, let's make sure that this
364 * region is available.
365 */
366 error = extent_alloc_region(ex, bpa, size,
367 EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0));
368 if (error)
369 return (error);
370
371 /*
372 * For I/O space, that's all she wrote.
373 */
374 if (t == X86_BUS_SPACE_IO) {
375 *bshp = bpa;
376 return (0);
377 }
378
379 if (bpa >= IOM_BEGIN && (bpa + size) <= IOM_END) {
380 *bshp = (bus_space_handle_t)ISA_HOLE_VADDR(bpa);
381 return(0);
382 }
383
384 if (!pmap_initialized && bpa < 0x100000000) {
385 *bshp = (bus_space_handle_t)PMAP_DIRECT_MAP(bpa);
386 return(0);
387 }
388
389 /*
390 * For memory space, map the bus physical address to
391 * a kernel virtual address.
392 */
393 error = x86_mem_add_mapping(bpa, size, flags, bshp);
394 if (error) {
395 if (extent_free(ex, bpa, size, EX_NOWAIT |
396 (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
397 printf("bus_space_map: pa 0x%lx, size 0x%lx\n",
398 bpa, size);
399 printf("bus_space_map: can't free region\n");
400 }
401 }
402
403 return (error);
404 }
405
406 int
_bus_space_map(bus_space_tag_t t,bus_addr_t bpa,bus_size_t size,int flags,bus_space_handle_t * bshp)407 _bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags,
408 bus_space_handle_t *bshp)
409 {
410
411 /*
412 * For I/O space, just fill in the handle.
413 */
414 if (t == X86_BUS_SPACE_IO) {
415 *bshp = bpa;
416 return (0);
417 }
418
419 /*
420 * For memory space, map the bus physical address to
421 * a kernel virtual address.
422 */
423 return (x86_mem_add_mapping(bpa, size, flags, bshp));
424 }
425
426 int
bus_space_alloc(bus_space_tag_t t,bus_addr_t rstart,bus_addr_t rend,bus_size_t size,bus_size_t alignment,bus_size_t boundary,int flags,bus_addr_t * bpap,bus_space_handle_t * bshp)427 bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend,
428 bus_size_t size, bus_size_t alignment, bus_size_t boundary, int flags,
429 bus_addr_t *bpap, bus_space_handle_t *bshp)
430 {
431 struct extent *ex;
432 u_long bpa;
433 int error;
434
435 /*
436 * Pick the appropriate extent map.
437 */
438 if (t == X86_BUS_SPACE_IO) {
439 ex = ioport_ex;
440 } else if (t == X86_BUS_SPACE_MEM)
441 ex = iomem_ex;
442 else
443 panic("bus_space_alloc: bad bus space tag");
444
445 /*
446 * Sanity check the allocation against the extent's boundaries.
447 */
448 if (rstart < ex->ex_start || rend > ex->ex_end)
449 panic("bus_space_alloc: bad region start/end");
450
451 /*
452 * Do the requested allocation.
453 */
454 error = extent_alloc_subregion(ex, rstart, rend, size, alignment,
455 0, boundary,
456 EX_FAST | EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0),
457 &bpa);
458
459 if (error)
460 return (error);
461
462 /*
463 * For I/O space, that's all she wrote.
464 */
465 if (t == X86_BUS_SPACE_IO) {
466 *bshp = *bpap = bpa;
467 return (0);
468 }
469
470 /*
471 * For memory space, map the bus physical address to
472 * a kernel virtual address.
473 */
474 error = x86_mem_add_mapping(bpa, size, flags, bshp);
475 if (error) {
476 if (extent_free(iomem_ex, bpa, size, EX_NOWAIT |
477 (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
478 printf("bus_space_alloc: pa 0x%lx, size 0x%lx\n",
479 bpa, size);
480 printf("bus_space_alloc: can't free region\n");
481 }
482 }
483
484 *bpap = bpa;
485
486 return (error);
487 }
488
489 int
x86_mem_add_mapping(bus_addr_t bpa,bus_size_t size,int flags,bus_space_handle_t * bshp)490 x86_mem_add_mapping(bus_addr_t bpa, bus_size_t size, int flags,
491 bus_space_handle_t *bshp)
492 {
493 paddr_t pa, endpa;
494 vaddr_t va;
495 bus_size_t map_size;
496 int pmap_flags = PMAP_NOCACHE;
497
498 pa = trunc_page(bpa);
499 endpa = round_page(bpa + size);
500
501 #ifdef DIAGNOSTIC
502 if (endpa <= pa && endpa != 0)
503 panic("bus_mem_add_mapping: overflow");
504 #endif
505
506 map_size = endpa - pa;
507
508 va = (vaddr_t)km_alloc(map_size, &kv_any, &kp_none, &kd_nowait);
509 if (va == 0)
510 return (ENOMEM);
511
512 *bshp = (bus_space_handle_t)(va + (bpa & PGOFSET));
513
514 if (flags & BUS_SPACE_MAP_CACHEABLE)
515 pmap_flags = 0;
516 else if (flags & BUS_SPACE_MAP_PREFETCHABLE)
517 pmap_flags = PMAP_WC;
518
519 for (; map_size > 0;
520 pa += PAGE_SIZE, va += PAGE_SIZE, map_size -= PAGE_SIZE)
521 pmap_kenter_pa(va, pa | pmap_flags, PROT_READ | PROT_WRITE);
522 pmap_update(pmap_kernel());
523
524 return 0;
525 }
526
527 /*
528 * void _bus_space_unmap(bus_space_tag bst, bus_space_handle bsh,
529 * bus_size_t size, bus_addr_t *adrp)
530 *
531 * This function unmaps memory- or io-space mapped by the function
532 * _bus_space_map(). This function works nearly as same as
533 * bus_space_unmap(), but this function does not ask kernel
534 * built-in extents and returns physical address of the bus space,
535 * for the convenience of the extra extent manager.
536 */
537 void
_bus_space_unmap(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t size,bus_addr_t * adrp)538 _bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size,
539 bus_addr_t *adrp)
540 {
541 u_long va, endva;
542 bus_addr_t bpa;
543
544 /*
545 * Find the correct bus physical address.
546 */
547 if (t == X86_BUS_SPACE_IO) {
548 bpa = bsh;
549 } else if (t == X86_BUS_SPACE_MEM) {
550 bpa = (bus_addr_t)ISA_PHYSADDR(bsh);
551 if (IOM_BEGIN <= bpa && bpa <= IOM_END)
552 goto ok;
553
554 va = trunc_page(bsh);
555 endva = round_page(bsh + size);
556
557 #ifdef DIAGNOSTIC
558 if (endva <= va)
559 panic("_bus_space_unmap: overflow");
560 #endif
561
562 (void) pmap_extract(pmap_kernel(), va, &bpa);
563 bpa += (bsh & PGOFSET);
564
565 pmap_kremove(va, endva - va);
566 pmap_update(pmap_kernel());
567
568 /*
569 * Free the kernel virtual mapping.
570 */
571 km_free((void *)va, endva - va, &kv_any, &kp_none);
572 } else
573 panic("bus_space_unmap: bad bus space tag");
574
575 ok:
576 if (adrp != NULL)
577 *adrp = bpa;
578 }
579
580 void
bus_space_unmap(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t size)581 bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
582 {
583 struct extent *ex;
584 u_long va, endva;
585 bus_addr_t bpa;
586
587 /*
588 * Find the correct extent and bus physical address.
589 */
590 if (t == X86_BUS_SPACE_IO) {
591 ex = ioport_ex;
592 bpa = bsh;
593 } else if (t == X86_BUS_SPACE_MEM) {
594 ex = iomem_ex;
595 bpa = (bus_addr_t)ISA_PHYSADDR(bsh);
596 if (IOM_BEGIN <= bpa && bpa <= IOM_END)
597 goto ok;
598
599 if (bsh >= PMAP_DIRECT_BASE && bsh < PMAP_DIRECT_END) {
600 bpa = PMAP_DIRECT_UNMAP(bsh);
601 goto ok;
602 }
603
604 va = trunc_page(bsh);
605 endva = round_page(bsh + size);
606
607 #ifdef DIAGNOSTIC
608 if (endva <= va)
609 panic("bus_space_unmap: overflow");
610 #endif
611
612 (void)pmap_extract(pmap_kernel(), va, &bpa);
613 bpa += (bsh & PGOFSET);
614
615 pmap_kremove(va, endva - va);
616 pmap_update(pmap_kernel());
617
618 /*
619 * Free the kernel virtual mapping.
620 */
621 km_free((void *)va, endva - va, &kv_any, &kp_none);
622 } else
623 panic("bus_space_unmap: bad bus space tag");
624
625 ok:
626 if (extent_free(ex, bpa, size,
627 EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
628 printf("bus_space_unmap: %s 0x%lx, size 0x%lx\n",
629 (t == X86_BUS_SPACE_IO) ? "port" : "pa", bpa, size);
630 printf("bus_space_unmap: can't free region\n");
631 }
632 }
633
634 void
bus_space_free(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t size)635 bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
636 {
637
638 /* bus_space_unmap() does all that we need to do. */
639 bus_space_unmap(t, bsh, size);
640 }
641
642 int
bus_space_subregion(bus_space_tag_t t,bus_space_handle_t bsh,bus_size_t offset,bus_size_t size,bus_space_handle_t * nbshp)643 bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
644 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
645 {
646
647 *nbshp = bsh + offset;
648 return (0);
649 }
650
651 u_int8_t
x86_bus_space_io_read_1(bus_space_handle_t h,bus_size_t o)652 x86_bus_space_io_read_1(bus_space_handle_t h, bus_size_t o)
653 {
654 return (inb(h + o));
655 }
656
657 u_int16_t
x86_bus_space_io_read_2(bus_space_handle_t h,bus_size_t o)658 x86_bus_space_io_read_2(bus_space_handle_t h, bus_size_t o)
659 {
660 return (inw(h + o));
661 }
662
663 u_int32_t
x86_bus_space_io_read_4(bus_space_handle_t h,bus_size_t o)664 x86_bus_space_io_read_4(bus_space_handle_t h, bus_size_t o)
665 {
666 return (inl(h + o));
667 }
668
669 u_int64_t
x86_bus_space_io_read_8(bus_space_handle_t h,bus_size_t o)670 x86_bus_space_io_read_8(bus_space_handle_t h, bus_size_t o)
671 {
672 panic("bus_space_read_8: invalid bus space tag");
673 }
674
675 void
x86_bus_space_io_read_multi_1(bus_space_handle_t h,bus_size_t o,u_int8_t * ptr,bus_size_t cnt)676 x86_bus_space_io_read_multi_1(bus_space_handle_t h, bus_size_t o,
677 u_int8_t *ptr, bus_size_t cnt)
678 {
679 insb(h + o, ptr, cnt);
680 }
681
682 void
x86_bus_space_io_read_multi_2(bus_space_handle_t h,bus_size_t o,u_int16_t * ptr,bus_size_t cnt)683 x86_bus_space_io_read_multi_2(bus_space_handle_t h, bus_size_t o,
684 u_int16_t *ptr, bus_size_t cnt)
685 {
686 insw(h + o, ptr, cnt);
687 }
688
689 void
x86_bus_space_io_read_multi_4(bus_space_handle_t h,bus_size_t o,u_int32_t * ptr,bus_size_t cnt)690 x86_bus_space_io_read_multi_4(bus_space_handle_t h, bus_size_t o,
691 u_int32_t *ptr, bus_size_t cnt)
692 {
693 insl(h + o, ptr, cnt);
694 }
695
696 void
x86_bus_space_io_read_multi_8(bus_space_handle_t h,bus_size_t o,u_int64_t * ptr,bus_size_t cnt)697 x86_bus_space_io_read_multi_8(bus_space_handle_t h, bus_size_t o,
698 u_int64_t *ptr, bus_size_t cnt)
699 {
700 panic("bus_space_multi_8: invalid bus space tag");
701 }
702
703 void
x86_bus_space_io_read_region_1(bus_space_handle_t h,bus_size_t o,u_int8_t * ptr,bus_size_t cnt)704 x86_bus_space_io_read_region_1(bus_space_handle_t h,
705 bus_size_t o, u_int8_t *ptr, bus_size_t cnt)
706 {
707 int dummy1;
708 void *dummy2;
709 int dummy3;
710 int __x;
711 u_int32_t port = h + o;
712 __asm volatile(
713 "1: inb %w1,%%al ;"
714 " stosb ;"
715 " incl %1 ;"
716 " loop 1b" :
717 "=&a" (__x), "=d" (dummy1), "=D" (dummy2),
718 "=c" (dummy3) :
719 "1" (port), "2" (ptr), "3" (cnt) :
720 "memory");
721 }
722
723 void
x86_bus_space_io_read_region_2(bus_space_handle_t h,bus_size_t o,u_int16_t * ptr,bus_size_t cnt)724 x86_bus_space_io_read_region_2(bus_space_handle_t h,
725 bus_size_t o, u_int16_t *ptr, bus_size_t cnt)
726 {
727 int dummy1;
728 void *dummy2;
729 int dummy3;
730 int __x;
731 u_int32_t port = h + o;
732 __asm volatile(
733 "1: inw %w1,%%ax ;"
734 " stosw ;"
735 " addl $2,%1 ;"
736 " loop 1b" :
737 "=&a" (__x), "=d" (dummy1), "=D" (dummy2),
738 "=c" (dummy3) :
739 "1" ((port)), "2" ((ptr)), "3" ((cnt)) :
740 "memory");
741 }
742
743 void
x86_bus_space_io_read_region_4(bus_space_handle_t h,bus_size_t o,u_int32_t * ptr,bus_size_t cnt)744 x86_bus_space_io_read_region_4(bus_space_handle_t h,
745 bus_size_t o, u_int32_t *ptr, bus_size_t cnt)
746 {
747 int dummy1;
748 void *dummy2;
749 int dummy3;
750 int __x;
751 u_int32_t port = h + o;
752 __asm volatile(
753 "1: inl %w1,%%eax ;"
754 " stosl ;"
755 " addl $4,%1 ;"
756 " loop 1b" :
757 "=&a" (__x), "=d" (dummy1), "=D" (dummy2),
758 "=c" (dummy3) :
759 "1" (port), "2" (ptr), "3" (cnt) :
760 "memory");
761 }
762
763 void
x86_bus_space_io_read_region_8(bus_space_handle_t h,bus_size_t o,u_int64_t * ptr,bus_size_t cnt)764 x86_bus_space_io_read_region_8(bus_space_handle_t h,
765 bus_size_t o, u_int64_t *ptr, bus_size_t cnt)
766 {
767 panic("bus_space_read_region_8: invalid bus space tag");
768 }
769
770 void
x86_bus_space_io_write_1(bus_space_handle_t h,bus_size_t o,u_int8_t v)771 x86_bus_space_io_write_1(bus_space_handle_t h, bus_size_t o, u_int8_t v)
772 {
773 outb(h + o, v);
774 }
775
776 void
x86_bus_space_io_write_2(bus_space_handle_t h,bus_size_t o,u_int16_t v)777 x86_bus_space_io_write_2(bus_space_handle_t h, bus_size_t o, u_int16_t v)
778 {
779 outw(h + o, v);
780 }
781
782 void
x86_bus_space_io_write_4(bus_space_handle_t h,bus_size_t o,u_int32_t v)783 x86_bus_space_io_write_4(bus_space_handle_t h, bus_size_t o, u_int32_t v)
784 {
785 outl(h + o, v);
786 }
787
788 void
x86_bus_space_io_write_8(bus_space_handle_t h,bus_size_t o,u_int64_t v)789 x86_bus_space_io_write_8(bus_space_handle_t h, bus_size_t o, u_int64_t v)
790 {
791 panic("bus_space_write_8: invalid bus space tag");
792 }
793
794 void
x86_bus_space_io_write_multi_1(bus_space_handle_t h,bus_size_t o,const u_int8_t * ptr,bus_size_t cnt)795 x86_bus_space_io_write_multi_1(bus_space_handle_t h,
796 bus_size_t o, const u_int8_t *ptr, bus_size_t cnt)
797 {
798 outsb(h + o, ptr, cnt);
799 }
800
801 void
x86_bus_space_io_write_multi_2(bus_space_handle_t h,bus_size_t o,const u_int16_t * ptr,bus_size_t cnt)802 x86_bus_space_io_write_multi_2(bus_space_handle_t h,
803 bus_size_t o, const u_int16_t *ptr, bus_size_t cnt)
804 {
805 outsw(h + o, ptr, cnt);
806 }
807
808 void
x86_bus_space_io_write_multi_4(bus_space_handle_t h,bus_size_t o,const u_int32_t * ptr,bus_size_t cnt)809 x86_bus_space_io_write_multi_4(bus_space_handle_t h,
810 bus_size_t o, const u_int32_t *ptr, bus_size_t cnt)
811 {
812 outsl(h + o, ptr, cnt);
813 }
814
815 void
x86_bus_space_io_write_multi_8(bus_space_handle_t h,bus_size_t o,const u_int64_t * ptr,bus_size_t cnt)816 x86_bus_space_io_write_multi_8(bus_space_handle_t h,
817 bus_size_t o, const u_int64_t *ptr, bus_size_t cnt)
818 {
819 panic("bus_space_write_multi_8: invalid bus space tag");
820 }
821
822 void
x86_bus_space_io_write_region_1(bus_space_handle_t h,bus_size_t o,const u_int8_t * ptr,bus_size_t cnt)823 x86_bus_space_io_write_region_1(bus_space_handle_t h,
824 bus_size_t o, const u_int8_t *ptr, bus_size_t cnt)
825 {
826 int dummy1;
827 void *dummy2;
828 int dummy3;
829 int __x;
830 u_int32_t port = h + o;
831 __asm volatile(
832 "1: lodsb ;"
833 " outb %%al,%w1 ;"
834 " incl %1 ;"
835 " loop 1b" :
836 "=&a" (__x), "=d" (dummy1), "=S" (dummy2),
837 "=c" (dummy3) :
838 "1" (port), "2" (ptr), "3" (cnt) :
839 "memory");
840 }
841
842 void
x86_bus_space_io_write_region_2(bus_space_handle_t h,bus_size_t o,const u_int16_t * ptr,bus_size_t cnt)843 x86_bus_space_io_write_region_2(bus_space_handle_t h,
844 bus_size_t o, const u_int16_t *ptr, bus_size_t cnt)
845 {
846 int dummy1;
847 void *dummy2;
848 int dummy3;
849 int __x;
850 u_int32_t port = h + o;
851 __asm volatile(
852 "1: lodsw ;"
853 " outw %%ax,%w1 ;"
854 " addl $2,%1 ;"
855 " loop 1b" :
856 "=&a" (__x), "=d" (dummy1), "=S" (dummy2),
857 "=c" (dummy3) :
858 "1" (port), "2" (ptr), "3" (cnt) :
859 "memory");
860 }
861
862 void
x86_bus_space_io_write_region_4(bus_space_handle_t h,bus_size_t o,const u_int32_t * ptr,bus_size_t cnt)863 x86_bus_space_io_write_region_4(bus_space_handle_t h,
864 bus_size_t o, const u_int32_t *ptr, bus_size_t cnt)
865 {
866 int dummy1;
867 void *dummy2;
868 int dummy3;
869 int __x;
870 u_int32_t port = h + o;
871 __asm volatile(
872 "1: lodsl ;"
873 " outl %%eax,%w1 ;"
874 " addl $4,%1 ;"
875 " loop 1b" :
876 "=&a" (__x), "=d" (dummy1), "=S" (dummy2),
877 "=c" (dummy3) :
878 "1" (port), "2" (ptr), "3" (cnt) :
879 "memory");
880 }
881
882 void
x86_bus_space_io_write_region_8(bus_space_handle_t h,bus_size_t o,const u_int64_t * ptr,bus_size_t cnt)883 x86_bus_space_io_write_region_8(bus_space_handle_t h,
884 bus_size_t o, const u_int64_t *ptr, bus_size_t cnt)
885 {
886 panic("bus_space_write_region_8: invalid bus space tag");
887 }
888
889 void
x86_bus_space_io_set_multi_1(bus_space_handle_t h,bus_size_t o,u_int8_t v,size_t c)890 x86_bus_space_io_set_multi_1(bus_space_handle_t h, bus_size_t o,
891 u_int8_t v, size_t c)
892 {
893 bus_addr_t addr = h + o;
894
895 while (c--)
896 outb(addr, v);
897 }
898
899 void
x86_bus_space_io_set_multi_2(bus_space_handle_t h,bus_size_t o,u_int16_t v,size_t c)900 x86_bus_space_io_set_multi_2(bus_space_handle_t h, bus_size_t o,
901 u_int16_t v, size_t c)
902 {
903 bus_addr_t addr = h + o;
904
905 while (c--)
906 outw(addr, v);
907 }
908
909 void
x86_bus_space_io_set_multi_4(bus_space_handle_t h,bus_size_t o,u_int32_t v,size_t c)910 x86_bus_space_io_set_multi_4(bus_space_handle_t h, bus_size_t o,
911 u_int32_t v, size_t c)
912 {
913 bus_addr_t addr = h + o;
914
915 while (c--)
916 outl(addr, v);
917 }
918
919 void
x86_bus_space_io_set_multi_8(bus_space_handle_t h,bus_size_t o,u_int64_t v,size_t c)920 x86_bus_space_io_set_multi_8(bus_space_handle_t h, bus_size_t o,
921 u_int64_t v, size_t c)
922 {
923 panic("bus_space_set_multi_8: invalid bus space tag");
924 }
925
926 void
x86_bus_space_io_set_region_1(bus_space_handle_t h,bus_size_t o,u_int8_t v,size_t c)927 x86_bus_space_io_set_region_1(bus_space_handle_t h, bus_size_t o,
928 u_int8_t v, size_t c)
929 {
930 bus_addr_t addr = h + o;
931
932 for (; c != 0; c--, addr++)
933 outb(addr, v);
934 }
935
936 void
x86_bus_space_io_set_region_2(bus_space_handle_t h,bus_size_t o,u_int16_t v,size_t c)937 x86_bus_space_io_set_region_2(bus_space_handle_t h, bus_size_t o,
938 u_int16_t v, size_t c)
939 {
940 bus_addr_t addr = h + o;
941
942 for (; c != 0; c--, addr += sizeof(v))
943 outw(addr, v);
944 }
945
946 void
x86_bus_space_io_set_region_4(bus_space_handle_t h,bus_size_t o,u_int32_t v,size_t c)947 x86_bus_space_io_set_region_4(bus_space_handle_t h, bus_size_t o,
948 u_int32_t v, size_t c)
949 {
950 bus_addr_t addr = h + o;
951
952 for (; c != 0; c--, addr += sizeof(v))
953 outl(addr, v);
954 }
955
956 void
x86_bus_space_io_set_region_8(bus_space_handle_t h,bus_size_t o,u_int64_t v,size_t c)957 x86_bus_space_io_set_region_8(bus_space_handle_t h, bus_size_t o,
958 u_int64_t v, size_t c)
959 {
960 panic("bus_space_set_region_8: invalid bus space tag");
961 }
962
963 void
x86_bus_space_io_copy_1(bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,size_t c)964 x86_bus_space_io_copy_1(bus_space_handle_t h1, bus_size_t o1,
965 bus_space_handle_t h2, bus_size_t o2, size_t c)
966 {
967 bus_addr_t addr1 = h1 + o1;
968 bus_addr_t addr2 = h2 + o2;
969
970 if (addr1 >= addr2) {
971 /* src after dest: copy forward */
972 for (; c != 0; c--, addr1++, addr2++)
973 outb(addr2, inb(addr1));
974 } else {
975 /* dest after src: copy backwards */
976 for (addr1 += (c - 1), addr2 += (c - 1);
977 c != 0; c--, addr1--, addr2--)
978 outb(addr2, inb(addr1));
979 }
980 }
981
982 void
x86_bus_space_io_copy_2(bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,size_t c)983 x86_bus_space_io_copy_2(bus_space_handle_t h1, bus_size_t o1,
984 bus_space_handle_t h2, bus_size_t o2, size_t c)
985 {
986 bus_addr_t addr1 = h1 + o1;
987 bus_addr_t addr2 = h2 + o2;
988
989 if (addr1 >= addr2) {
990 /* src after dest: copy forward */
991 for (; c != 0; c--, addr1 += 2, addr2 += 2)
992 outw(addr2, inw(addr1));
993 } else {
994 /* dest after src: copy backwards */
995 for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1);
996 c != 0; c--, addr1 -= 2, addr2 -= 2)
997 outw(addr2, inw(addr1));
998 }
999 }
1000
1001 void
x86_bus_space_io_copy_4(bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,size_t c)1002 x86_bus_space_io_copy_4(bus_space_handle_t h1, bus_size_t o1,
1003 bus_space_handle_t h2, bus_size_t o2, size_t c)
1004 {
1005 bus_addr_t addr1 = h1 + o1;
1006 bus_addr_t addr2 = h2 + o2;
1007
1008 if (addr1 >= addr2) {
1009 /* src after dest: copy forward */
1010 for (; c != 0; c--, addr1 += 4, addr2 += 4)
1011 outl(addr2, inl(addr1));
1012 } else {
1013 /* dest after src: copy backwards */
1014 for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1);
1015 c != 0; c--, addr1 -= 4, addr2 -= 4)
1016 outl(addr2, inl(addr1));
1017 }
1018 }
1019
1020 void
x86_bus_space_io_copy_8(bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,size_t c)1021 x86_bus_space_io_copy_8(bus_space_handle_t h1, bus_size_t o1,
1022 bus_space_handle_t h2, bus_size_t o2, size_t c)
1023 {
1024 panic("bus_space_set_region_8: invalid bus space tag");
1025 }
1026
1027 void *
x86_bus_space_io_vaddr(bus_space_handle_t h)1028 x86_bus_space_io_vaddr(bus_space_handle_t h)
1029 {
1030 return (NULL);
1031 }
1032
1033 paddr_t
x86_bus_space_io_mmap(bus_addr_t addr,off_t off,int prot,int flags)1034 x86_bus_space_io_mmap(bus_addr_t addr, off_t off, int prot, int flags)
1035 {
1036 /* Can't mmap I/O space. */
1037 return (-1);
1038 }
1039
1040 void
x86_bus_space_mem_write_1(bus_space_handle_t h,bus_size_t o,u_int8_t v)1041 x86_bus_space_mem_write_1(bus_space_handle_t h, bus_size_t o, u_int8_t v)
1042 {
1043 *(volatile u_int8_t *)(h + o) = v;
1044 }
1045
1046 void
x86_bus_space_mem_write_2(bus_space_handle_t h,bus_size_t o,u_int16_t v)1047 x86_bus_space_mem_write_2(bus_space_handle_t h, bus_size_t o, u_int16_t v)
1048 {
1049 *(volatile u_int16_t *)(h + o) = v;
1050 }
1051
1052 u_int8_t
x86_bus_space_mem_read_1(bus_space_handle_t h,bus_size_t o)1053 x86_bus_space_mem_read_1(bus_space_handle_t h, bus_size_t o)
1054 {
1055 return (*(volatile u_int8_t *)(h + o));
1056 }
1057
1058 u_int16_t
x86_bus_space_mem_read_2(bus_space_handle_t h,bus_size_t o)1059 x86_bus_space_mem_read_2(bus_space_handle_t h, bus_size_t o)
1060 {
1061 return (*(volatile u_int16_t *)(h + o));
1062 }
1063
1064 u_int32_t
x86_bus_space_mem_read_4(bus_space_handle_t h,bus_size_t o)1065 x86_bus_space_mem_read_4(bus_space_handle_t h, bus_size_t o)
1066 {
1067 return (*(volatile u_int32_t *)(h + o));
1068 }
1069
1070 u_int64_t
x86_bus_space_mem_read_8(bus_space_handle_t h,bus_size_t o)1071 x86_bus_space_mem_read_8(bus_space_handle_t h, bus_size_t o)
1072 {
1073 return (*(volatile u_int64_t *)(h + o));
1074 }
1075
1076 void
x86_bus_space_mem_read_multi_1(bus_space_handle_t h,bus_size_t o,u_int8_t * ptr,bus_size_t cnt)1077 x86_bus_space_mem_read_multi_1(bus_space_handle_t h, bus_size_t o,
1078 u_int8_t *ptr, bus_size_t cnt)
1079 {
1080 void *dummy1;
1081 int dummy2;
1082 void *dummy3;
1083 int __x;
1084 __asm volatile(
1085 "1: movb (%2),%%al ;"
1086 " stosb ;"
1087 " loop 1b" :
1088 "=D" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) :
1089 "0" ((ptr)), "1" ((cnt)), "2" (h + o) :
1090 "memory");
1091 }
1092
1093 void
x86_bus_space_mem_read_multi_2(bus_space_handle_t h,bus_size_t o,u_int16_t * ptr,bus_size_t cnt)1094 x86_bus_space_mem_read_multi_2(bus_space_handle_t h, bus_size_t o,
1095 u_int16_t *ptr, bus_size_t cnt)
1096 {
1097 void *dummy1;
1098 int dummy2;
1099 void *dummy3;
1100 int __x;
1101 __asm volatile(
1102 "1: movw (%2),%%ax ;"
1103 " stosw ;"
1104 " loop 1b" :
1105 "=D" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) :
1106 "0" ((ptr)), "1" ((cnt)), "2" (h + o) :
1107 "memory");
1108 }
1109
1110 void
x86_bus_space_mem_read_multi_4(bus_space_handle_t h,bus_size_t o,u_int32_t * ptr,bus_size_t cnt)1111 x86_bus_space_mem_read_multi_4(bus_space_handle_t h, bus_size_t o,
1112 u_int32_t *ptr, bus_size_t cnt)
1113 {
1114 void *dummy1;
1115 int dummy2;
1116 void *dummy3;
1117 int __x;
1118 __asm volatile(
1119 "1: movl (%2),%%eax ;"
1120 " stosl ;"
1121 " loop 1b" :
1122 "=D" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) :
1123 "0" ((ptr)), "1" ((cnt)), "2" (h + o) :
1124 "memory");
1125 }
1126
1127 void
x86_bus_space_mem_read_multi_8(bus_space_handle_t h,bus_size_t o,u_int64_t * ptr,bus_size_t cnt)1128 x86_bus_space_mem_read_multi_8(bus_space_handle_t h, bus_size_t o,
1129 u_int64_t *ptr, bus_size_t cnt)
1130 {
1131 void *dummy1;
1132 int dummy2;
1133 void *dummy3;
1134 int __x;
1135 __asm volatile(
1136 "1: movq (%2),%%rax ;"
1137 " stosq ;"
1138 " loop 1b" :
1139 "=D" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) :
1140 "0" ((ptr)), "1" ((cnt)), "2" (h + o) :
1141 "memory");
1142 }
1143
1144 void
x86_bus_space_mem_read_region_1(bus_space_handle_t h,bus_size_t o,u_int8_t * ptr,bus_size_t cnt)1145 x86_bus_space_mem_read_region_1(bus_space_handle_t h,
1146 bus_size_t o, u_int8_t *ptr, bus_size_t cnt)
1147 {
1148 int dummy1;
1149 void *dummy2;
1150 int dummy3;
1151 __asm volatile(
1152 " repne ;"
1153 " movsb" :
1154 "=S" (dummy1), "=D" (dummy2), "=c" (dummy3) :
1155 "0" (h + o), "1" (ptr), "2" (cnt) :
1156 "memory");
1157 }
1158
1159 void
x86_bus_space_mem_read_region_2(bus_space_handle_t h,bus_size_t o,u_int16_t * ptr,bus_size_t cnt)1160 x86_bus_space_mem_read_region_2(bus_space_handle_t h,
1161 bus_size_t o, u_int16_t *ptr, bus_size_t cnt)
1162 {
1163 int dummy1;
1164 void *dummy2;
1165 int dummy3;
1166 __asm volatile(
1167 " repne ;"
1168 " movsw" :
1169 "=S" (dummy1), "=D" (dummy2), "=c" (dummy3) :
1170 "0" (h + o), "1" (ptr), "2" (cnt) :
1171 "memory");
1172 }
1173
1174 void
x86_bus_space_mem_read_region_4(bus_space_handle_t h,bus_size_t o,u_int32_t * ptr,bus_size_t cnt)1175 x86_bus_space_mem_read_region_4(bus_space_handle_t h,
1176 bus_size_t o, u_int32_t *ptr, bus_size_t cnt)
1177 {
1178 int dummy1;
1179 void *dummy2;
1180 int dummy3;
1181 __asm volatile(
1182 " repne ;"
1183 " movsl" :
1184 "=S" (dummy1), "=D" (dummy2), "=c" (dummy3) :
1185 "0" (h + o), "1" (ptr), "2" (cnt) :
1186 "memory");
1187 }
1188
1189 void
x86_bus_space_mem_read_region_8(bus_space_handle_t h,bus_size_t o,u_int64_t * ptr,bus_size_t cnt)1190 x86_bus_space_mem_read_region_8(bus_space_handle_t h,
1191 bus_size_t o, u_int64_t *ptr, bus_size_t cnt)
1192 {
1193 int dummy1;
1194 void *dummy2;
1195 int dummy3;
1196 __asm volatile(
1197 " repne ;"
1198 " movsq" :
1199 "=S" (dummy1), "=D" (dummy2), "=c" (dummy3) :
1200 "0" (h + o), "1" (ptr), "2" (cnt) :
1201 "memory");
1202 }
1203
1204 void
x86_bus_space_mem_write_4(bus_space_handle_t h,bus_size_t o,u_int32_t v)1205 x86_bus_space_mem_write_4(bus_space_handle_t h, bus_size_t o, u_int32_t v)
1206 {
1207 *(volatile u_int32_t *)(h + o) = v;
1208 }
1209
1210 void
x86_bus_space_mem_write_8(bus_space_handle_t h,bus_size_t o,u_int64_t v)1211 x86_bus_space_mem_write_8(bus_space_handle_t h, bus_size_t o, u_int64_t v)
1212 {
1213 *(volatile u_int64_t *)(h + o) = v;
1214 }
1215
1216 void
x86_bus_space_mem_write_multi_1(bus_space_handle_t h,bus_size_t o,const u_int8_t * ptr,bus_size_t cnt)1217 x86_bus_space_mem_write_multi_1(bus_space_handle_t h,
1218 bus_size_t o, const u_int8_t *ptr, bus_size_t cnt)
1219 {
1220 void *dummy1;
1221 int dummy2;
1222 void *dummy3;
1223 int __x;
1224 __asm volatile(
1225 "1: lodsb ;"
1226 " movb %%al,(%2) ;"
1227 " loop 1b" :
1228 "=S" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) :
1229 "0" (ptr), "1" (cnt), "2" (h + o));
1230 }
1231
1232 void
x86_bus_space_mem_write_multi_2(bus_space_handle_t h,bus_size_t o,const u_int16_t * ptr,bus_size_t cnt)1233 x86_bus_space_mem_write_multi_2(bus_space_handle_t h,
1234 bus_size_t o, const u_int16_t *ptr, bus_size_t cnt)
1235 {
1236 void *dummy1;
1237 int dummy2;
1238 void *dummy3;
1239 int __x;
1240 __asm volatile(
1241 "1: lodsw ;"
1242 " movw %%ax,(%2) ;"
1243 " loop 1b" :
1244 "=S" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) :
1245 "0" (ptr), "1" (cnt), "2" (h + o));
1246 }
1247
1248 void
x86_bus_space_mem_write_multi_4(bus_space_handle_t h,bus_size_t o,const u_int32_t * ptr,bus_size_t cnt)1249 x86_bus_space_mem_write_multi_4(bus_space_handle_t h,
1250 bus_size_t o, const u_int32_t *ptr, bus_size_t cnt)
1251 {
1252 void *dummy1;
1253 int dummy2;
1254 void *dummy3;
1255 int __x;
1256 __asm volatile(
1257 "1: lodsl ;"
1258 " movl %%eax,(%2) ;"
1259 " loop 1b" :
1260 "=S" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) :
1261 "0" (ptr), "1" (cnt), "2" (h + o));
1262 }
1263
1264 void
x86_bus_space_mem_write_multi_8(bus_space_handle_t h,bus_size_t o,const u_int64_t * ptr,bus_size_t cnt)1265 x86_bus_space_mem_write_multi_8(bus_space_handle_t h,
1266 bus_size_t o, const u_int64_t *ptr, bus_size_t cnt)
1267 {
1268 void *dummy1;
1269 int dummy2;
1270 void *dummy3;
1271 int __x;
1272 __asm volatile(
1273 "1: lodsq ;"
1274 " movq %%rax,(%2) ;"
1275 " loop 1b" :
1276 "=S" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) :
1277 "0" (ptr), "1" (cnt), "2" (h + o));
1278 }
1279
1280 void
x86_bus_space_mem_write_region_1(bus_space_handle_t h,bus_size_t o,const u_int8_t * ptr,bus_size_t cnt)1281 x86_bus_space_mem_write_region_1(bus_space_handle_t h,
1282 bus_size_t o, const u_int8_t *ptr, bus_size_t cnt)
1283 {
1284 int dummy1;
1285 void *dummy2;
1286 int dummy3;
1287 __asm volatile(
1288 " repne ;"
1289 " movsb" :
1290 "=D" (dummy1), "=S" (dummy2), "=c" (dummy3) :
1291 "0" (h + o), "1" (ptr), "2" (cnt) :
1292 "memory");
1293 }
1294
1295 void
x86_bus_space_mem_write_region_2(bus_space_handle_t h,bus_size_t o,const u_int16_t * ptr,bus_size_t cnt)1296 x86_bus_space_mem_write_region_2(bus_space_handle_t h,
1297 bus_size_t o, const u_int16_t *ptr, bus_size_t cnt)
1298 {
1299 int dummy1;
1300 void *dummy2;
1301 int dummy3;
1302 __asm volatile(
1303 " repne ;"
1304 " movsw" :
1305 "=D" (dummy1), "=S" (dummy2), "=c" (dummy3) :
1306 "0" (h + o), "1" (ptr), "2" (cnt) :
1307 "memory");
1308 }
1309
1310 void
x86_bus_space_mem_write_region_4(bus_space_handle_t h,bus_size_t o,const u_int32_t * ptr,bus_size_t cnt)1311 x86_bus_space_mem_write_region_4(bus_space_handle_t h,
1312 bus_size_t o, const u_int32_t *ptr, bus_size_t cnt)
1313 {
1314 int dummy1;
1315 void *dummy2;
1316 int dummy3;
1317 __asm volatile(
1318 " repne ;"
1319 " movsl" :
1320 "=D" (dummy1), "=S" (dummy2), "=c" (dummy3) :
1321 "0" (h + o), "1" (ptr), "2" (cnt) :
1322 "memory");
1323 }
1324
1325 void
x86_bus_space_mem_write_region_8(bus_space_handle_t h,bus_size_t o,const u_int64_t * ptr,bus_size_t cnt)1326 x86_bus_space_mem_write_region_8(bus_space_handle_t h,
1327 bus_size_t o, const u_int64_t *ptr, bus_size_t cnt)
1328 {
1329 int dummy1;
1330 void *dummy2;
1331 int dummy3;
1332 __asm volatile(
1333 " repne ;"
1334 " movsq" :
1335 "=D" (dummy1), "=S" (dummy2), "=c" (dummy3) :
1336 "0" (h + o), "1" (ptr), "2" (cnt) :
1337 "memory");
1338 }
1339
1340 void
x86_bus_space_mem_set_multi_1(bus_space_handle_t h,bus_size_t o,u_int8_t v,size_t c)1341 x86_bus_space_mem_set_multi_1(bus_space_handle_t h, bus_size_t o,
1342 u_int8_t v, size_t c)
1343 {
1344 bus_addr_t addr = h + o;
1345
1346 while (c--)
1347 *(volatile u_int8_t *)(addr) = v;
1348 }
1349
1350 void
x86_bus_space_mem_set_multi_2(bus_space_handle_t h,bus_size_t o,u_int16_t v,size_t c)1351 x86_bus_space_mem_set_multi_2(bus_space_handle_t h, bus_size_t o,
1352 u_int16_t v, size_t c)
1353 {
1354 bus_addr_t addr = h + o;
1355
1356 while (c--)
1357 *(volatile u_int16_t *)(addr) = v;
1358 }
1359
1360 void
x86_bus_space_mem_set_multi_4(bus_space_handle_t h,bus_size_t o,u_int32_t v,size_t c)1361 x86_bus_space_mem_set_multi_4(bus_space_handle_t h, bus_size_t o,
1362 u_int32_t v, size_t c)
1363 {
1364 bus_addr_t addr = h + o;
1365
1366 while (c--)
1367 *(volatile u_int32_t *)(addr) = v;
1368 }
1369
1370 void
x86_bus_space_mem_set_multi_8(bus_space_handle_t h,bus_size_t o,u_int64_t v,size_t c)1371 x86_bus_space_mem_set_multi_8(bus_space_handle_t h, bus_size_t o,
1372 u_int64_t v, size_t c)
1373 {
1374 bus_addr_t addr = h + o;
1375
1376 while (c--)
1377 *(volatile u_int64_t *)(addr) = v;
1378 }
1379
1380 void
x86_bus_space_mem_set_region_1(bus_space_handle_t h,bus_size_t o,u_int8_t v,size_t c)1381 x86_bus_space_mem_set_region_1(bus_space_handle_t h, bus_size_t o,
1382 u_int8_t v, size_t c)
1383 {
1384 bus_addr_t addr = h + o;
1385
1386 for (; c != 0; c--, addr++)
1387 *(volatile u_int8_t *)(addr) = v;
1388 }
1389
1390 void
x86_bus_space_mem_set_region_2(bus_space_handle_t h,bus_size_t o,u_int16_t v,size_t c)1391 x86_bus_space_mem_set_region_2(bus_space_handle_t h, bus_size_t o,
1392 u_int16_t v, size_t c)
1393 {
1394 bus_addr_t addr = h + o;
1395
1396 for (; c != 0; c--, addr += sizeof(v))
1397 *(volatile u_int16_t *)(addr) = v;
1398 }
1399
1400 void
x86_bus_space_mem_set_region_4(bus_space_handle_t h,bus_size_t o,u_int32_t v,size_t c)1401 x86_bus_space_mem_set_region_4(bus_space_handle_t h, bus_size_t o,
1402 u_int32_t v, size_t c)
1403 {
1404 bus_addr_t addr = h + o;
1405
1406 for (; c != 0; c--, addr += sizeof(v))
1407 *(volatile u_int32_t *)(addr) = v;
1408 }
1409
1410 void
x86_bus_space_mem_set_region_8(bus_space_handle_t h,bus_size_t o,u_int64_t v,size_t c)1411 x86_bus_space_mem_set_region_8(bus_space_handle_t h, bus_size_t o,
1412 u_int64_t v, size_t c)
1413 {
1414 bus_addr_t addr = h + o;
1415
1416 for (; c != 0; c--, addr += sizeof(v))
1417 *(volatile u_int64_t *)(addr) = v;
1418 }
1419
1420 void
x86_bus_space_mem_copy_1(bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,size_t c)1421 x86_bus_space_mem_copy_1( bus_space_handle_t h1, bus_size_t o1,
1422 bus_space_handle_t h2, bus_size_t o2, size_t c)
1423 {
1424 bus_addr_t addr1 = h1 + o1;
1425 bus_addr_t addr2 = h2 + o2;
1426
1427 if (addr1 >= addr2) {
1428 /* src after dest: copy forward */
1429 for (; c != 0; c--, addr1++, addr2++)
1430 *(volatile u_int8_t *)(addr2) =
1431 *(volatile u_int8_t *)(addr1);
1432 } else {
1433 /* dest after src: copy backwards */
1434 for (addr1 += (c - 1), addr2 += (c - 1);
1435 c != 0; c--, addr1--, addr2--)
1436 *(volatile u_int8_t *)(addr2) =
1437 *(volatile u_int8_t *)(addr1);
1438 }
1439 }
1440
1441 void
x86_bus_space_mem_copy_2(bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,size_t c)1442 x86_bus_space_mem_copy_2(bus_space_handle_t h1, bus_size_t o1,
1443 bus_space_handle_t h2, bus_size_t o2, size_t c)
1444 {
1445 bus_addr_t addr1 = h1 + o1;
1446 bus_addr_t addr2 = h2 + o2;
1447
1448 if (addr1 >= addr2) {
1449 /* src after dest: copy forward */
1450 for (; c != 0; c--, addr1 += 2, addr2 += 2)
1451 *(volatile u_int16_t *)(addr2) =
1452 *(volatile u_int16_t *)(addr1);
1453 } else {
1454 /* dest after src: copy backwards */
1455 for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1);
1456 c != 0; c--, addr1 -= 2, addr2 -= 2)
1457 *(volatile u_int16_t *)(addr2) =
1458 *(volatile u_int16_t *)(addr1);
1459 }
1460 }
1461
1462 void
x86_bus_space_mem_copy_4(bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,size_t c)1463 x86_bus_space_mem_copy_4(bus_space_handle_t h1, bus_size_t o1,
1464 bus_space_handle_t h2, bus_size_t o2, size_t c)
1465 {
1466 bus_addr_t addr1 = h1 + o1;
1467 bus_addr_t addr2 = h2 + o2;
1468
1469 if (addr1 >= addr2) {
1470 /* src after dest: copy forward */
1471 for (; c != 0; c--, addr1 += 4, addr2 += 4)
1472 *(volatile u_int32_t *)(addr2) =
1473 *(volatile u_int32_t *)(addr1);
1474 } else {
1475 /* dest after src: copy backwards */
1476 for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1);
1477 c != 0; c--, addr1 -= 4, addr2 -= 4)
1478 *(volatile u_int32_t *)(addr2) =
1479 *(volatile u_int32_t *)(addr1);
1480 }
1481 }
1482
1483 void
x86_bus_space_mem_copy_8(bus_space_handle_t h1,bus_size_t o1,bus_space_handle_t h2,bus_size_t o2,size_t c)1484 x86_bus_space_mem_copy_8(bus_space_handle_t h1, bus_size_t o1,
1485 bus_space_handle_t h2, bus_size_t o2, size_t c)
1486 {
1487 bus_addr_t addr1 = h1 + o1;
1488 bus_addr_t addr2 = h2 + o2;
1489
1490 if (addr1 >= addr2) {
1491 /* src after dest: copy forward */
1492 for (; c != 0; c--, addr1 += 8, addr2 += 8)
1493 *(volatile u_int64_t *)(addr2) =
1494 *(volatile u_int64_t *)(addr1);
1495 } else {
1496 /* dest after src: copy backwards */
1497 for (addr1 += 8 * (c - 1), addr2 += 8 * (c - 1);
1498 c != 0; c--, addr1 -= 8, addr2 -= 8)
1499 *(volatile u_int64_t *)(addr2) =
1500 *(volatile u_int64_t *)(addr1);
1501 }
1502 }
1503
1504 void *
x86_bus_space_mem_vaddr(bus_space_handle_t h)1505 x86_bus_space_mem_vaddr(bus_space_handle_t h)
1506 {
1507 return ((void *)h);
1508 }
1509
1510 paddr_t
x86_bus_space_mem_mmap(bus_addr_t addr,off_t off,int prot,int flags)1511 x86_bus_space_mem_mmap(bus_addr_t addr, off_t off, int prot, int flags)
1512 {
1513 /*
1514 * "addr" is the base address of the device we're mapping.
1515 * "off" is the offset into that device.
1516 *
1517 * Note we are called for each "page" in the device that
1518 * the upper layers want to map.
1519 */
1520 return (addr + off);
1521 }
1522