xref: /openbsd-src/sys/arch/amd64/amd64/bus_space.c (revision 36d473f7f0ead3c2cbb6b3d19866737bc94956ce)
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