Mon Jan 10 16:59:09 2011 UTC ()
Bump iomem_ex_storage from 16 to 64. Based on analysis from joda@:

	http://mail-index.netbsd.org/current-users/2010/10/01/msg014446.html

Discussed with mrg@ and jmcneill@.


(jruoho)
diff -r1.31 -r1.32 src/sys/arch/x86/x86/bus_space.c

cvs diff -r1.31 -r1.32 src/sys/arch/x86/x86/bus_space.c (switch to unified diff)

--- src/sys/arch/x86/x86/bus_space.c 2010/07/27 13:54:19 1.31
+++ src/sys/arch/x86/x86/bus_space.c 2011/01/10 16:59:09 1.32
@@ -1,718 +1,718 @@ @@ -1,718 +1,718 @@
1/* $NetBSD: bus_space.c,v 1.31 2010/07/27 13:54:19 jakllsch Exp $ */ 1/* $NetBSD: bus_space.c,v 1.32 2011/01/10 16:59:09 jruoho Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace 8 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
9 * Simulation Facility, NASA Ames Research Center. 9 * Simulation Facility, NASA Ames Research Center.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: bus_space.c,v 1.31 2010/07/27 13:54:19 jakllsch Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: bus_space.c,v 1.32 2011/01/10 16:59:09 jruoho Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38#include <sys/malloc.h> 38#include <sys/malloc.h>
39#include <sys/extent.h> 39#include <sys/extent.h>
40 40
41#include <uvm/uvm_extern.h> 41#include <uvm/uvm_extern.h>
42 42
43#include <dev/isa/isareg.h> 43#include <dev/isa/isareg.h>
44 44
45#include <sys/bus.h> 45#include <sys/bus.h>
46#include <machine/pio.h> 46#include <machine/pio.h>
47#include <machine/isa_machdep.h> 47#include <machine/isa_machdep.h>
48 48
49#ifdef XEN 49#ifdef XEN
50#include <xen/hypervisor.h> 50#include <xen/hypervisor.h>
51#endif 51#endif
52 52
53/* 53/*
54 * Macros for sanity-checking the aligned-ness of pointers passed to 54 * Macros for sanity-checking the aligned-ness of pointers passed to
55 * bus space ops. These are not strictly necessary on the x86, but 55 * bus space ops. These are not strictly necessary on the x86, but
56 * could lead to performance improvements, and help catch problems 56 * could lead to performance improvements, and help catch problems
57 * with drivers that would creep up on other architectures. 57 * with drivers that would creep up on other architectures.
58 */ 58 */
59#ifdef BUS_SPACE_DEBUG  59#ifdef BUS_SPACE_DEBUG
60#define BUS_SPACE_ALIGNED_ADDRESS(p, t) \ 60#define BUS_SPACE_ALIGNED_ADDRESS(p, t) \
61 ((((u_long)(p)) & (sizeof(t)-1)) == 0) 61 ((((u_long)(p)) & (sizeof(t)-1)) == 0)
62 62
63#define BUS_SPACE_ADDRESS_SANITY(p, t, d) \ 63#define BUS_SPACE_ADDRESS_SANITY(p, t, d) \
64({ \ 64({ \
65 if (BUS_SPACE_ALIGNED_ADDRESS((p), t) == 0) { \ 65 if (BUS_SPACE_ALIGNED_ADDRESS((p), t) == 0) { \
66 printf("%s 0x%lx not aligned to %zu bytes %s:%d\n", \ 66 printf("%s 0x%lx not aligned to %zu bytes %s:%d\n", \
67 d, (u_long)(p), sizeof(t), __FILE__, __LINE__); \ 67 d, (u_long)(p), sizeof(t), __FILE__, __LINE__); \
68 } \ 68 } \
69 (void) 0; \ 69 (void) 0; \
70}) 70})
71#else 71#else
72#define BUS_SPACE_ADDRESS_SANITY(p,t,d) (void) 0 72#define BUS_SPACE_ADDRESS_SANITY(p,t,d) (void) 0
73#endif /* BUS_SPACE_DEBUG */ 73#endif /* BUS_SPACE_DEBUG */
74 74
75/* 75/*
76 * Extent maps to manage I/O and memory space. Allocate 76 * Extent maps to manage I/O and memory space. Allocate
77 * storage for 8 regions in each, initially. Later, ioport_malloc_safe 77 * storage for 8 regions in each, initially. Later, ioport_malloc_safe
78 * will indicate that it's safe to use malloc() to dynamically allocate 78 * will indicate that it's safe to use malloc() to dynamically allocate
79 * region descriptors. 79 * region descriptors.
80 * 80 *
81 * N.B. At least two regions are _always_ allocated from the iomem 81 * N.B. At least two regions are _always_ allocated from the iomem
82 * extent map; (0 -> ISA hole) and (end of ISA hole -> end of RAM). 82 * extent map; (0 -> ISA hole) and (end of ISA hole -> end of RAM).
83 * 83 *
84 * The extent maps are not static! Machine-dependent ISA and EISA 84 * The extent maps are not static! Machine-dependent ISA and EISA
85 * routines need access to them for bus address space allocation. 85 * routines need access to them for bus address space allocation.
86 */ 86 */
87static long ioport_ex_storage[EXTENT_FIXED_STORAGE_SIZE(16) / sizeof(long)]; 87static long ioport_ex_storage[EXTENT_FIXED_STORAGE_SIZE(16) / sizeof(long)];
88static long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(16) / sizeof(long)]; 88static long iomem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(64) / sizeof(long)];
89struct extent *ioport_ex; 89struct extent *ioport_ex;
90struct extent *iomem_ex; 90struct extent *iomem_ex;
91static int ioport_malloc_safe; 91static int ioport_malloc_safe;
92 92
93static struct bus_space_tag x86_io = { .bst_type = X86_BUS_SPACE_IO }; 93static struct bus_space_tag x86_io = { .bst_type = X86_BUS_SPACE_IO };
94static struct bus_space_tag x86_mem = { .bst_type = X86_BUS_SPACE_MEM }; 94static struct bus_space_tag x86_mem = { .bst_type = X86_BUS_SPACE_MEM };
95 95
96bus_space_tag_t x86_bus_space_io = &x86_io; 96bus_space_tag_t x86_bus_space_io = &x86_io;
97bus_space_tag_t x86_bus_space_mem = &x86_mem; 97bus_space_tag_t x86_bus_space_mem = &x86_mem;
98 98
99int x86_mem_add_mapping(bus_addr_t, bus_size_t, 99int x86_mem_add_mapping(bus_addr_t, bus_size_t,
100 int, bus_space_handle_t *); 100 int, bus_space_handle_t *);
101 101
102static inline bool 102static inline bool
103x86_bus_space_is_io(bus_space_tag_t t) 103x86_bus_space_is_io(bus_space_tag_t t)
104{ 104{
105 return t->bst_type == X86_BUS_SPACE_IO; 105 return t->bst_type == X86_BUS_SPACE_IO;
106} 106}
107 107
108static inline bool 108static inline bool
109x86_bus_space_is_mem(bus_space_tag_t t) 109x86_bus_space_is_mem(bus_space_tag_t t)
110{ 110{
111 return t->bst_type == X86_BUS_SPACE_MEM; 111 return t->bst_type == X86_BUS_SPACE_MEM;
112} 112}
113 113
114void 114void
115x86_bus_space_init(void) 115x86_bus_space_init(void)
116{ 116{
117 /* 117 /*
118 * Initialize the I/O port and I/O mem extent maps. 118 * Initialize the I/O port and I/O mem extent maps.
119 * Note: we don't have to check the return value since 119 * Note: we don't have to check the return value since
120 * creation of a fixed extent map will never fail (since 120 * creation of a fixed extent map will never fail (since
121 * descriptor storage has already been allocated). 121 * descriptor storage has already been allocated).
122 * 122 *
123 * N.B. The iomem extent manages _all_ physical addresses 123 * N.B. The iomem extent manages _all_ physical addresses
124 * on the machine. When the amount of RAM is found, the two 124 * on the machine. When the amount of RAM is found, the two
125 * extents of RAM are allocated from the map (0 -> ISA hole 125 * extents of RAM are allocated from the map (0 -> ISA hole
126 * and end of ISA hole -> end of RAM). 126 * and end of ISA hole -> end of RAM).
127 */ 127 */
128 ioport_ex = extent_create("ioport", 0x0, 0xffff, M_DEVBUF, 128 ioport_ex = extent_create("ioport", 0x0, 0xffff, M_DEVBUF,
129 (void *)ioport_ex_storage, sizeof(ioport_ex_storage), 129 (void *)ioport_ex_storage, sizeof(ioport_ex_storage),
130 EX_NOCOALESCE|EX_NOWAIT); 130 EX_NOCOALESCE|EX_NOWAIT);
131 iomem_ex = extent_create("iomem", 0x0, 0xffffffff, M_DEVBUF, 131 iomem_ex = extent_create("iomem", 0x0, 0xffffffff, M_DEVBUF,
132 (void *)iomem_ex_storage, sizeof(iomem_ex_storage), 132 (void *)iomem_ex_storage, sizeof(iomem_ex_storage),
133 EX_NOCOALESCE|EX_NOWAIT); 133 EX_NOCOALESCE|EX_NOWAIT);
134 134
135#ifdef XEN 135#ifdef XEN
136 /* We are privileged guest os - should have IO privileges. */ 136 /* We are privileged guest os - should have IO privileges. */
137 if (xendomain_is_privileged()) { 137 if (xendomain_is_privileged()) {
138 struct physdev_op physop; 138 struct physdev_op physop;
139 physop.cmd = PHYSDEVOP_SET_IOPL; 139 physop.cmd = PHYSDEVOP_SET_IOPL;
140 physop.u.set_iopl.iopl = 1; 140 physop.u.set_iopl.iopl = 1;
141 if (HYPERVISOR_physdev_op(&physop) != 0) 141 if (HYPERVISOR_physdev_op(&physop) != 0)
142 panic("Unable to obtain IOPL, " 142 panic("Unable to obtain IOPL, "
143 "despite being SIF_PRIVILEGED"); 143 "despite being SIF_PRIVILEGED");
144 } 144 }
145#endif /* XEN */ 145#endif /* XEN */
146} 146}
147 147
148void 148void
149x86_bus_space_mallocok(void) 149x86_bus_space_mallocok(void)
150{ 150{
151 151
152 ioport_malloc_safe = 1; 152 ioport_malloc_safe = 1;
153} 153}
154 154
155int 155int
156bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, 156bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size,
157 int flags, bus_space_handle_t *bshp) 157 int flags, bus_space_handle_t *bshp)
158{ 158{
159 int error; 159 int error;
160 struct extent *ex; 160 struct extent *ex;
161 161
162 /* 162 /*
163 * Pick the appropriate extent map. 163 * Pick the appropriate extent map.
164 */ 164 */
165 if (x86_bus_space_is_io(t)) { 165 if (x86_bus_space_is_io(t)) {
166 if (flags & BUS_SPACE_MAP_LINEAR) 166 if (flags & BUS_SPACE_MAP_LINEAR)
167 return (EOPNOTSUPP); 167 return (EOPNOTSUPP);
168 ex = ioport_ex; 168 ex = ioport_ex;
169 } else if (x86_bus_space_is_mem(t)) 169 } else if (x86_bus_space_is_mem(t))
170 ex = iomem_ex; 170 ex = iomem_ex;
171 else 171 else
172 panic("x86_memio_map: bad bus space tag"); 172 panic("x86_memio_map: bad bus space tag");
173 173
174 /* 174 /*
175 * Before we go any further, let's make sure that this 175 * Before we go any further, let's make sure that this
176 * region is available. 176 * region is available.
177 */ 177 */
178 error = extent_alloc_region(ex, bpa, size, 178 error = extent_alloc_region(ex, bpa, size,
179 EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0)); 179 EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0));
180 if (error) 180 if (error)
181 return (error); 181 return (error);
182 182
183 /* 183 /*
184 * For I/O space, that's all she wrote. 184 * For I/O space, that's all she wrote.
185 */ 185 */
186 if (x86_bus_space_is_io(t)) { 186 if (x86_bus_space_is_io(t)) {
187 *bshp = bpa; 187 *bshp = bpa;
188 return (0); 188 return (0);
189 } 189 }
190 190
191#ifndef XEN 191#ifndef XEN
192 if (bpa >= IOM_BEGIN && (bpa + size) != 0 && (bpa + size) <= IOM_END) { 192 if (bpa >= IOM_BEGIN && (bpa + size) != 0 && (bpa + size) <= IOM_END) {
193 *bshp = (bus_space_handle_t)ISA_HOLE_VADDR(bpa); 193 *bshp = (bus_space_handle_t)ISA_HOLE_VADDR(bpa);
194 return(0); 194 return(0);
195 } 195 }
196#endif /* !XEN */ 196#endif /* !XEN */
197 197
198 /* 198 /*
199 * For memory space, map the bus physical address to 199 * For memory space, map the bus physical address to
200 * a kernel virtual address. 200 * a kernel virtual address.
201 */ 201 */
202 error = x86_mem_add_mapping(bpa, size, flags, bshp); 202 error = x86_mem_add_mapping(bpa, size, flags, bshp);
203 if (error) { 203 if (error) {
204 if (extent_free(ex, bpa, size, EX_NOWAIT | 204 if (extent_free(ex, bpa, size, EX_NOWAIT |
205 (ioport_malloc_safe ? EX_MALLOCOK : 0))) { 205 (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
206 printf("x86_memio_map: pa 0x%jx, size 0x%jx\n", 206 printf("x86_memio_map: pa 0x%jx, size 0x%jx\n",
207 (uintmax_t)bpa, (uintmax_t)size); 207 (uintmax_t)bpa, (uintmax_t)size);
208 printf("x86_memio_map: can't free region\n"); 208 printf("x86_memio_map: can't free region\n");
209 } 209 }
210 } 210 }
211 211
212 return (error); 212 return (error);
213} 213}
214 214
215int 215int
216_x86_memio_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, 216_x86_memio_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size,
217 int flags, bus_space_handle_t *bshp) 217 int flags, bus_space_handle_t *bshp)
218{ 218{
219 219
220 /* 220 /*
221 * For I/O space, just fill in the handle. 221 * For I/O space, just fill in the handle.
222 */ 222 */
223 if (x86_bus_space_is_io(t)) { 223 if (x86_bus_space_is_io(t)) {
224 if (flags & BUS_SPACE_MAP_LINEAR) 224 if (flags & BUS_SPACE_MAP_LINEAR)
225 return (EOPNOTSUPP); 225 return (EOPNOTSUPP);
226 *bshp = bpa; 226 *bshp = bpa;
227 return (0); 227 return (0);
228 } 228 }
229 229
230 /* 230 /*
231 * For memory space, map the bus physical address to 231 * For memory space, map the bus physical address to
232 * a kernel virtual address. 232 * a kernel virtual address.
233 */ 233 */
234 return x86_mem_add_mapping(bpa, size, flags, bshp); 234 return x86_mem_add_mapping(bpa, size, flags, bshp);
235} 235}
236 236
237int 237int
238bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend, 238bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend,
239 bus_size_t size, bus_size_t alignment, bus_size_t boundary, 239 bus_size_t size, bus_size_t alignment, bus_size_t boundary,
240 int flags, bus_addr_t *bpap, bus_space_handle_t *bshp) 240 int flags, bus_addr_t *bpap, bus_space_handle_t *bshp)
241{ 241{
242 struct extent *ex; 242 struct extent *ex;
243 u_long bpa; 243 u_long bpa;
244 int error; 244 int error;
245 245
246 /* 246 /*
247 * Pick the appropriate extent map. 247 * Pick the appropriate extent map.
248 */ 248 */
249 if (x86_bus_space_is_io(t)) { 249 if (x86_bus_space_is_io(t)) {
250 if (flags & BUS_SPACE_MAP_LINEAR) 250 if (flags & BUS_SPACE_MAP_LINEAR)
251 return (EOPNOTSUPP); 251 return (EOPNOTSUPP);
252 ex = ioport_ex; 252 ex = ioport_ex;
253 } else if (x86_bus_space_is_mem(t)) 253 } else if (x86_bus_space_is_mem(t))
254 ex = iomem_ex; 254 ex = iomem_ex;
255 else 255 else
256 panic("x86_memio_alloc: bad bus space tag"); 256 panic("x86_memio_alloc: bad bus space tag");
257 257
258 /* 258 /*
259 * Sanity check the allocation against the extent's boundaries. 259 * Sanity check the allocation against the extent's boundaries.
260 */ 260 */
261 if (rstart < ex->ex_start || rend > ex->ex_end) 261 if (rstart < ex->ex_start || rend > ex->ex_end)
262 panic("x86_memio_alloc: bad region start/end"); 262 panic("x86_memio_alloc: bad region start/end");
263 263
264 /* 264 /*
265 * Do the requested allocation. 265 * Do the requested allocation.
266 */ 266 */
267 error = extent_alloc_subregion(ex, rstart, rend, size, alignment, 267 error = extent_alloc_subregion(ex, rstart, rend, size, alignment,
268 boundary, 268 boundary,
269 EX_FAST | EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0), 269 EX_FAST | EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0),
270 &bpa); 270 &bpa);
271 271
272 if (error) 272 if (error)
273 return (error); 273 return (error);
274 274
275 /* 275 /*
276 * For I/O space, that's all she wrote. 276 * For I/O space, that's all she wrote.
277 */ 277 */
278 if (x86_bus_space_is_io(t)) { 278 if (x86_bus_space_is_io(t)) {
279 *bshp = *bpap = bpa; 279 *bshp = *bpap = bpa;
280 return (0); 280 return (0);
281 } 281 }
282 282
283 /* 283 /*
284 * For memory space, map the bus physical address to 284 * For memory space, map the bus physical address to
285 * a kernel virtual address. 285 * a kernel virtual address.
286 */ 286 */
287 error = x86_mem_add_mapping(bpa, size, flags, bshp); 287 error = x86_mem_add_mapping(bpa, size, flags, bshp);
288 if (error) { 288 if (error) {
289 if (extent_free(iomem_ex, bpa, size, EX_NOWAIT | 289 if (extent_free(iomem_ex, bpa, size, EX_NOWAIT |
290 (ioport_malloc_safe ? EX_MALLOCOK : 0))) { 290 (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
291 printf("x86_memio_alloc: pa 0x%jx, size 0x%jx\n", 291 printf("x86_memio_alloc: pa 0x%jx, size 0x%jx\n",
292 (uintmax_t)bpa, (uintmax_t)size); 292 (uintmax_t)bpa, (uintmax_t)size);
293 printf("x86_memio_alloc: can't free region\n"); 293 printf("x86_memio_alloc: can't free region\n");
294 } 294 }
295 } 295 }
296 296
297 *bpap = bpa; 297 *bpap = bpa;
298 298
299 return (error); 299 return (error);
300} 300}
301 301
302int 302int
303x86_mem_add_mapping(bus_addr_t bpa, bus_size_t size, 303x86_mem_add_mapping(bus_addr_t bpa, bus_size_t size,
304 int flags, bus_space_handle_t *bshp) 304 int flags, bus_space_handle_t *bshp)
305{ 305{
306 paddr_t pa, endpa; 306 paddr_t pa, endpa;
307 vaddr_t va, sva; 307 vaddr_t va, sva;
308 u_int pmapflags; 308 u_int pmapflags;
309 309
310 pa = x86_trunc_page(bpa); 310 pa = x86_trunc_page(bpa);
311 endpa = x86_round_page(bpa + size); 311 endpa = x86_round_page(bpa + size);
312 312
313 pmapflags = PMAP_NOCACHE; 313 pmapflags = PMAP_NOCACHE;
314 if ((flags & BUS_SPACE_MAP_CACHEABLE) != 0) 314 if ((flags & BUS_SPACE_MAP_CACHEABLE) != 0)
315 pmapflags = 0; 315 pmapflags = 0;
316 else if (flags & BUS_SPACE_MAP_PREFETCHABLE) 316 else if (flags & BUS_SPACE_MAP_PREFETCHABLE)
317 pmapflags = PMAP_WRITE_COMBINE; 317 pmapflags = PMAP_WRITE_COMBINE;
318 318
319#ifdef DIAGNOSTIC 319#ifdef DIAGNOSTIC
320 if (endpa != 0 && endpa <= pa) 320 if (endpa != 0 && endpa <= pa)
321 panic("x86_mem_add_mapping: overflow"); 321 panic("x86_mem_add_mapping: overflow");
322#endif 322#endif
323 323
324#ifdef XEN 324#ifdef XEN
325 if (bpa >= IOM_BEGIN && (bpa + size) != 0 && (bpa + size) <= IOM_END) { 325 if (bpa >= IOM_BEGIN && (bpa + size) != 0 && (bpa + size) <= IOM_END) {
326 sva = (vaddr_t)ISA_HOLE_VADDR(pa); 326 sva = (vaddr_t)ISA_HOLE_VADDR(pa);
327 } else 327 } else
328#endif /* XEN */ 328#endif /* XEN */
329 { 329 {
330 sva = uvm_km_alloc(kernel_map, endpa - pa, 0, 330 sva = uvm_km_alloc(kernel_map, endpa - pa, 0,
331 UVM_KMF_VAONLY | UVM_KMF_NOWAIT); 331 UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
332 if (sva == 0) 332 if (sva == 0)
333 return (ENOMEM); 333 return (ENOMEM);
334 } 334 }
335 335
336 *bshp = (bus_space_handle_t)(sva + (bpa & PGOFSET)); 336 *bshp = (bus_space_handle_t)(sva + (bpa & PGOFSET));
337 337
338 for (va = sva; pa != endpa; pa += PAGE_SIZE, va += PAGE_SIZE) { 338 for (va = sva; pa != endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
339 pmap_kenter_ma(va, pa, VM_PROT_READ | VM_PROT_WRITE, pmapflags); 339 pmap_kenter_ma(va, pa, VM_PROT_READ | VM_PROT_WRITE, pmapflags);
340 } 340 }
341 pmap_update(pmap_kernel()); 341 pmap_update(pmap_kernel());
342 342
343 return 0; 343 return 0;
344} 344}
345 345
346bool 346bool
347bus_space_is_equal(bus_space_tag_t t1, bus_space_tag_t t2) 347bus_space_is_equal(bus_space_tag_t t1, bus_space_tag_t t2)
348{ 348{
349 if (t1 == NULL || t2 == NULL) 349 if (t1 == NULL || t2 == NULL)
350 return false; 350 return false;
351 return t1->bst_type == t2->bst_type; 351 return t1->bst_type == t2->bst_type;
352} 352}
353 353
354/* 354/*
355 * void _x86_memio_unmap(bus_space_tag bst, bus_space_handle bsh, 355 * void _x86_memio_unmap(bus_space_tag bst, bus_space_handle bsh,
356 * bus_size_t size, bus_addr_t *adrp) 356 * bus_size_t size, bus_addr_t *adrp)
357 * 357 *
358 * This function unmaps memory- or io-space mapped by the function 358 * This function unmaps memory- or io-space mapped by the function
359 * _x86_memio_map(). This function works nearly as same as 359 * _x86_memio_map(). This function works nearly as same as
360 * x86_memio_unmap(), but this function does not ask kernel 360 * x86_memio_unmap(), but this function does not ask kernel
361 * built-in extents and returns physical address of the bus space, 361 * built-in extents and returns physical address of the bus space,
362 * for the convenience of the extra extent manager. 362 * for the convenience of the extra extent manager.
363 */ 363 */
364void 364void
365_x86_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh, 365_x86_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
366 bus_size_t size, bus_addr_t *adrp) 366 bus_size_t size, bus_addr_t *adrp)
367{ 367{
368 u_long va, endva; 368 u_long va, endva;
369 bus_addr_t bpa; 369 bus_addr_t bpa;
370 370
371 /* 371 /*
372 * Find the correct extent and bus physical address. 372 * Find the correct extent and bus physical address.
373 */ 373 */
374 if (x86_bus_space_is_io(t)) { 374 if (x86_bus_space_is_io(t)) {
375 bpa = bsh; 375 bpa = bsh;
376 } else if (x86_bus_space_is_mem(t)) { 376 } else if (x86_bus_space_is_mem(t)) {
377 if (bsh >= atdevbase && (bsh + size) != 0 && 377 if (bsh >= atdevbase && (bsh + size) != 0 &&
378 (bsh + size) <= (atdevbase + IOM_SIZE)) { 378 (bsh + size) <= (atdevbase + IOM_SIZE)) {
379 bpa = (bus_addr_t)ISA_PHYSADDR(bsh); 379 bpa = (bus_addr_t)ISA_PHYSADDR(bsh);
380 } else { 380 } else {
381 381
382 va = x86_trunc_page(bsh); 382 va = x86_trunc_page(bsh);
383 endva = x86_round_page(bsh + size); 383 endva = x86_round_page(bsh + size);
384 384
385#ifdef DIAGNOSTIC 385#ifdef DIAGNOSTIC
386 if (endva <= va) { 386 if (endva <= va) {
387 panic("_x86_memio_unmap: overflow"); 387 panic("_x86_memio_unmap: overflow");
388 } 388 }
389#endif 389#endif
390 390
391 if (pmap_extract_ma(pmap_kernel(), va, &bpa) == FALSE) { 391 if (pmap_extract_ma(pmap_kernel(), va, &bpa) == FALSE) {
392 panic("_x86_memio_unmap:" 392 panic("_x86_memio_unmap:"
393 " wrong virtual address"); 393 " wrong virtual address");
394 } 394 }
395 bpa += (bsh & PGOFSET); 395 bpa += (bsh & PGOFSET);
396 pmap_kremove(va, endva - va); 396 pmap_kremove(va, endva - va);
397 pmap_update(pmap_kernel()); 397 pmap_update(pmap_kernel());
398 398
399 /* 399 /*
400 * Free the kernel virtual mapping. 400 * Free the kernel virtual mapping.
401 */ 401 */
402 uvm_km_free(kernel_map, va, endva - va, UVM_KMF_VAONLY); 402 uvm_km_free(kernel_map, va, endva - va, UVM_KMF_VAONLY);
403 } 403 }
404 } else { 404 } else {
405 panic("_x86_memio_unmap: bad bus space tag"); 405 panic("_x86_memio_unmap: bad bus space tag");
406 } 406 }
407 407
408 if (adrp != NULL) { 408 if (adrp != NULL) {
409 *adrp = bpa; 409 *adrp = bpa;
410 } 410 }
411} 411}
412 412
413void 413void
414bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size) 414bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
415{ 415{
416 struct extent *ex; 416 struct extent *ex;
417 u_long va, endva; 417 u_long va, endva;
418 bus_addr_t bpa; 418 bus_addr_t bpa;
419 419
420 /* 420 /*
421 * Find the correct extent and bus physical address. 421 * Find the correct extent and bus physical address.
422 */ 422 */
423 if (x86_bus_space_is_io(t)) { 423 if (x86_bus_space_is_io(t)) {
424 ex = ioport_ex; 424 ex = ioport_ex;
425 bpa = bsh; 425 bpa = bsh;
426 } else if (x86_bus_space_is_mem(t)) { 426 } else if (x86_bus_space_is_mem(t)) {
427 ex = iomem_ex; 427 ex = iomem_ex;
428 428
429 if (bsh >= atdevbase && (bsh + size) != 0 && 429 if (bsh >= atdevbase && (bsh + size) != 0 &&
430 (bsh + size) <= (atdevbase + IOM_SIZE)) { 430 (bsh + size) <= (atdevbase + IOM_SIZE)) {
431 bpa = (bus_addr_t)ISA_PHYSADDR(bsh); 431 bpa = (bus_addr_t)ISA_PHYSADDR(bsh);
432 goto ok; 432 goto ok;
433 } 433 }
434 434
435 va = x86_trunc_page(bsh); 435 va = x86_trunc_page(bsh);
436 endva = x86_round_page(bsh + size); 436 endva = x86_round_page(bsh + size);
437 437
438#ifdef DIAGNOSTIC 438#ifdef DIAGNOSTIC
439 if (endva <= va) 439 if (endva <= va)
440 panic("x86_memio_unmap: overflow"); 440 panic("x86_memio_unmap: overflow");
441#endif 441#endif
442 442
443 (void) pmap_extract_ma(pmap_kernel(), va, &bpa); 443 (void) pmap_extract_ma(pmap_kernel(), va, &bpa);
444 bpa += (bsh & PGOFSET); 444 bpa += (bsh & PGOFSET);
445 445
446 pmap_kremove(va, endva - va); 446 pmap_kremove(va, endva - va);
447 pmap_update(pmap_kernel()); 447 pmap_update(pmap_kernel());
448 448
449 /* 449 /*
450 * Free the kernel virtual mapping. 450 * Free the kernel virtual mapping.
451 */ 451 */
452 uvm_km_free(kernel_map, va, endva - va, UVM_KMF_VAONLY); 452 uvm_km_free(kernel_map, va, endva - va, UVM_KMF_VAONLY);
453 } else 453 } else
454 panic("x86_memio_unmap: bad bus space tag"); 454 panic("x86_memio_unmap: bad bus space tag");
455 455
456ok: 456ok:
457 if (extent_free(ex, bpa, size, 457 if (extent_free(ex, bpa, size,
458 EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0))) { 458 EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
459 printf("x86_memio_unmap: %s 0x%jx, size 0x%jx\n", 459 printf("x86_memio_unmap: %s 0x%jx, size 0x%jx\n",
460 x86_bus_space_is_io(t) ? "port" : "pa", 460 x86_bus_space_is_io(t) ? "port" : "pa",
461 (uintmax_t)bpa, (uintmax_t)size); 461 (uintmax_t)bpa, (uintmax_t)size);
462 printf("x86_memio_unmap: can't free region\n"); 462 printf("x86_memio_unmap: can't free region\n");
463 } 463 }
464} 464}
465 465
466void 466void
467bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size) 467bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
468{ 468{
469 469
470 /* bus_space_unmap() does all that we need to do. */ 470 /* bus_space_unmap() does all that we need to do. */
471 bus_space_unmap(t, bsh, size); 471 bus_space_unmap(t, bsh, size);
472} 472}
473 473
474int 474int
475bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh, 475bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
476 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp) 476 bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
477{ 477{
478 478
479 *nbshp = bsh + offset; 479 *nbshp = bsh + offset;
480 return (0); 480 return (0);
481} 481}
482 482
483paddr_t 483paddr_t
484bus_space_mmap(bus_space_tag_t t, bus_addr_t addr, off_t off, int prot, 484bus_space_mmap(bus_space_tag_t t, bus_addr_t addr, off_t off, int prot,
485 int flags) 485 int flags)
486{ 486{
487 487
488 /* Can't mmap I/O space. */ 488 /* Can't mmap I/O space. */
489 if (x86_bus_space_is_io(t)) 489 if (x86_bus_space_is_io(t))
490 return (-1); 490 return (-1);
491 491
492 /* 492 /*
493 * "addr" is the base address of the device we're mapping. 493 * "addr" is the base address of the device we're mapping.
494 * "off" is the offset into that device. 494 * "off" is the offset into that device.
495 * 495 *
496 * Note we are called for each "page" in the device that 496 * Note we are called for each "page" in the device that
497 * the upper layers want to map. 497 * the upper layers want to map.
498 */ 498 */
499 return (x86_btop(addr + off)); 499 return (x86_btop(addr + off));
500} 500}
501 501
502void 502void
503bus_space_set_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 503bus_space_set_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
504 uint8_t v, size_t c) 504 uint8_t v, size_t c)
505{ 505{
506 vaddr_t addr = h + o; 506 vaddr_t addr = h + o;
507 507
508 if (x86_bus_space_is_io(t)) 508 if (x86_bus_space_is_io(t))
509 while (c--) 509 while (c--)
510 outb(addr, v); 510 outb(addr, v);
511 else 511 else
512 while (c--) 512 while (c--)
513 *(volatile uint8_t *)(addr) = v; 513 *(volatile uint8_t *)(addr) = v;
514} 514}
515 515
516void 516void
517bus_space_set_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 517bus_space_set_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
518 uint16_t v, size_t c) 518 uint16_t v, size_t c)
519{ 519{
520 vaddr_t addr = h + o; 520 vaddr_t addr = h + o;
521 521
522 BUS_SPACE_ADDRESS_SANITY(addr, uint16_t, "bus addr"); 522 BUS_SPACE_ADDRESS_SANITY(addr, uint16_t, "bus addr");
523 523
524 if (x86_bus_space_is_io(t)) 524 if (x86_bus_space_is_io(t))
525 while (c--) 525 while (c--)
526 outw(addr, v); 526 outw(addr, v);
527 else 527 else
528 while (c--) 528 while (c--)
529 *(volatile uint16_t *)(addr) = v; 529 *(volatile uint16_t *)(addr) = v;
530} 530}
531 531
532void 532void
533bus_space_set_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 533bus_space_set_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
534 uint32_t v, size_t c) 534 uint32_t v, size_t c)
535{ 535{
536 vaddr_t addr = h + o; 536 vaddr_t addr = h + o;
537 537
538 BUS_SPACE_ADDRESS_SANITY(addr, uint32_t, "bus addr"); 538 BUS_SPACE_ADDRESS_SANITY(addr, uint32_t, "bus addr");
539 539
540 if (x86_bus_space_is_io(t)) 540 if (x86_bus_space_is_io(t))
541 while (c--) 541 while (c--)
542 outl(addr, v); 542 outl(addr, v);
543 else 543 else
544 while (c--) 544 while (c--)
545 *(volatile uint32_t *)(addr) = v; 545 *(volatile uint32_t *)(addr) = v;
546} 546}
547 547
548void 548void
549bus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 549bus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
550 uint8_t v, size_t c) 550 uint8_t v, size_t c)
551{ 551{
552 vaddr_t addr = h + o; 552 vaddr_t addr = h + o;
553 553
554 if (x86_bus_space_is_io(t)) 554 if (x86_bus_space_is_io(t))
555 for (; c != 0; c--, addr++) 555 for (; c != 0; c--, addr++)
556 outb(addr, v); 556 outb(addr, v);
557 else 557 else
558 for (; c != 0; c--, addr++) 558 for (; c != 0; c--, addr++)
559 *(volatile uint8_t *)(addr) = v; 559 *(volatile uint8_t *)(addr) = v;
560} 560}
561 561
562void 562void
563bus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 563bus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
564 uint16_t v, size_t c) 564 uint16_t v, size_t c)
565{ 565{
566 vaddr_t addr = h + o; 566 vaddr_t addr = h + o;
567 567
568 BUS_SPACE_ADDRESS_SANITY(addr, uint16_t, "bus addr"); 568 BUS_SPACE_ADDRESS_SANITY(addr, uint16_t, "bus addr");
569 569
570 if (x86_bus_space_is_io(t)) 570 if (x86_bus_space_is_io(t))
571 for (; c != 0; c--, addr += 2) 571 for (; c != 0; c--, addr += 2)
572 outw(addr, v); 572 outw(addr, v);
573 else 573 else
574 for (; c != 0; c--, addr += 2) 574 for (; c != 0; c--, addr += 2)
575 *(volatile uint16_t *)(addr) = v; 575 *(volatile uint16_t *)(addr) = v;
576} 576}
577 577
578void 578void
579bus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 579bus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
580 uint32_t v, size_t c) 580 uint32_t v, size_t c)
581{ 581{
582 vaddr_t addr = h + o; 582 vaddr_t addr = h + o;
583 583
584 BUS_SPACE_ADDRESS_SANITY(addr, uint32_t, "bus addr"); 584 BUS_SPACE_ADDRESS_SANITY(addr, uint32_t, "bus addr");
585 585
586 if (x86_bus_space_is_io(t)) 586 if (x86_bus_space_is_io(t))
587 for (; c != 0; c--, addr += 4) 587 for (; c != 0; c--, addr += 4)
588 outl(addr, v); 588 outl(addr, v);
589 else 589 else
590 for (; c != 0; c--, addr += 4) 590 for (; c != 0; c--, addr += 4)
591 *(volatile uint32_t *)(addr) = v; 591 *(volatile uint32_t *)(addr) = v;
592} 592}
593 593
594void 594void
595bus_space_copy_region_1(bus_space_tag_t t, bus_space_handle_t h1, 595bus_space_copy_region_1(bus_space_tag_t t, bus_space_handle_t h1,
596 bus_size_t o1, bus_space_handle_t h2, 596 bus_size_t o1, bus_space_handle_t h2,
597 bus_size_t o2, size_t c) 597 bus_size_t o2, size_t c)
598{ 598{
599 vaddr_t addr1 = h1 + o1; 599 vaddr_t addr1 = h1 + o1;
600 vaddr_t addr2 = h2 + o2; 600 vaddr_t addr2 = h2 + o2;
601 601
602 if (x86_bus_space_is_io(t)) { 602 if (x86_bus_space_is_io(t)) {
603 if (addr1 >= addr2) { 603 if (addr1 >= addr2) {
604 /* src after dest: copy forward */ 604 /* src after dest: copy forward */
605 for (; c != 0; c--, addr1++, addr2++) 605 for (; c != 0; c--, addr1++, addr2++)
606 outb(addr2, inb(addr1)); 606 outb(addr2, inb(addr1));
607 } else { 607 } else {
608 /* dest after src: copy backwards */ 608 /* dest after src: copy backwards */
609 for (addr1 += (c - 1), addr2 += (c - 1); 609 for (addr1 += (c - 1), addr2 += (c - 1);
610 c != 0; c--, addr1--, addr2--) 610 c != 0; c--, addr1--, addr2--)
611 outb(addr2, inb(addr1)); 611 outb(addr2, inb(addr1));
612 } 612 }
613 } else { 613 } else {
614 if (addr1 >= addr2) { 614 if (addr1 >= addr2) {
615 /* src after dest: copy forward */ 615 /* src after dest: copy forward */
616 for (; c != 0; c--, addr1++, addr2++) 616 for (; c != 0; c--, addr1++, addr2++)
617 *(volatile uint8_t *)(addr2) = 617 *(volatile uint8_t *)(addr2) =
618 *(volatile uint8_t *)(addr1); 618 *(volatile uint8_t *)(addr1);
619 } else { 619 } else {
620 /* dest after src: copy backwards */ 620 /* dest after src: copy backwards */
621 for (addr1 += (c - 1), addr2 += (c - 1); 621 for (addr1 += (c - 1), addr2 += (c - 1);
622 c != 0; c--, addr1--, addr2--) 622 c != 0; c--, addr1--, addr2--)
623 *(volatile uint8_t *)(addr2) = 623 *(volatile uint8_t *)(addr2) =
624 *(volatile uint8_t *)(addr1); 624 *(volatile uint8_t *)(addr1);
625 } 625 }
626 } 626 }
627} 627}
628 628
629void 629void
630bus_space_copy_region_2(bus_space_tag_t t, bus_space_handle_t h1, 630bus_space_copy_region_2(bus_space_tag_t t, bus_space_handle_t h1,
631 bus_size_t o1, bus_space_handle_t h2, 631 bus_size_t o1, bus_space_handle_t h2,
632 bus_size_t o2, size_t c) 632 bus_size_t o2, size_t c)
633{ 633{
634 vaddr_t addr1 = h1 + o1; 634 vaddr_t addr1 = h1 + o1;
635 vaddr_t addr2 = h2 + o2; 635 vaddr_t addr2 = h2 + o2;
636 636
637 BUS_SPACE_ADDRESS_SANITY(addr1, uint16_t, "bus addr 1"); 637 BUS_SPACE_ADDRESS_SANITY(addr1, uint16_t, "bus addr 1");
638 BUS_SPACE_ADDRESS_SANITY(addr2, uint16_t, "bus addr 2"); 638 BUS_SPACE_ADDRESS_SANITY(addr2, uint16_t, "bus addr 2");
639 639
640 if (x86_bus_space_is_io(t)) { 640 if (x86_bus_space_is_io(t)) {
641 if (addr1 >= addr2) { 641 if (addr1 >= addr2) {
642 /* src after dest: copy forward */ 642 /* src after dest: copy forward */
643 for (; c != 0; c--, addr1 += 2, addr2 += 2) 643 for (; c != 0; c--, addr1 += 2, addr2 += 2)
644 outw(addr2, inw(addr1)); 644 outw(addr2, inw(addr1));
645 } else { 645 } else {
646 /* dest after src: copy backwards */ 646 /* dest after src: copy backwards */
647 for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1); 647 for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1);
648 c != 0; c--, addr1 -= 2, addr2 -= 2) 648 c != 0; c--, addr1 -= 2, addr2 -= 2)
649 outw(addr2, inw(addr1)); 649 outw(addr2, inw(addr1));
650 } 650 }
651 } else { 651 } else {
652 if (addr1 >= addr2) { 652 if (addr1 >= addr2) {
653 /* src after dest: copy forward */ 653 /* src after dest: copy forward */
654 for (; c != 0; c--, addr1 += 2, addr2 += 2) 654 for (; c != 0; c--, addr1 += 2, addr2 += 2)
655 *(volatile uint16_t *)(addr2) = 655 *(volatile uint16_t *)(addr2) =
656 *(volatile uint16_t *)(addr1); 656 *(volatile uint16_t *)(addr1);
657 } else { 657 } else {
658 /* dest after src: copy backwards */ 658 /* dest after src: copy backwards */
659 for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1); 659 for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1);
660 c != 0; c--, addr1 -= 2, addr2 -= 2) 660 c != 0; c--, addr1 -= 2, addr2 -= 2)
661 *(volatile uint16_t *)(addr2) = 661 *(volatile uint16_t *)(addr2) =
662 *(volatile uint16_t *)(addr1); 662 *(volatile uint16_t *)(addr1);
663 } 663 }
664 } 664 }
665} 665}
666 666
667void 667void
668bus_space_copy_region_4(bus_space_tag_t t, bus_space_handle_t h1, 668bus_space_copy_region_4(bus_space_tag_t t, bus_space_handle_t h1,
669 bus_size_t o1, bus_space_handle_t h2, 669 bus_size_t o1, bus_space_handle_t h2,
670 bus_size_t o2, size_t c) 670 bus_size_t o2, size_t c)
671{ 671{
672 vaddr_t addr1 = h1 + o1; 672 vaddr_t addr1 = h1 + o1;
673 vaddr_t addr2 = h2 + o2; 673 vaddr_t addr2 = h2 + o2;
674 674
675 BUS_SPACE_ADDRESS_SANITY(addr1, uint32_t, "bus addr 1"); 675 BUS_SPACE_ADDRESS_SANITY(addr1, uint32_t, "bus addr 1");
676 BUS_SPACE_ADDRESS_SANITY(addr2, uint32_t, "bus addr 2"); 676 BUS_SPACE_ADDRESS_SANITY(addr2, uint32_t, "bus addr 2");
677 677
678 if (x86_bus_space_is_io(t)) { 678 if (x86_bus_space_is_io(t)) {
679 if (addr1 >= addr2) { 679 if (addr1 >= addr2) {
680 /* src after dest: copy forward */ 680 /* src after dest: copy forward */
681 for (; c != 0; c--, addr1 += 4, addr2 += 4) 681 for (; c != 0; c--, addr1 += 4, addr2 += 4)
682 outl(addr2, inl(addr1)); 682 outl(addr2, inl(addr1));
683 } else { 683 } else {
684 /* dest after src: copy backwards */ 684 /* dest after src: copy backwards */
685 for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1); 685 for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1);
686 c != 0; c--, addr1 -= 4, addr2 -= 4) 686 c != 0; c--, addr1 -= 4, addr2 -= 4)
687 outl(addr2, inl(addr1)); 687 outl(addr2, inl(addr1));
688 } 688 }
689 } else { 689 } else {
690 if (addr1 >= addr2) { 690 if (addr1 >= addr2) {
691 /* src after dest: copy forward */ 691 /* src after dest: copy forward */
692 for (; c != 0; c--, addr1 += 4, addr2 += 4) 692 for (; c != 0; c--, addr1 += 4, addr2 += 4)
693 *(volatile uint32_t *)(addr2) = 693 *(volatile uint32_t *)(addr2) =
694 *(volatile uint32_t *)(addr1); 694 *(volatile uint32_t *)(addr1);
695 } else { 695 } else {
696 /* dest after src: copy backwards */ 696 /* dest after src: copy backwards */
697 for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1); 697 for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1);
698 c != 0; c--, addr1 -= 4, addr2 -= 4) 698 c != 0; c--, addr1 -= 4, addr2 -= 4)
699 *(volatile uint32_t *)(addr2) = 699 *(volatile uint32_t *)(addr2) =
700 *(volatile uint32_t *)(addr1); 700 *(volatile uint32_t *)(addr1);
701 } 701 }
702 } 702 }
703} 703}
704 704
705void 705void
706bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, 706bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
707 bus_size_t offset, bus_size_t len, int flags) 707 bus_size_t offset, bus_size_t len, int flags)
708{ 708{
709 709
710 /* Function call is enough to prevent reordering of loads. */ 710 /* Function call is enough to prevent reordering of loads. */
711} 711}
712 712
713void * 713void *
714bus_space_vaddr(bus_space_tag_t tag, bus_space_handle_t bsh) 714bus_space_vaddr(bus_space_tag_t tag, bus_space_handle_t bsh)
715{ 715{
716 716
717 return x86_bus_space_is_mem(tag) ? (void *)bsh : NULL; 717 return x86_bus_space_is_mem(tag) ? (void *)bsh : NULL;
718} 718}