Home | History | Annotate | Line # | Download | only in alchemy
au_wired_space.c revision 1.3
      1 /* $NetBSD: au_wired_space.c,v 1.3 2006/03/16 14:23:19 simonb Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2006 Itronix Inc.
      5  * All rights reserved.
      6  *
      7  * Written by Garrett D'Amore for Itronix Inc.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     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.
     20  *
     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.
     32  */
     33 /*
     34  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
     35  * All rights reserved.
     36  *
     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.
     40  *
     41  * Redistribution and use in source and binary forms, with or without
     42  * modification, are permitted provided that the following conditions
     43  * are met:
     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.
     49  * 3. All advertising materials mentioning features or use of this software
     50  *    must display the following acknowledgement:
     51  *	This product includes software developed by the NetBSD
     52  *	Foundation, Inc. and its contributors.
     53  * 4. Neither the name of The NetBSD Foundation nor the names of its
     54  *    contributors may be used to endorse or promote products derived
     55  *    from this software without specific prior written permission.
     56  *
     57  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     58  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     59  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     60  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     61  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     62  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     63  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     64  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     65  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     66  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     67  * POSSIBILITY OF SUCH DAMAGE.
     68  */
     69 
     70 #include <sys/cdefs.h>
     71 __KERNEL_RCSID(0, "$NetBSD: au_wired_space.c,v 1.3 2006/03/16 14:23:19 simonb Exp $");
     72 
     73 /*
     74  * This provides mappings for the upper I/O regions used on some
     75  * Alchemy parts, e.g. PCI and PCMCIA spaces.  These spaces can be
     76  * accessed using wired TLB entries.
     77  */
     78 
     79 #include <sys/param.h>
     80 #include <sys/systm.h>
     81 #include <sys/extent.h>
     82 #include <sys/malloc.h>
     83 #include <sys/endian.h>
     84 
     85 #include <machine/bus.h>
     86 #include <machine/locore.h>
     87 #include <machine/wired_map.h>
     88 #include <mips/alchemy/include/au_wired_space.h>
     89 
     90 #ifndef	AU_WIRED_EXTENT_SZ
     91 #define	AU_WIRED_EXTENT_SZ	EXTENT_FIXED_STORAGE_SIZE(10)
     92 #endif
     93 
     94 typedef struct au_wired_cookie {
     95 	const char	*c_name;
     96 	bus_addr_t	c_start;
     97 	bus_size_t	c_size;
     98 	paddr_t		c_pbase;
     99 	int		c_flags;
    100 	int		c_swswap;
    101 	boolean_t	c_hwswap;
    102 	struct extent	*c_extent;
    103 	long		c_exstore[AU_WIRED_EXTENT_SZ/sizeof (long)];
    104 } au_wired_cookie_t;
    105 
    106 int au_wired_map(void *, bus_addr_t, bus_size_t, int,
    107     bus_space_handle_t *, int);
    108 void au_wired_unmap(void *, bus_space_handle_t, bus_size_t, int);
    109 void *au_wired_vaddr(void *, bus_space_handle_t);
    110 int au_wired_subregion(void *, bus_space_handle_t, bus_size_t, bus_size_t,
    111     bus_space_handle_t *);
    112 paddr_t au_wired_mmap(void *, bus_addr_t, off_t, int, int);
    113 int au_wired_alloc(void *, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t,
    114     bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
    115 void au_wired_free(void *, bus_space_handle_t, bus_size_t);
    116 void au_wired_barrier(void *, bus_space_handle_t, bus_size_t, bus_size_t, int);
    117 uint8_t au_wired_r_1(void *, bus_space_handle_t, bus_size_t);
    118 uint16_t au_wired_r_2(void *, bus_space_handle_t, bus_size_t);
    119 uint32_t au_wired_r_4(void *, bus_space_handle_t, bus_size_t);
    120 uint64_t au_wired_r_8(void *, bus_space_handle_t, bus_size_t);
    121 void au_wired_rm_1(void *, bus_space_handle_t, bus_size_t, uint8_t *,
    122     bus_size_t);
    123 void au_wired_rm_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
    124     bus_size_t);
    125 void au_wired_rm_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
    126     bus_size_t);
    127 void au_wired_rm_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
    128     bus_size_t);
    129 void au_wired_rr_1(void *, bus_space_handle_t, bus_size_t, uint8_t *,
    130     bus_size_t);
    131 void au_wired_rr_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
    132     bus_size_t);
    133 void au_wired_rr_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
    134     bus_size_t);
    135 void au_wired_rr_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
    136     bus_size_t);
    137 void au_wired_w_1(void *, bus_space_handle_t, bus_size_t, uint8_t);
    138 void au_wired_w_2(void *, bus_space_handle_t, bus_size_t, uint16_t);
    139 void au_wired_w_4(void *, bus_space_handle_t, bus_size_t, uint32_t);
    140 void au_wired_w_8(void *, bus_space_handle_t, bus_size_t, uint64_t);
    141 void au_wired_wm_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *,
    142     bus_size_t);
    143 void au_wired_wm_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
    144     bus_size_t);
    145 void au_wired_wm_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
    146     bus_size_t);
    147 void au_wired_wm_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
    148     bus_size_t);
    149 void au_wired_wr_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *,
    150     bus_size_t);
    151 void au_wired_wr_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
    152     bus_size_t);
    153 void au_wired_wr_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
    154     bus_size_t);
    155 void au_wired_wr_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
    156     bus_size_t);
    157 void au_wired_sm_1(void *, bus_space_handle_t, bus_size_t, uint8_t,
    158     bus_size_t);
    159 void au_wired_sm_2(void *, bus_space_handle_t, bus_size_t, uint16_t,
    160     bus_size_t);
    161 void au_wired_sm_4(void *, bus_space_handle_t, bus_size_t, uint32_t,
    162     bus_size_t);
    163 void au_wired_sm_8(void *, bus_space_handle_t, bus_size_t, uint64_t,
    164     bus_size_t);
    165 void au_wired_sr_1(void *, bus_space_handle_t, bus_size_t, uint8_t,
    166     bus_size_t);
    167 void au_wired_sr_2(void *, bus_space_handle_t, bus_size_t, uint16_t,
    168     bus_size_t);
    169 void au_wired_sr_4(void *, bus_space_handle_t, bus_size_t, uint32_t,
    170     bus_size_t);
    171 void au_wired_sr_8(void *, bus_space_handle_t, bus_size_t, uint64_t,
    172     bus_size_t);
    173 void au_wired_c_1(void *, bus_space_handle_t, bus_size_t,
    174     bus_space_handle_t, bus_size_t, bus_size_t);
    175 void au_wired_c_2(void *, bus_space_handle_t, bus_size_t,
    176     bus_space_handle_t, bus_size_t, bus_size_t);
    177 void au_wired_c_4(void *, bus_space_handle_t, bus_size_t,
    178     bus_space_handle_t, bus_size_t, bus_size_t);
    179 void au_wired_c_8(void *, bus_space_handle_t, bus_size_t,
    180     bus_space_handle_t, bus_size_t, bus_size_t);
    181 uint16_t au_wired_rs_2(void *, bus_space_handle_t, bus_size_t);
    182 uint32_t au_wired_rs_4(void *, bus_space_handle_t, bus_size_t);
    183 uint64_t au_wired_rs_8(void *, bus_space_handle_t, bus_size_t);
    184 void au_wired_ws_2(void *, bus_space_handle_t, bus_size_t, uint16_t);
    185 void au_wired_ws_4(void *, bus_space_handle_t, bus_size_t, uint32_t);
    186 void au_wired_ws_8(void *, bus_space_handle_t, bus_size_t, uint64_t);
    187 void au_wired_rms_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
    188     bus_size_t);
    189 void au_wired_rms_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
    190     bus_size_t);
    191 void au_wired_rms_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
    192     bus_size_t);
    193 void au_wired_rrs_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
    194     bus_size_t);
    195 void au_wired_rrs_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
    196     bus_size_t);
    197 void au_wired_rrs_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
    198     bus_size_t);
    199 void au_wired_wms_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
    200     bus_size_t);
    201 void au_wired_wms_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
    202     bus_size_t);
    203 void au_wired_wms_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
    204     bus_size_t);
    205 void au_wired_wrs_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
    206     bus_size_t);
    207 void au_wired_wrs_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
    208     bus_size_t);
    209 void au_wired_wrs_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
    210     bus_size_t);
    211 
    212 int
    213 au_wired_map(void *cookie, bus_addr_t addr, bus_size_t size,
    214     int flags, bus_space_handle_t *bshp, int acct)
    215 {
    216 	int			err;
    217 	au_wired_cookie_t	*c = (au_wired_cookie_t *)cookie;
    218 	paddr_t			pa;
    219 
    220 	/* make sure we can map this bus address */
    221 	if (addr < c->c_start ||
    222 	    addr + size > c->c_start + c->c_size)
    223 		return EINVAL;
    224 
    225 	pa = c->c_pbase + (addr - c->c_start);
    226 
    227 	if (!mips3_wired_enter_region(addr, pa, size))
    228 		return ENOMEM;
    229 
    230 	/*
    231 	 * bus addresses are taken from virtual address space.
    232 	 */
    233 	if (acct && c->c_extent != NULL) {
    234 		err = extent_alloc_region(c->c_extent, addr, size, EX_NOWAIT);
    235 		if (err)
    236 			return err;
    237 	}
    238 
    239 	*bshp = addr;
    240 
    241 	return 0;
    242 }
    243 
    244 void
    245 au_wired_unmap(void *cookie, bus_space_handle_t bsh, bus_size_t size, int acct)
    246 {
    247 	au_wired_cookie_t	*c = (au_wired_cookie_t *)cookie;
    248 
    249 	if (acct != 0 && c->c_extent != NULL) {
    250 		extent_free(c->c_extent, (vaddr_t)bsh, size, EX_NOWAIT);
    251 	}
    252 }
    253 
    254 int
    255 au_wired_subregion(void *cookie, bus_space_handle_t bsh,
    256     bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
    257 {
    258 
    259 	*nbshp = bsh + offset;
    260 	return 0;
    261 }
    262 
    263 void *
    264 au_wired_vaddr(void *cookie, bus_space_handle_t bsh)
    265 {
    266 
    267 	return ((void *)bsh);
    268 }
    269 
    270 paddr_t
    271 au_wired_mmap(void *cookie, bus_addr_t addr, off_t off, int prot, int flags)
    272 {
    273 	au_wired_cookie_t	*c = (au_wired_cookie_t *)cookie;
    274 
    275 	/* I/O spaces should not be directly mmap'ed */
    276 	if (c->c_flags & AU_WIRED_SPACE_IO)
    277 		return -1;
    278 
    279 	if (addr < c->c_start || (addr + off) >= (c->c_start + c->c_size))
    280 		return -1;
    281 
    282 	return mips_btop(c->c_pbase + (addr - c->c_start) + off);
    283 }
    284 
    285 int
    286 au_wired_alloc(void *cookie, bus_addr_t start, bus_addr_t end,
    287     bus_size_t size, bus_size_t align, bus_size_t boundary, int flags,
    288     bus_addr_t *addrp, bus_space_handle_t *bshp)
    289 {
    290 	au_wired_cookie_t	*c = (au_wired_cookie_t *)cookie;
    291 	vaddr_t addr;
    292 	int err;
    293 	paddr_t pa;
    294 
    295 	if (c->c_extent == NULL)
    296 		panic("au_wired_alloc: extent map %s not avail", c->c_name);
    297 
    298 	if (start < c->c_start || ((start + size) > (c->c_start + c->c_size)))
    299 		return EINVAL;
    300 
    301 	err = extent_alloc_subregion(c->c_extent, start, end, size,
    302 	    align, boundary, EX_FAST | EX_NOWAIT, &addr);
    303 	if (err)
    304 		return err;
    305 
    306 	pa = c->c_pbase + (addr - c->c_start);
    307 
    308 	if (!mips3_wired_enter_region(addr, pa, size))
    309 		return ENOMEM;
    310 
    311 	*bshp = addr;
    312 	*addrp = addr;
    313 	return 0;
    314 }
    315 
    316 void
    317 au_wired_free(void *cookie, bus_space_handle_t bsh, bus_size_t size)
    318 {
    319 
    320 	/* unmap takes care of it all */
    321 	au_wired_unmap(cookie, bsh, size, 1);
    322 }
    323 
    324 inline void
    325 au_wired_barrier(void *cookie, bus_space_handle_t bsh, bus_size_t o,
    326     bus_size_t l, int f)
    327 {
    328 
    329 	if (f & BUS_SPACE_BARRIER_WRITE)
    330 		wbflush();
    331 }
    332 
    333 inline uint8_t
    334 au_wired_r_1(void *v, bus_space_handle_t h, bus_size_t o)
    335 {
    336 
    337 	return (*(volatile uint8_t *)(h + o));
    338 }
    339 
    340 inline uint16_t
    341 au_wired_r_2(void *v, bus_space_handle_t h, bus_size_t o)
    342 {
    343 	uint16_t		val = (*(volatile uint16_t *)(h + o));
    344 	au_wired_cookie_t	*c = (au_wired_cookie_t *)v;
    345 
    346 	return (c->c_swswap ? bswap16(val) : val);
    347 }
    348 
    349 inline uint32_t
    350 au_wired_r_4(void *v, bus_space_handle_t h, bus_size_t o)
    351 {
    352 	uint32_t		val = (*(volatile uint32_t *)(h + o));
    353 	au_wired_cookie_t	*c = (au_wired_cookie_t *)v;
    354 
    355 	return (c->c_swswap ? bswap32(val) : val);
    356 }
    357 
    358 inline uint64_t
    359 au_wired_r_8(void *v, bus_space_handle_t h, bus_size_t o)
    360 {
    361 	uint64_t		val = (*(volatile uint64_t *)(h + o));
    362 	au_wired_cookie_t	*c = (au_wired_cookie_t *)v;
    363 
    364 	return (c->c_swswap ? bswap64(val) : val);
    365 }
    366 
    367 inline void
    368 au_wired_w_1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t val)
    369 {
    370 
    371 	*(volatile uint8_t *)(h + o) = val;
    372 }
    373 
    374 inline void
    375 au_wired_w_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t val)
    376 {
    377 	au_wired_cookie_t	*c = (au_wired_cookie_t *)v;
    378 
    379 	*(volatile uint16_t *)(h + o) = c->c_swswap ? bswap16(val) : val;
    380 }
    381 
    382 inline void
    383 au_wired_w_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t val)
    384 {
    385 	au_wired_cookie_t	*c = (au_wired_cookie_t *)v;
    386 
    387 	*(volatile uint32_t *)(h + o) = c->c_swswap ? bswap32(val) : val;
    388 }
    389 
    390 inline void
    391 au_wired_w_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t val)
    392 {
    393 	au_wired_cookie_t	*c = (au_wired_cookie_t *)v;
    394 
    395 	*(volatile uint64_t *)(h + o) = c->c_swswap ? bswap64(val) : val;
    396 }
    397 
    398 inline uint16_t
    399 au_wired_rs_2(void *v, bus_space_handle_t h, bus_size_t o)
    400 {
    401 	uint16_t		val = (*(volatile uint16_t *)(h + o));
    402 	au_wired_cookie_t	*c = (au_wired_cookie_t *)v;
    403 
    404 	return (c->c_hwswap ? bswap16(val) : val);
    405 }
    406 
    407 inline uint32_t
    408 au_wired_rs_4(void *v, bus_space_handle_t h, bus_size_t o)
    409 {
    410 	uint32_t		val = (*(volatile uint32_t *)(h + o));
    411 	au_wired_cookie_t	*c = (au_wired_cookie_t *)v;
    412 
    413 	return (c->c_hwswap ? bswap32(val) : val);
    414 }
    415 
    416 inline uint64_t
    417 au_wired_rs_8(void *v, bus_space_handle_t h, bus_size_t o)
    418 {
    419 	uint64_t		val = (*(volatile uint64_t *)(h + o));
    420 	au_wired_cookie_t	*c = (au_wired_cookie_t *)v;
    421 
    422 	return (c->c_hwswap ? bswap64(val) : val);
    423 }
    424 
    425 inline void
    426 au_wired_ws_2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t val)
    427 {
    428 	au_wired_cookie_t	*c = (au_wired_cookie_t *)v;
    429 
    430 	*(volatile uint16_t *)(h + o) = c->c_hwswap ? bswap16(val) : val;
    431 }
    432 
    433 inline void
    434 au_wired_ws_4(void *v, bus_space_handle_t h, bus_size_t o, uint32_t val)
    435 {
    436 	au_wired_cookie_t	*c = (au_wired_cookie_t *)v;
    437 
    438 	*(volatile uint32_t *)(h + o) = c->c_hwswap ? bswap32(val) : val;
    439 }
    440 
    441 inline void
    442 au_wired_ws_8(void *v, bus_space_handle_t h, bus_size_t o, uint64_t val)
    443 {
    444 	au_wired_cookie_t	*c = (au_wired_cookie_t *)v;
    445 
    446 	*(volatile uint64_t *)(h + o) = c->c_hwswap ? bswap64(val) : val;
    447 }
    448 
    449 #define	AU_WIRED_RM(TYPE,BYTES)						\
    450 void									\
    451 __CONCAT(au_wired_rm_,BYTES)(void *v,					\
    452     bus_space_handle_t h, bus_size_t o, TYPE *dst, bus_size_t cnt)	\
    453 {									\
    454 									\
    455 	while (cnt-- > 0)						\
    456 		*dst ++ = __CONCAT(au_wired_r_,BYTES)(v, h, o);		\
    457 }
    458 AU_WIRED_RM(uint8_t,1)
    459 AU_WIRED_RM(uint16_t,2)
    460 AU_WIRED_RM(uint32_t,4)
    461 AU_WIRED_RM(uint64_t,8)
    462 
    463 #define	AU_WIRED_RMS(TYPE,BYTES)					\
    464 void									\
    465 __CONCAT(au_wired_rms_,BYTES)(void *v,					\
    466     bus_space_handle_t h, bus_size_t o, TYPE *dst, bus_size_t cnt)	\
    467 {									\
    468 									\
    469 	while (cnt-- > 0) {						\
    470 		wbflush();						\
    471 		*dst++ = __CONCAT(au_wired_rs_,BYTES)(v, h, o);		\
    472 	}								\
    473 }
    474 AU_WIRED_RMS(uint16_t,2)
    475 AU_WIRED_RMS(uint32_t,4)
    476 AU_WIRED_RMS(uint64_t,8)
    477 
    478 #define AU_WIRED_RR(TYPE,BYTES)						\
    479 void									\
    480 __CONCAT(au_wired_rr_,BYTES)(void *v,					\
    481     bus_space_handle_t h, bus_size_t o, TYPE *dst, bus_size_t cnt)	\
    482 {									\
    483 									\
    484 	while (cnt-- > 0) {						\
    485 		*dst++ = __CONCAT(au_wired_r_,BYTES)(v, h, o);		\
    486 		o += BYTES;						\
    487 	}								\
    488 }
    489 AU_WIRED_RR(uint8_t,1)
    490 AU_WIRED_RR(uint16_t,2)
    491 AU_WIRED_RR(uint32_t,4)
    492 AU_WIRED_RR(uint64_t,8)
    493 
    494 #define AU_WIRED_RRS(TYPE,BYTES)					\
    495 void									\
    496 __CONCAT(au_wired_rrs_,BYTES)(void *v,					\
    497     bus_space_handle_t h, bus_size_t o, TYPE *dst, bus_size_t cnt)	\
    498 {									\
    499 									\
    500 	while (cnt-- > 0) {						\
    501 		*dst++ = __CONCAT(au_wired_rs_,BYTES)(v, h, o);		\
    502 		o += BYTES;						\
    503 	}								\
    504 }
    505 AU_WIRED_RRS(uint16_t,2)
    506 AU_WIRED_RRS(uint32_t,4)
    507 AU_WIRED_RRS(uint64_t,8)
    508 
    509 #define	AU_WIRED_WM(TYPE,BYTES)						\
    510 void									\
    511 __CONCAT(au_wired_wm_,BYTES)(void *v,					\
    512     bus_space_handle_t h, bus_size_t o, const TYPE *src,		\
    513     bus_size_t cnt)							\
    514 {									\
    515 									\
    516 	while (cnt-- > 0) {						\
    517 		__CONCAT(au_wired_w_,BYTES)(v, h, o, *src++);		\
    518 		wbflush();						\
    519 	}								\
    520 }
    521 AU_WIRED_WM(uint8_t,1)
    522 AU_WIRED_WM(uint16_t,2)
    523 AU_WIRED_WM(uint32_t,4)
    524 AU_WIRED_WM(uint64_t,8)
    525 
    526 #define	AU_WIRED_WMS(TYPE,BYTES)					\
    527 void									\
    528 __CONCAT(au_wired_wms_,BYTES)(void *v,					\
    529     bus_space_handle_t h, bus_size_t o, const TYPE *src,		\
    530     bus_size_t cnt)							\
    531 {									\
    532 									\
    533 	while (cnt-- > 0) {						\
    534 		__CONCAT(au_wired_ws_,BYTES)(v, h, o, *src++);		\
    535 		wbflush();						\
    536 	}								\
    537 }
    538 AU_WIRED_WMS(uint16_t,2)
    539 AU_WIRED_WMS(uint32_t,4)
    540 AU_WIRED_WMS(uint64_t,8)
    541 
    542 #define	AU_WIRED_WR(TYPE,BYTES)						\
    543 void									\
    544 __CONCAT(au_wired_wr_,BYTES)(void *v,					\
    545     bus_space_handle_t h, bus_size_t o, const TYPE *src,		\
    546     bus_size_t cnt)							\
    547 {									\
    548 									\
    549 	while (cnt-- > 0) {						\
    550 		__CONCAT(au_wired_w_,BYTES)(v, h, o, *src++);		\
    551 		o += BYTES;						\
    552 	}								\
    553 }
    554 AU_WIRED_WR(uint8_t,1)
    555 AU_WIRED_WR(uint16_t,2)
    556 AU_WIRED_WR(uint32_t,4)
    557 AU_WIRED_WR(uint64_t,8)
    558 
    559 #define	AU_WIRED_WRS(TYPE,BYTES)					\
    560 void									\
    561 __CONCAT(au_wired_wrs_,BYTES)(void *v,					\
    562     bus_space_handle_t h, bus_size_t o, const TYPE *src,		\
    563     bus_size_t cnt)							\
    564 {									\
    565 									\
    566 	while (cnt-- > 0) {						\
    567 		__CONCAT(au_wired_ws_,BYTES)(v, h, o, *src++);		\
    568 		o += BYTES;						\
    569 	}								\
    570 }
    571 AU_WIRED_WRS(uint16_t,2)
    572 AU_WIRED_WRS(uint32_t,4)
    573 AU_WIRED_WRS(uint64_t,8)
    574 
    575 #define	AU_WIRED_SM(TYPE,BYTES)						\
    576 void									\
    577 __CONCAT(au_wired_sm_,BYTES)(void *v,					\
    578     bus_space_handle_t h, bus_size_t o, TYPE val,			\
    579     bus_size_t cnt)							\
    580 {									\
    581 									\
    582 	while (cnt-- > 0) {						\
    583 		__CONCAT(au_wired_w_,BYTES)(v, h, o, val);		\
    584 		wbflush();						\
    585 	}								\
    586 }
    587 AU_WIRED_SM(uint8_t,1)
    588 AU_WIRED_SM(uint16_t,2)
    589 AU_WIRED_SM(uint32_t,4)
    590 AU_WIRED_SM(uint64_t,8)
    591 
    592 #define	AU_WIRED_SR(TYPE,BYTES)						\
    593 void									\
    594 __CONCAT(au_wired_sr_,BYTES)(void *v,					\
    595     bus_space_handle_t h, bus_size_t o, TYPE val,			\
    596     bus_size_t cnt)							\
    597 {									\
    598 									\
    599 	while (cnt-- > 0) {						\
    600 		__CONCAT(au_wired_w_,BYTES)(v, h, o, val);		\
    601 		o += BYTES;						\
    602 	}								\
    603 }
    604 AU_WIRED_SR(uint8_t,1)
    605 AU_WIRED_SR(uint16_t,2)
    606 AU_WIRED_SR(uint32_t,4)
    607 AU_WIRED_SR(uint64_t,8)
    608 
    609 
    610 #define	AU_WIRED_C(TYPE,BYTES)						\
    611 void									\
    612 __CONCAT(au_wired_c_,BYTES)(void *v,					\
    613     bus_space_handle_t h1, bus_size_t o1, bus_space_handle_t h2,	\
    614     bus_space_handle_t o2, bus_size_t cnt)				\
    615 {									\
    616 	volatile TYPE *src, *dst;					\
    617 	src = (volatile TYPE *)(h1 + o1);				\
    618 	dst = (volatile TYPE *)(h2 + o2);				\
    619 									\
    620 	if (src >= dst) {						\
    621 		while (cnt-- > 0)					\
    622 			*dst++ = *src++;				\
    623 	} else {							\
    624 		src += cnt - 1;						\
    625 		dst += cnt - 1;						\
    626 		while (cnt-- > 0)					\
    627 			*dst-- = *src--;				\
    628 	}								\
    629 }
    630 AU_WIRED_C(uint8_t,1)
    631 AU_WIRED_C(uint16_t,2)
    632 AU_WIRED_C(uint32_t,4)
    633 AU_WIRED_C(uint64_t,8)
    634 
    635 
    636 void
    637 au_wired_space_init(bus_space_tag_t bst, const char *name,
    638     paddr_t paddr, bus_addr_t start, bus_size_t size, int flags)
    639 {
    640 	au_wired_cookie_t	*c;
    641 
    642 	c = malloc(sizeof (struct au_wired_cookie), M_DEVBUF,
    643 	    M_NOWAIT | M_ZERO);
    644 
    645 	c->c_pbase = paddr;
    646 	c->c_name = name;
    647 	c->c_start = start;
    648 	c->c_size = size;
    649 
    650 	/* allocate extent manager */
    651 	c->c_extent = extent_create(name, start, start + size, M_DEVBUF,
    652 	    (caddr_t)c->c_exstore, sizeof (c->c_exstore), EX_NOWAIT);
    653 	if (c->c_extent == NULL)
    654 		panic("au_wired_space_init: %s: cannot create extent", name);
    655 
    656 #if	_BYTE_ORDER == _BIG_ENDIAN
    657 	if (flags & AU_WIRED_SPACE_LITTLE_ENDIAN) {
    658 		if (flags & AU_WIRED_SPACE_SWAP_HW)
    659 			c->c_hwswap = 1;
    660 		else
    661 			c->c_swswap = 1;
    662 	}
    663 
    664 #elif	_BYTE_ORDER == _LITTLE_ENDIAN
    665 	if (flags & AU_WIRED_SPACE_BIG_ENDIAN) {
    666 		if (flags & AU_WIRED_SPACE_SWAP_HW)
    667 			c->c_hwswap = 1;
    668 		else
    669 			c->c_swswap = 1;
    670 	}
    671 #endif
    672 
    673 	bst->bs_cookie = c;
    674 	bst->bs_map = au_wired_map;
    675 	bst->bs_unmap = au_wired_unmap;
    676 	bst->bs_subregion = au_wired_subregion;
    677 	bst->bs_translate = NULL;	/* we don't use these */
    678 	bst->bs_get_window = NULL;	/* we don't use these */
    679 	bst->bs_alloc = au_wired_alloc;
    680 	bst->bs_free = au_wired_free;
    681 	bst->bs_vaddr = au_wired_vaddr;
    682 	bst->bs_mmap = au_wired_mmap;
    683 	bst->bs_barrier = au_wired_barrier;
    684 	bst->bs_r_1 = au_wired_r_1;
    685 	bst->bs_w_1 = au_wired_w_1;
    686 	bst->bs_r_2 = au_wired_r_2;
    687 	bst->bs_r_4 = au_wired_r_4;
    688 	bst->bs_r_8 = au_wired_r_8;
    689 	bst->bs_w_2 = au_wired_w_2;
    690 	bst->bs_w_4 = au_wired_w_4;
    691 	bst->bs_w_8 = au_wired_w_8;
    692 	bst->bs_rm_1 = au_wired_rm_1;
    693 	bst->bs_rm_2 = au_wired_rm_2;
    694 	bst->bs_rm_4 = au_wired_rm_4;
    695 	bst->bs_rm_8 = au_wired_rm_8;
    696 	bst->bs_rr_1 = au_wired_rr_1;
    697 	bst->bs_rr_2 = au_wired_rr_2;
    698 	bst->bs_rr_4 = au_wired_rr_4;
    699 	bst->bs_rr_8 = au_wired_rr_8;
    700 	bst->bs_wm_1 = au_wired_wm_1;
    701 	bst->bs_wm_2 = au_wired_wm_2;
    702 	bst->bs_wm_4 = au_wired_wm_4;
    703 	bst->bs_wm_8 = au_wired_wm_8;
    704 	bst->bs_wr_1 = au_wired_wr_1;
    705 	bst->bs_wr_2 = au_wired_wr_2;
    706 	bst->bs_wr_4 = au_wired_wr_4;
    707 	bst->bs_wr_8 = au_wired_wr_8;
    708 	bst->bs_sm_1 = au_wired_sm_1;
    709 	bst->bs_sm_2 = au_wired_sm_2;
    710 	bst->bs_sm_4 = au_wired_sm_4;
    711 	bst->bs_sm_8 = au_wired_sm_8;
    712 	bst->bs_sr_1 = au_wired_sr_1;
    713 	bst->bs_sr_2 = au_wired_sr_2;
    714 	bst->bs_sr_4 = au_wired_sr_4;
    715 	bst->bs_sr_8 = au_wired_sr_8;
    716 	bst->bs_c_1 = au_wired_c_1;
    717 	bst->bs_c_2 = au_wired_c_2;
    718 	bst->bs_c_4 = au_wired_c_4;
    719 	bst->bs_c_8 = au_wired_c_8;
    720 
    721 	bst->bs_rs_1 = au_wired_r_1;
    722 	bst->bs_rs_2 = au_wired_rs_2;
    723 	bst->bs_rs_4 = au_wired_rs_4;
    724 	bst->bs_rs_8 = au_wired_rs_8;
    725 	bst->bs_rms_1 = au_wired_rm_1;
    726 	bst->bs_rms_2 = au_wired_rms_2;
    727 	bst->bs_rms_4 = au_wired_rms_4;
    728 	bst->bs_rms_8 = au_wired_rms_8;
    729 	bst->bs_rrs_1 = au_wired_rr_1;
    730 	bst->bs_rrs_2 = au_wired_rrs_2;
    731 	bst->bs_rrs_4 = au_wired_rrs_4;
    732 	bst->bs_rrs_8 = au_wired_rrs_8;
    733 	bst->bs_ws_1 = au_wired_w_1;
    734 	bst->bs_ws_2 = au_wired_ws_2;
    735 	bst->bs_ws_4 = au_wired_ws_4;
    736 	bst->bs_ws_8 = au_wired_ws_8;
    737 	bst->bs_wms_1 = au_wired_wm_1;
    738 	bst->bs_wms_2 = au_wired_wms_2;
    739 	bst->bs_wms_4 = au_wired_wms_4;
    740 	bst->bs_wms_8 = au_wired_wms_8;
    741 	bst->bs_wrs_1 = au_wired_wr_1;
    742 	bst->bs_wrs_2 = au_wired_wrs_2;
    743 	bst->bs_wrs_4 = au_wired_wrs_4;
    744 	bst->bs_wrs_8 = au_wired_wrs_8;
    745 }
    746