1 /* $NetBSD: au_himem_space.c,v 1.9 2009/11/07 07:27:45 cegger Exp $ */
4 * Copyright (c) 2006 Itronix Inc.
7 * Written by Garrett D'Amore for Itronix Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of Itronix Inc. may not be used to endorse
18 * or promote products derived from this software without specific
19 * prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
22 * 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 ITRONIX INC. BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * 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.
34 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
35 * All rights reserved.
37 * This code is derived from software contributed to The NetBSD Foundation
38 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
39 * Simulation Facility, NASA Ames Research Center.
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
50 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
51 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
52 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
54 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
55 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
56 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
57 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
58 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
59 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60 * POSSIBILITY OF SUCH DAMAGE.
63 #include <sys/cdefs.h>
64 __KERNEL_RCSID(0, "$NetBSD: au_himem_space.c,v 1.9 2009/11/07 07:27:45 cegger Exp $");
67 * This provides mappings for the upper I/O regions used on some
68 * Alchemy parts, e.g. PCI, PCMCIA, and LCD. The mappings do not use
69 * wired TLB entries, but instead rely on wiring entries in the kernel
73 #include <sys/param.h>
74 #include <sys/systm.h>
75 #include <sys/extent.h>
76 #include <sys/malloc.h>
77 #include <sys/endian.h>
80 #include <machine/bus.h>
81 #include <machine/locore.h>
82 #include <mips/alchemy/include/au_himem_space.h>
84 #define TRUNC_PAGE(x) ((x) & ~(PAGE_SIZE - 1))
85 #define ROUND_PAGE(x) TRUNC_PAGE((x) + (PAGE_SIZE - 1))
87 typedef struct au_himem_cookie
{
95 struct extent
*c_extent
;
98 int au_himem_map(void *, bus_addr_t
, bus_size_t
, int,
99 bus_space_handle_t
*, int);
100 void au_himem_unmap(void *, bus_space_handle_t
, bus_size_t
, int);
101 void *au_himem_vaddr(void *, bus_space_handle_t
);
102 int au_himem_subregion(void *, bus_space_handle_t
, bus_size_t
, bus_size_t
,
103 bus_space_handle_t
*);
104 paddr_t
au_himem_mmap(void *, bus_addr_t
, off_t
, int, int);
105 int au_himem_alloc(void *, bus_addr_t
, bus_addr_t
, bus_size_t
, bus_size_t
,
106 bus_size_t
, int, bus_addr_t
*, bus_space_handle_t
*);
107 void au_himem_free(void *, bus_space_handle_t
, bus_size_t
);
108 void au_himem_barrier(void *, bus_space_handle_t
, bus_size_t
, bus_size_t
, int);
109 uint8_t au_himem_r_1(void *, bus_space_handle_t
, bus_size_t
);
110 uint16_t au_himem_r_2(void *, bus_space_handle_t
, bus_size_t
);
111 uint32_t au_himem_r_4(void *, bus_space_handle_t
, bus_size_t
);
112 uint64_t au_himem_r_8(void *, bus_space_handle_t
, bus_size_t
);
113 void au_himem_rm_1(void *, bus_space_handle_t
, bus_size_t
, uint8_t *,
115 void au_himem_rm_2(void *, bus_space_handle_t
, bus_size_t
, uint16_t *,
117 void au_himem_rm_4(void *, bus_space_handle_t
, bus_size_t
, uint32_t *,
119 void au_himem_rm_8(void *, bus_space_handle_t
, bus_size_t
, uint64_t *,
121 void au_himem_rr_1(void *, bus_space_handle_t
, bus_size_t
, uint8_t *,
123 void au_himem_rr_2(void *, bus_space_handle_t
, bus_size_t
, uint16_t *,
125 void au_himem_rr_4(void *, bus_space_handle_t
, bus_size_t
, uint32_t *,
127 void au_himem_rr_8(void *, bus_space_handle_t
, bus_size_t
, uint64_t *,
129 void au_himem_w_1(void *, bus_space_handle_t
, bus_size_t
, uint8_t);
130 void au_himem_w_2(void *, bus_space_handle_t
, bus_size_t
, uint16_t);
131 void au_himem_w_4(void *, bus_space_handle_t
, bus_size_t
, uint32_t);
132 void au_himem_w_8(void *, bus_space_handle_t
, bus_size_t
, uint64_t);
133 void au_himem_wm_1(void *, bus_space_handle_t
, bus_size_t
, const uint8_t *,
135 void au_himem_wm_2(void *, bus_space_handle_t
, bus_size_t
, const uint16_t *,
137 void au_himem_wm_4(void *, bus_space_handle_t
, bus_size_t
, const uint32_t *,
139 void au_himem_wm_8(void *, bus_space_handle_t
, bus_size_t
, const uint64_t *,
141 void au_himem_wr_1(void *, bus_space_handle_t
, bus_size_t
, const uint8_t *,
143 void au_himem_wr_2(void *, bus_space_handle_t
, bus_size_t
, const uint16_t *,
145 void au_himem_wr_4(void *, bus_space_handle_t
, bus_size_t
, const uint32_t *,
147 void au_himem_wr_8(void *, bus_space_handle_t
, bus_size_t
, const uint64_t *,
149 void au_himem_sm_1(void *, bus_space_handle_t
, bus_size_t
, uint8_t,
151 void au_himem_sm_2(void *, bus_space_handle_t
, bus_size_t
, uint16_t,
153 void au_himem_sm_4(void *, bus_space_handle_t
, bus_size_t
, uint32_t,
155 void au_himem_sm_8(void *, bus_space_handle_t
, bus_size_t
, uint64_t,
157 void au_himem_sr_1(void *, bus_space_handle_t
, bus_size_t
, uint8_t,
159 void au_himem_sr_2(void *, bus_space_handle_t
, bus_size_t
, uint16_t,
161 void au_himem_sr_4(void *, bus_space_handle_t
, bus_size_t
, uint32_t,
163 void au_himem_sr_8(void *, bus_space_handle_t
, bus_size_t
, uint64_t,
165 void au_himem_c_1(void *, bus_space_handle_t
, bus_size_t
,
166 bus_space_handle_t
, bus_size_t
, bus_size_t
);
167 void au_himem_c_2(void *, bus_space_handle_t
, bus_size_t
,
168 bus_space_handle_t
, bus_size_t
, bus_size_t
);
169 void au_himem_c_4(void *, bus_space_handle_t
, bus_size_t
,
170 bus_space_handle_t
, bus_size_t
, bus_size_t
);
171 void au_himem_c_8(void *, bus_space_handle_t
, bus_size_t
,
172 bus_space_handle_t
, bus_size_t
, bus_size_t
);
173 uint16_t au_himem_rs_2(void *, bus_space_handle_t
, bus_size_t
);
174 uint32_t au_himem_rs_4(void *, bus_space_handle_t
, bus_size_t
);
175 uint64_t au_himem_rs_8(void *, bus_space_handle_t
, bus_size_t
);
176 void au_himem_ws_2(void *, bus_space_handle_t
, bus_size_t
, uint16_t);
177 void au_himem_ws_4(void *, bus_space_handle_t
, bus_size_t
, uint32_t);
178 void au_himem_ws_8(void *, bus_space_handle_t
, bus_size_t
, uint64_t);
179 void au_himem_rms_2(void *, bus_space_handle_t
, bus_size_t
, uint16_t *,
181 void au_himem_rms_4(void *, bus_space_handle_t
, bus_size_t
, uint32_t *,
183 void au_himem_rms_8(void *, bus_space_handle_t
, bus_size_t
, uint64_t *,
185 void au_himem_rrs_2(void *, bus_space_handle_t
, bus_size_t
, uint16_t *,
187 void au_himem_rrs_4(void *, bus_space_handle_t
, bus_size_t
, uint32_t *,
189 void au_himem_rrs_8(void *, bus_space_handle_t
, bus_size_t
, uint64_t *,
191 void au_himem_wms_2(void *, bus_space_handle_t
, bus_size_t
, const uint16_t *,
193 void au_himem_wms_4(void *, bus_space_handle_t
, bus_size_t
, const uint32_t *,
195 void au_himem_wms_8(void *, bus_space_handle_t
, bus_size_t
, const uint64_t *,
197 void au_himem_wrs_2(void *, bus_space_handle_t
, bus_size_t
, const uint16_t *,
199 void au_himem_wrs_4(void *, bus_space_handle_t
, bus_size_t
, const uint32_t *,
201 void au_himem_wrs_8(void *, bus_space_handle_t
, bus_size_t
, const uint64_t *,
205 au_himem_map(void *cookie
, bus_addr_t addr
, bus_size_t size
,
206 int flags
, bus_space_handle_t
*bshp
, int acct
)
208 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)cookie
;
215 /* make sure we can map this bus address */
216 if (addr
< c
->c_start
|| (addr
+ size
) > c
->c_end
) {
220 /* physical address, page aligned */
221 pa
= TRUNC_PAGE(c
->c_physoff
+ addr
);
224 * we are only going to work with whole pages. the
225 * calculation is the offset into the first page, plus the
226 * intended size, rounded up to a whole number of pages.
228 realsz
= ROUND_PAGE((addr
% PAGE_SIZE
) + size
);
230 va
= uvm_km_alloc(kernel_map
,
231 realsz
, PAGE_SIZE
, UVM_KMF_VAONLY
| UVM_KMF_NOWAIT
);
236 /* virtual address in handle (offset appropriately) */
237 *bshp
= va
+ (addr
% PAGE_SIZE
);
239 /* map the pages in the kernel pmap */
242 pmap_kenter_pa(va
, pa
, VM_PROT_READ
| VM_PROT_WRITE
, 0);
247 pmap_update(pmap_kernel());
250 /* record our allocated range of bus addresses */
251 if (acct
&& c
->c_extent
!= NULL
) {
252 err
= extent_alloc_region(c
->c_extent
, addr
, size
, EX_NOWAIT
);
254 au_himem_unmap(cookie
, *bshp
, size
, 0);
263 au_himem_unmap(void *cookie
, bus_space_handle_t bsh
, bus_size_t size
, int acct
)
265 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)cookie
;
271 va
= (vaddr_t
)TRUNC_PAGE(bsh
);
272 realsz
= (vsize_t
)ROUND_PAGE((bsh
% PAGE_SIZE
) + size
);
276 /* make sure that any pending writes are flushed */
280 * we have to get the bus address, so that we can free it in the
281 * extent manager. this is the unfortunate thing about using
282 * virtual memory instead of just a 1:1 mapping scheme.
284 if (pmap_extract(pmap_kernel(), va
, &pa
) == false)
285 panic("au_himem_unmap: virtual address invalid!");
287 /* now remove it from the pmap */
288 pmap_kremove(va
, realsz
);
289 pmap_update(pmap_kernel());
292 /* finally we can release both virtual and bus address ranges */
293 uvm_km_free(kernel_map
, va
, realsz
, UVM_KMF_VAONLY
);
297 addr
= ((pa
- c
->c_physoff
) + (bsh
% PAGE_SIZE
));
298 extent_free(c
->c_extent
, addr
, size
, EX_NOWAIT
);
303 au_himem_subregion(void *cookie
, bus_space_handle_t bsh
,
304 bus_size_t offset
, bus_size_t size
, bus_space_handle_t
*nbshp
)
307 *nbshp
= bsh
+ offset
;
312 au_himem_vaddr(void *cookie
, bus_space_handle_t bsh
)
315 return ((void *)bsh
);
319 au_himem_mmap(void *cookie
, bus_addr_t addr
, off_t off
, int prot
, int flags
)
321 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)cookie
;
323 /* I/O spaces should not be directly mmap'ed */
324 if (c
->c_flags
& AU_HIMEM_SPACE_IO
)
327 if (addr
< c
->c_start
|| (addr
+ off
) >= c
->c_end
)
330 return mips_btop(c
->c_physoff
+ addr
+ off
);
334 au_himem_alloc(void *cookie
, bus_addr_t start
, bus_addr_t end
,
335 bus_size_t size
, bus_size_t align
, bus_size_t boundary
, int flags
,
336 bus_addr_t
*addrp
, bus_space_handle_t
*bshp
)
338 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)cookie
;
342 err
= extent_alloc_subregion(c
->c_extent
, start
, end
, size
,
343 align
, boundary
, EX_FAST
| EX_NOWAIT
, &addr
);
347 err
= au_himem_map(cookie
, addr
, size
, flags
, bshp
, 0);
349 extent_free(c
->c_extent
, addr
, size
, EX_NOWAIT
);
355 au_himem_free(void *cookie
, bus_space_handle_t bsh
, bus_size_t size
)
358 /* unmap takes care of it all */
359 au_himem_unmap(cookie
, bsh
, size
, 1);
363 au_himem_barrier(void *cookie
, bus_space_handle_t bsh
, bus_size_t o
,
367 if (f
& BUS_SPACE_BARRIER_WRITE
)
372 au_himem_r_1(void *v
, bus_space_handle_t h
, bus_size_t o
)
375 return (*(volatile uint8_t *)(intptr_t)(h
+ o
));
379 au_himem_r_2(void *v
, bus_space_handle_t h
, bus_size_t o
)
382 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)v
;
385 val
= (*(volatile uint16_t *)(intptr_t)(h
+ o
));
386 return (c
->c_swswap
? bswap16(val
) : val
);
390 au_himem_r_4(void *v
, bus_space_handle_t h
, bus_size_t o
)
393 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)v
;
396 val
= (*(volatile uint32_t *)(intptr_t)(h
+ o
));
397 return (c
->c_swswap
? bswap32(val
) : val
);
401 au_himem_r_8(void *v
, bus_space_handle_t h
, bus_size_t o
)
404 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)v
;
407 val
= (*(volatile uint64_t *)(intptr_t)(h
+ o
));
408 return (c
->c_swswap
? bswap64(val
) : val
);
412 au_himem_w_1(void *v
, bus_space_handle_t h
, bus_size_t o
, uint8_t val
)
415 *(volatile uint8_t *)(intptr_t)(h
+ o
) = val
;
420 au_himem_w_2(void *v
, bus_space_handle_t h
, bus_size_t o
, uint16_t val
)
422 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)v
;
424 *(volatile uint16_t *)(intptr_t)(h
+ o
) = c
->c_swswap
? bswap16(val
) : val
;
429 au_himem_w_4(void *v
, bus_space_handle_t h
, bus_size_t o
, uint32_t val
)
431 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)v
;
433 *(volatile uint32_t *)(intptr_t)(h
+ o
) = c
->c_swswap
? bswap32(val
) : val
;
438 au_himem_w_8(void *v
, bus_space_handle_t h
, bus_size_t o
, uint64_t val
)
440 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)v
;
442 *(volatile uint64_t *)(intptr_t)(h
+ o
) = c
->c_swswap
? bswap64(val
) : val
;
447 au_himem_rs_2(void *v
, bus_space_handle_t h
, bus_size_t o
)
450 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)v
;
453 val
= (*(volatile uint16_t *)(intptr_t)(h
+ o
));
454 return (c
->c_hwswap
? bswap16(val
) : val
);
458 au_himem_rs_4(void *v
, bus_space_handle_t h
, bus_size_t o
)
461 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)v
;
464 val
= (*(volatile uint32_t *)(intptr_t)(h
+ o
));
465 return (c
->c_hwswap
? bswap32(val
) : val
);
469 au_himem_rs_8(void *v
, bus_space_handle_t h
, bus_size_t o
)
472 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)v
;
475 val
= (*(volatile uint64_t *)(intptr_t)(h
+ o
));
476 return (c
->c_hwswap
? bswap64(val
) : val
);
480 au_himem_ws_2(void *v
, bus_space_handle_t h
, bus_size_t o
, uint16_t val
)
482 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)v
;
484 *(volatile uint16_t *)(intptr_t)(h
+ o
) = c
->c_hwswap
? bswap16(val
) : val
;
489 au_himem_ws_4(void *v
, bus_space_handle_t h
, bus_size_t o
, uint32_t val
)
491 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)v
;
493 *(volatile uint32_t *)(intptr_t)(h
+ o
) = c
->c_hwswap
? bswap32(val
) : val
;
498 au_himem_ws_8(void *v
, bus_space_handle_t h
, bus_size_t o
, uint64_t val
)
500 au_himem_cookie_t
*c
= (au_himem_cookie_t
*)v
;
502 *(volatile uint64_t *)(intptr_t)(h
+ o
) = c
->c_hwswap
? bswap64(val
) : val
;
506 #define AU_HIMEM_RM(TYPE,BYTES) \
508 __CONCAT(au_himem_rm_,BYTES)(void *v, \
509 bus_space_handle_t h, bus_size_t o, TYPE *dst, bus_size_t cnt) \
513 *dst ++ = __CONCAT(au_himem_r_,BYTES)(v, h, o); \
515 AU_HIMEM_RM(uint8_t,1)
516 AU_HIMEM_RM(uint16_t,2)
517 AU_HIMEM_RM(uint32_t,4)
518 AU_HIMEM_RM(uint64_t,8)
520 #define AU_HIMEM_RMS(TYPE,BYTES) \
522 __CONCAT(au_himem_rms_,BYTES)(void *v, \
523 bus_space_handle_t h, bus_size_t o, TYPE *dst, bus_size_t cnt) \
526 while (cnt-- > 0) { \
527 *dst++ = __CONCAT(au_himem_rs_,BYTES)(v, h, o); \
530 AU_HIMEM_RMS(uint16_t,2)
531 AU_HIMEM_RMS(uint32_t,4)
532 AU_HIMEM_RMS(uint64_t,8)
534 #define AU_HIMEM_RR(TYPE,BYTES) \
536 __CONCAT(au_himem_rr_,BYTES)(void *v, \
537 bus_space_handle_t h, bus_size_t o, TYPE *dst, bus_size_t cnt) \
540 while (cnt-- > 0) { \
541 *dst++ = __CONCAT(au_himem_r_,BYTES)(v, h, o); \
545 AU_HIMEM_RR(uint8_t,1)
546 AU_HIMEM_RR(uint16_t,2)
547 AU_HIMEM_RR(uint32_t,4)
548 AU_HIMEM_RR(uint64_t,8)
550 #define AU_HIMEM_RRS(TYPE,BYTES) \
552 __CONCAT(au_himem_rrs_,BYTES)(void *v, \
553 bus_space_handle_t h, bus_size_t o, TYPE *dst, bus_size_t cnt) \
556 while (cnt-- > 0) { \
557 *dst++ = __CONCAT(au_himem_rs_,BYTES)(v, h, o); \
561 AU_HIMEM_RRS(uint16_t,2)
562 AU_HIMEM_RRS(uint32_t,4)
563 AU_HIMEM_RRS(uint64_t,8)
565 #define AU_HIMEM_WM(TYPE,BYTES) \
567 __CONCAT(au_himem_wm_,BYTES)(void *v, \
568 bus_space_handle_t h, bus_size_t o, const TYPE *src, \
572 while (cnt-- > 0) { \
573 __CONCAT(au_himem_w_,BYTES)(v, h, o, *src++); \
576 AU_HIMEM_WM(uint8_t,1)
577 AU_HIMEM_WM(uint16_t,2)
578 AU_HIMEM_WM(uint32_t,4)
579 AU_HIMEM_WM(uint64_t,8)
581 #define AU_HIMEM_WMS(TYPE,BYTES) \
583 __CONCAT(au_himem_wms_,BYTES)(void *v, \
584 bus_space_handle_t h, bus_size_t o, const TYPE *src, \
588 while (cnt-- > 0) { \
589 __CONCAT(au_himem_ws_,BYTES)(v, h, o, *src++); \
592 AU_HIMEM_WMS(uint16_t,2)
593 AU_HIMEM_WMS(uint32_t,4)
594 AU_HIMEM_WMS(uint64_t,8)
596 #define AU_HIMEM_WR(TYPE,BYTES) \
598 __CONCAT(au_himem_wr_,BYTES)(void *v, \
599 bus_space_handle_t h, bus_size_t o, const TYPE *src, \
603 while (cnt-- > 0) { \
604 __CONCAT(au_himem_w_,BYTES)(v, h, o, *src++); \
608 AU_HIMEM_WR(uint8_t,1)
609 AU_HIMEM_WR(uint16_t,2)
610 AU_HIMEM_WR(uint32_t,4)
611 AU_HIMEM_WR(uint64_t,8)
613 #define AU_HIMEM_WRS(TYPE,BYTES) \
615 __CONCAT(au_himem_wrs_,BYTES)(void *v, \
616 bus_space_handle_t h, bus_size_t o, const TYPE *src, \
620 while (cnt-- > 0) { \
621 __CONCAT(au_himem_ws_,BYTES)(v, h, o, *src++); \
625 AU_HIMEM_WRS(uint16_t,2)
626 AU_HIMEM_WRS(uint32_t,4)
627 AU_HIMEM_WRS(uint64_t,8)
629 #define AU_HIMEM_SM(TYPE,BYTES) \
631 __CONCAT(au_himem_sm_,BYTES)(void *v, \
632 bus_space_handle_t h, bus_size_t o, TYPE val, \
636 while (cnt-- > 0) { \
637 __CONCAT(au_himem_w_,BYTES)(v, h, o, val); \
640 AU_HIMEM_SM(uint8_t,1)
641 AU_HIMEM_SM(uint16_t,2)
642 AU_HIMEM_SM(uint32_t,4)
643 AU_HIMEM_SM(uint64_t,8)
645 #define AU_HIMEM_SR(TYPE,BYTES) \
647 __CONCAT(au_himem_sr_,BYTES)(void *v, \
648 bus_space_handle_t h, bus_size_t o, TYPE val, \
652 while (cnt-- > 0) { \
653 __CONCAT(au_himem_w_,BYTES)(v, h, o, val); \
657 AU_HIMEM_SR(uint8_t,1)
658 AU_HIMEM_SR(uint16_t,2)
659 AU_HIMEM_SR(uint32_t,4)
660 AU_HIMEM_SR(uint64_t,8)
663 #define AU_HIMEM_C(TYPE,BYTES) \
665 __CONCAT(au_himem_c_,BYTES)(void *v, \
666 bus_space_handle_t h1, bus_size_t o1, bus_space_handle_t h2, \
667 bus_size_t o2, bus_size_t cnt) \
669 volatile TYPE *src, *dst; \
670 src = (volatile TYPE *)(intptr_t)(h1 + o1); \
671 dst = (volatile TYPE *)(intptr_t)(h2 + o2); \
683 AU_HIMEM_C(uint8_t,1)
684 AU_HIMEM_C(uint16_t,2)
685 AU_HIMEM_C(uint32_t,4)
686 AU_HIMEM_C(uint64_t,8)
690 au_himem_space_init(bus_space_tag_t bst
, const char *name
,
691 paddr_t physoff
, bus_addr_t start
, bus_addr_t end
, int flags
)
693 au_himem_cookie_t
*c
;
695 c
= malloc(sizeof (struct au_himem_cookie
), M_DEVBUF
,
701 c
->c_physoff
= physoff
;
703 /* allocate extent manager */
704 c
->c_extent
= extent_create(name
, start
, end
, M_DEVBUF
,
706 if (c
->c_extent
== NULL
)
707 panic("au_himem_space_init: %s: cannot create extent", name
);
709 #if _BYTE_ORDER == _BIG_ENDIAN
710 if (flags
& AU_HIMEM_SPACE_LITTLE_ENDIAN
) {
711 if (flags
& AU_HIMEM_SPACE_SWAP_HW
)
717 #elif _BYTE_ORDER == _LITTLE_ENDIAN
718 if (flags
& AU_HIMEM_SPACE_BIG_ENDIAN
) {
719 if (flags
& AU_HIMEM_SPACE_SWAP_HW
)
727 bst
->bs_map
= au_himem_map
;
728 bst
->bs_unmap
= au_himem_unmap
;
729 bst
->bs_subregion
= au_himem_subregion
;
730 bst
->bs_translate
= NULL
; /* we don't use these */
731 bst
->bs_get_window
= NULL
; /* we don't use these */
732 bst
->bs_alloc
= au_himem_alloc
;
733 bst
->bs_free
= au_himem_free
;
734 bst
->bs_vaddr
= au_himem_vaddr
;
735 bst
->bs_mmap
= au_himem_mmap
;
736 bst
->bs_barrier
= au_himem_barrier
;
737 bst
->bs_r_1
= au_himem_r_1
;
738 bst
->bs_w_1
= au_himem_w_1
;
739 bst
->bs_r_2
= au_himem_r_2
;
740 bst
->bs_r_4
= au_himem_r_4
;
741 bst
->bs_r_8
= au_himem_r_8
;
742 bst
->bs_w_2
= au_himem_w_2
;
743 bst
->bs_w_4
= au_himem_w_4
;
744 bst
->bs_w_8
= au_himem_w_8
;
745 bst
->bs_rm_1
= au_himem_rm_1
;
746 bst
->bs_rm_2
= au_himem_rm_2
;
747 bst
->bs_rm_4
= au_himem_rm_4
;
748 bst
->bs_rm_8
= au_himem_rm_8
;
749 bst
->bs_rr_1
= au_himem_rr_1
;
750 bst
->bs_rr_2
= au_himem_rr_2
;
751 bst
->bs_rr_4
= au_himem_rr_4
;
752 bst
->bs_rr_8
= au_himem_rr_8
;
753 bst
->bs_wm_1
= au_himem_wm_1
;
754 bst
->bs_wm_2
= au_himem_wm_2
;
755 bst
->bs_wm_4
= au_himem_wm_4
;
756 bst
->bs_wm_8
= au_himem_wm_8
;
757 bst
->bs_wr_1
= au_himem_wr_1
;
758 bst
->bs_wr_2
= au_himem_wr_2
;
759 bst
->bs_wr_4
= au_himem_wr_4
;
760 bst
->bs_wr_8
= au_himem_wr_8
;
761 bst
->bs_sm_1
= au_himem_sm_1
;
762 bst
->bs_sm_2
= au_himem_sm_2
;
763 bst
->bs_sm_4
= au_himem_sm_4
;
764 bst
->bs_sm_8
= au_himem_sm_8
;
765 bst
->bs_sr_1
= au_himem_sr_1
;
766 bst
->bs_sr_2
= au_himem_sr_2
;
767 bst
->bs_sr_4
= au_himem_sr_4
;
768 bst
->bs_sr_8
= au_himem_sr_8
;
769 bst
->bs_c_1
= au_himem_c_1
;
770 bst
->bs_c_2
= au_himem_c_2
;
771 bst
->bs_c_4
= au_himem_c_4
;
772 bst
->bs_c_8
= au_himem_c_8
;
774 bst
->bs_rs_1
= au_himem_r_1
;
775 bst
->bs_rs_2
= au_himem_rs_2
;
776 bst
->bs_rs_4
= au_himem_rs_4
;
777 bst
->bs_rs_8
= au_himem_rs_8
;
778 bst
->bs_rms_1
= au_himem_rm_1
;
779 bst
->bs_rms_2
= au_himem_rms_2
;
780 bst
->bs_rms_4
= au_himem_rms_4
;
781 bst
->bs_rms_8
= au_himem_rms_8
;
782 bst
->bs_rrs_1
= au_himem_rr_1
;
783 bst
->bs_rrs_2
= au_himem_rrs_2
;
784 bst
->bs_rrs_4
= au_himem_rrs_4
;
785 bst
->bs_rrs_8
= au_himem_rrs_8
;
786 bst
->bs_ws_1
= au_himem_w_1
;
787 bst
->bs_ws_2
= au_himem_ws_2
;
788 bst
->bs_ws_4
= au_himem_ws_4
;
789 bst
->bs_ws_8
= au_himem_ws_8
;
790 bst
->bs_wms_1
= au_himem_wm_1
;
791 bst
->bs_wms_2
= au_himem_wms_2
;
792 bst
->bs_wms_4
= au_himem_wms_4
;
793 bst
->bs_wms_8
= au_himem_wms_8
;
794 bst
->bs_wrs_1
= au_himem_wr_1
;
795 bst
->bs_wrs_2
= au_himem_wrs_2
;
796 bst
->bs_wrs_4
= au_himem_wrs_4
;
797 bst
->bs_wrs_8
= au_himem_wrs_8
;