Home | History | Annotate | Line # | Download | only in atari
      1 /*	$NetBSD: be_bus.c,v 1.19 2026/04/26 12:49:36 thorpej Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Leo Weppelman.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 __KERNEL_RCSID(0, "$NetBSD: be_bus.c,v 1.19 2026/04/26 12:49:36 thorpej Exp $");
     34 
     35 #include <sys/types.h>
     36 #include <sys/param.h>
     37 #include <sys/systm.h>
     38 #include <sys/kmem.h>
     39 #include <machine/cpu.h>
     40 #include <sys/bus.h>
     41 
     42 /*
     43  * This file contains the common functions for using a big endian (linear)
     44  * bus on a big endian atari.
     45  */
     46 
     47 	/* Autoconf detection stuff */
     48 static int		beb_bus_space_peek_1(bus_space_tag_t,
     49 				bus_space_handle_t, bus_size_t);
     50 static int		beb_bus_space_peek_2(bus_space_tag_t,
     51 				bus_space_handle_t, bus_size_t);
     52 static int		beb_bus_space_peek_4(bus_space_tag_t,
     53 				bus_space_handle_t, bus_size_t);
     54 static int		beb_bus_space_peek_8(bus_space_tag_t,
     55 				bus_space_handle_t, bus_size_t);
     56 
     57 	/* read (single) */
     58 static uint8_t		beb_bus_space_read_1(bus_space_tag_t,
     59 				bus_space_handle_t, bus_size_t);
     60 static uint16_t		beb_bus_space_read_2(bus_space_tag_t,
     61 				bus_space_handle_t, bus_size_t);
     62 static uint32_t		beb_bus_space_read_4(bus_space_tag_t,
     63 				bus_space_handle_t, bus_size_t);
     64 static uint64_t		beb_bus_space_read_8(bus_space_tag_t,
     65 				bus_space_handle_t, bus_size_t);
     66 
     67 	/* write (single) */
     68 static void		beb_bus_space_write_1(bus_space_tag_t,
     69 				bus_space_handle_t, bus_size_t, uint8_t);
     70 static void		beb_bus_space_write_2(bus_space_tag_t,
     71 				bus_space_handle_t, bus_size_t, uint16_t);
     72 static void		beb_bus_space_write_4(bus_space_tag_t,
     73 				bus_space_handle_t, bus_size_t, uint32_t);
     74 static void		beb_bus_space_write_8(bus_space_tag_t,
     75 				bus_space_handle_t, bus_size_t, uint64_t);
     76 
     77 	/* read multiple */
     78 static void		beb_bus_space_read_multi_1(bus_space_tag_t,
     79 				bus_space_handle_t, bus_size_t, uint8_t *,
     80 				bus_size_t);
     81 static void		beb_bus_space_read_multi_2(bus_space_tag_t,
     82 				bus_space_handle_t, bus_size_t, uint16_t *,
     83 				bus_size_t);
     84 static void		beb_bus_space_read_multi_4(bus_space_tag_t,
     85 				bus_space_handle_t, bus_size_t, uint32_t *,
     86 				bus_size_t);
     87 static void		beb_bus_space_read_multi_8(bus_space_tag_t,
     88 				bus_space_handle_t, bus_size_t, uint64_t *,
     89 				bus_size_t);
     90 
     91 	/* write multiple */
     92 static void		beb_bus_space_write_multi_1(bus_space_tag_t,
     93 				bus_space_handle_t, bus_size_t,
     94 				const uint8_t *, bus_size_t);
     95 static void		beb_bus_space_write_multi_2(bus_space_tag_t,
     96 				bus_space_handle_t, bus_size_t,
     97 				const uint16_t *, bus_size_t);
     98 static void		beb_bus_space_write_multi_4(bus_space_tag_t,
     99 				bus_space_handle_t, bus_size_t,
    100 				const uint32_t *, bus_size_t);
    101 static void		beb_bus_space_write_multi_8(bus_space_tag_t,
    102 				bus_space_handle_t, bus_size_t,
    103 				const uint64_t *, bus_size_t);
    104 
    105 	/* read region */
    106 static void		beb_bus_space_read_region_1(bus_space_tag_t,
    107 				bus_space_handle_t, bus_size_t, uint8_t *,
    108 				bus_size_t);
    109 static void		beb_bus_space_read_region_2(bus_space_tag_t,
    110 				bus_space_handle_t, bus_size_t, uint16_t *,
    111 				bus_size_t);
    112 static void		beb_bus_space_read_region_4(bus_space_tag_t,
    113 				bus_space_handle_t, bus_size_t, uint32_t *,
    114 				bus_size_t);
    115 static void		beb_bus_space_read_region_8(bus_space_tag_t,
    116 				bus_space_handle_t, bus_size_t, uint64_t *,
    117 				bus_size_t);
    118 
    119 	/* read region */
    120 static void		beb_bus_space_write_region_1(bus_space_tag_t,
    121 				bus_space_handle_t, bus_size_t,
    122 				const uint8_t *, bus_size_t);
    123 static void		beb_bus_space_write_region_2(bus_space_tag_t,
    124 				bus_space_handle_t, bus_size_t,
    125 				const uint16_t *, bus_size_t);
    126 static void		beb_bus_space_write_region_4(bus_space_tag_t,
    127 				bus_space_handle_t, bus_size_t,
    128 				const uint32_t *, bus_size_t);
    129 static void		beb_bus_space_write_region_8(bus_space_tag_t,
    130 				bus_space_handle_t, bus_size_t,
    131 				const uint64_t *, bus_size_t);
    132 
    133 	/* set multi */
    134 static void		beb_bus_space_set_multi_1(bus_space_tag_t,
    135 				bus_space_handle_t, bus_size_t, uint8_t,
    136 				bus_size_t);
    137 static void		beb_bus_space_set_multi_2(bus_space_tag_t,
    138 				bus_space_handle_t, bus_size_t, uint16_t,
    139 				bus_size_t);
    140 static void		beb_bus_space_set_multi_4(bus_space_tag_t,
    141 				bus_space_handle_t, bus_size_t, uint32_t,
    142 				bus_size_t);
    143 static void		beb_bus_space_set_multi_8(bus_space_tag_t,
    144 				bus_space_handle_t, bus_size_t, uint64_t,
    145 				bus_size_t);
    146 
    147 	/* set region */
    148 static void		beb_bus_space_set_region_1(bus_space_tag_t,
    149 				bus_space_handle_t, bus_size_t, uint8_t,
    150 				bus_size_t);
    151 static void		beb_bus_space_set_region_2(bus_space_tag_t,
    152 				bus_space_handle_t, bus_size_t, uint16_t,
    153 				bus_size_t);
    154 static void		beb_bus_space_set_region_4(bus_space_tag_t,
    155 				bus_space_handle_t, bus_size_t, uint32_t,
    156 				bus_size_t);
    157 static void		beb_bus_space_set_region_8(bus_space_tag_t,
    158 				bus_space_handle_t, bus_size_t, uint64_t,
    159 				bus_size_t);
    160 
    161 /*
    162  * Don't force a function call overhead on these primitives...
    163  */
    164 #define __read_1(h, o)		*((volatile uint8_t  *)((h) + (o)))
    165 #define __read_2(h, o)		*((volatile uint16_t *)((h) + (o)))
    166 #define __read_4(h, o)		*((volatile uint32_t *)((h) + (o)))
    167 #define __read_8(h, o)		*((volatile uint64_t *)((h) + (o)))
    168 
    169 #define __write_1(h, o, v)	*((volatile uint8_t  *)((h) + (o))) = (v)
    170 #define __write_2(h, o, v)	*((volatile uint16_t *)((h) + (o))) = (v)
    171 #define __write_4(h, o, v)	*((volatile uint32_t *)((h) + (o))) = (v)
    172 #define __write_8(h, o, v)	*((volatile uint64_t *)((h) + (o))) = (v)
    173 
    174 bus_space_tag_t
    175 beb_alloc_bus_space_tag(bus_space_tag_t storage)
    176 {
    177 	bus_space_tag_t	beb_t;
    178 
    179 	/*
    180 	 * Allow the caller to specify storage space for the tag. This
    181 	 * is used during console config (when kmem_alloc() can't be used).
    182 	 */
    183 	if (storage != NULL)
    184 		beb_t = storage;
    185 	else {
    186 		beb_t = kmem_alloc(sizeof(*beb_t), KM_SLEEP);
    187 	}
    188 	memset(beb_t, 0, sizeof(*beb_t));
    189 
    190 	beb_t->abs_p_1   = beb_bus_space_peek_1;
    191 	beb_t->abs_p_2   = beb_bus_space_peek_2;
    192 	beb_t->abs_p_4   = beb_bus_space_peek_4;
    193 	beb_t->abs_p_8   = beb_bus_space_peek_8;
    194 	beb_t->abs_r_1   = beb_bus_space_read_1;
    195 	beb_t->abs_r_2   = beb_bus_space_read_2;
    196 	beb_t->abs_r_4   = beb_bus_space_read_4;
    197 	beb_t->abs_r_8   = beb_bus_space_read_8;
    198 	beb_t->abs_rs_1  = beb_bus_space_read_1;
    199 	beb_t->abs_rs_2  = beb_bus_space_read_2;
    200 	beb_t->abs_rs_4  = beb_bus_space_read_4;
    201 	beb_t->abs_rs_8  = beb_bus_space_read_8;
    202 	beb_t->abs_rm_1  = beb_bus_space_read_multi_1;
    203 	beb_t->abs_rm_2  = beb_bus_space_read_multi_2;
    204 	beb_t->abs_rm_4  = beb_bus_space_read_multi_4;
    205 	beb_t->abs_rm_8  = beb_bus_space_read_multi_8;
    206 	beb_t->abs_rms_1 = beb_bus_space_read_multi_1;
    207 	beb_t->abs_rms_2 = beb_bus_space_read_multi_2;
    208 	beb_t->abs_rms_4 = beb_bus_space_read_multi_4;
    209 	beb_t->abs_rms_8 = beb_bus_space_read_multi_8;
    210 	beb_t->abs_rr_1  = beb_bus_space_read_region_1;
    211 	beb_t->abs_rr_2  = beb_bus_space_read_region_2;
    212 	beb_t->abs_rr_4  = beb_bus_space_read_region_4;
    213 	beb_t->abs_rr_8  = beb_bus_space_read_region_8;
    214 	beb_t->abs_rrs_1 = beb_bus_space_read_region_1;
    215 	beb_t->abs_rrs_2 = beb_bus_space_read_region_2;
    216 	beb_t->abs_rrs_4 = beb_bus_space_read_region_4;
    217 	beb_t->abs_rrs_8 = beb_bus_space_read_region_8;
    218 	beb_t->abs_w_1   = beb_bus_space_write_1;
    219 	beb_t->abs_w_2   = beb_bus_space_write_2;
    220 	beb_t->abs_w_4   = beb_bus_space_write_4;
    221 	beb_t->abs_w_8   = beb_bus_space_write_8;
    222 	beb_t->abs_ws_1  = beb_bus_space_write_1;
    223 	beb_t->abs_ws_2  = beb_bus_space_write_2;
    224 	beb_t->abs_ws_4  = beb_bus_space_write_4;
    225 	beb_t->abs_ws_8  = beb_bus_space_write_8;
    226 	beb_t->abs_wm_1  = beb_bus_space_write_multi_1;
    227 	beb_t->abs_wm_2  = beb_bus_space_write_multi_2;
    228 	beb_t->abs_wm_4  = beb_bus_space_write_multi_4;
    229 	beb_t->abs_wm_8  = beb_bus_space_write_multi_8;
    230 	beb_t->abs_wms_1 = beb_bus_space_write_multi_1;
    231 	beb_t->abs_wms_2 = beb_bus_space_write_multi_2;
    232 	beb_t->abs_wms_4 = beb_bus_space_write_multi_4;
    233 	beb_t->abs_wms_8 = beb_bus_space_write_multi_8;
    234 	beb_t->abs_wr_1  = beb_bus_space_write_region_1;
    235 	beb_t->abs_wr_2  = beb_bus_space_write_region_2;
    236 	beb_t->abs_wr_4  = beb_bus_space_write_region_4;
    237 	beb_t->abs_wr_8  = beb_bus_space_write_region_8;
    238 	beb_t->abs_wrs_1 = beb_bus_space_write_region_1;
    239 	beb_t->abs_wrs_2 = beb_bus_space_write_region_2;
    240 	beb_t->abs_wrs_4 = beb_bus_space_write_region_4;
    241 	beb_t->abs_wrs_8 = beb_bus_space_write_region_8;
    242 	beb_t->abs_sm_1  = beb_bus_space_set_multi_1;
    243 	beb_t->abs_sm_2  = beb_bus_space_set_multi_2;
    244 	beb_t->abs_sm_4  = beb_bus_space_set_multi_4;
    245 	beb_t->abs_sm_8  = beb_bus_space_set_multi_8;
    246 	beb_t->abs_sr_1  = beb_bus_space_set_region_1;
    247 	beb_t->abs_sr_2  = beb_bus_space_set_region_2;
    248 	beb_t->abs_sr_4  = beb_bus_space_set_region_4;
    249 	beb_t->abs_sr_8  = beb_bus_space_set_region_8;
    250 
    251 	return beb_t;
    252 }
    253 
    254 
    255 /*
    256  * The various access functions
    257  */
    258 
    259 /*
    260  *	int bus_space_peek_N(bus_space_tag_t tag,
    261  *		bus_space_handle_t sh, bus_size_t offset);
    262  *
    263  * Check if the address is suitable for reading N-byte quantities.
    264  */
    265 static int
    266 beb_bus_space_peek_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
    267 {
    268 
    269 	return !badaddr_sz((void *)(h + o), 1);
    270 }
    271 
    272 static int
    273 beb_bus_space_peek_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
    274 {
    275 
    276 	return !badaddr_sz((void *)(h + o), 2);
    277 }
    278 
    279 static int
    280 beb_bus_space_peek_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
    281 {
    282 
    283 	return !badaddr_sz((void *)(h + o), 4);
    284 }
    285 
    286 static int
    287 beb_bus_space_peek_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
    288 {
    289 
    290 	return !badaddr_sz((void *)(h + o), 8);
    291 }
    292 
    293 /*
    294  *	uintX_t bus_space_read_N(bus_space_tag_t tag,
    295  *		bus_space_handle_t bsh, bus_size_t offset);
    296  *
    297  * Return an 1, 2, 4, or 8 byte value read from the bus_space described
    298  * by tag/handle at `offset'. The value is converted to host-endian.
    299  */
    300 static uint8_t
    301 beb_bus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
    302 {
    303 
    304 	return __read_1(h, o);
    305 }
    306 
    307 static uint16_t
    308 beb_bus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
    309 {
    310 
    311 	return __read_2(h, o);
    312 }
    313 
    314 static uint32_t
    315 beb_bus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
    316 {
    317 
    318 	return __read_4(h, o);
    319 }
    320 
    321 static uint64_t
    322 beb_bus_space_read_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
    323 {
    324 
    325 	return __read_8(h, o);
    326 }
    327 
    328 /*
    329  *	uintX_t bus_space_write_N(bus_space_tag_t tag,
    330  *		bus_space_handle_t bsh, bus_size_t offset, uintX_t val);
    331  *
    332  * Write an 1, 2, 4, or 8 byte value to the bus_space described by tag/handle
    333  * at `offset'. The value `val' is converted from host to bus endianness
    334  * before being written.
    335  */
    336 static void
    337 beb_bus_space_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
    338     uint8_t v)
    339 {
    340 
    341 	__write_1(h, o, v);
    342 }
    343 
    344 static void
    345 beb_bus_space_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
    346     uint16_t v)
    347 {
    348 
    349 	__write_2(h, o, v);
    350 }
    351 
    352 static void
    353 beb_bus_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
    354     uint32_t v)
    355 {
    356 
    357 	__write_4(h, o, v);
    358 }
    359 
    360 static void
    361 beb_bus_space_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
    362     uint64_t v)
    363 {
    364 
    365 	__write_8(h, o, v);
    366 }
    367 
    368 /*
    369  *	void bus_space_read_multi_N(bus_space_tag_t tag,
    370  *		bus_space_handle_t bsh, bus_size_t offset, uintX_t *address,
    371  *		bus_size_t count);
    372  *
    373  * Read 'count' 1, 2, 4, or 8 byte values from the bus_space described by
    374  * tag/handle at `offset' and store them in the address range starting at
    375  * 'address'. The values are converted to CPU endian order before being
    376  * being stored.
    377  */
    378 static void
    379 beb_bus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t h,
    380     bus_size_t o, uint8_t *a, bus_size_t c)
    381 {
    382 
    383 	for (; c; a++, c--)
    384 		*a = __read_1(h, o);
    385 }
    386 
    387 static void
    388 beb_bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h,
    389     bus_size_t o, uint16_t *a, bus_size_t c)
    390 {
    391 
    392 	for (; c; a++, c--)
    393 		*a = __read_2(h, o);
    394 }
    395 
    396 static void
    397 beb_bus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t h,
    398     bus_size_t o, uint32_t *a, bus_size_t c)
    399 {
    400 
    401 	for (; c; a++, c--)
    402 		*a = __read_4(h, o);
    403 }
    404 
    405 static void
    406 beb_bus_space_read_multi_8(bus_space_tag_t t, bus_space_handle_t h,
    407     bus_size_t o, uint64_t *a, bus_size_t c)
    408 {
    409 
    410 	for (; c; a++, c--)
    411 		*a = __read_8(h, o);
    412 }
    413 
    414 /*
    415  *	void bus_space_write_multi_N(bus_space_tag_t tag,
    416  *		bus_space_handle_t bsh, bus_size_t offset,
    417  *		const uintX_t *address, bus_size_t count);
    418  *
    419  * Write 'count' 1, 2, 4, or 8 byte values from the address range starting
    420  * at 'address' to the bus_space described by tag/handle at `offset'.
    421  * The values are converted to bus endian order before being written to
    422  * the bus.
    423  */
    424 static void
    425 beb_bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h,
    426     bus_size_t o, const uint8_t *a, bus_size_t c)
    427 {
    428 
    429 	for (; c; a++, c--)
    430 		__write_1(h, o, *a);
    431 }
    432 
    433 static void
    434 beb_bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h,
    435     bus_size_t o, const uint16_t *a, bus_size_t c)
    436 {
    437 
    438 	for (; c; a++, c--)
    439 		__write_2(h, o, *a);
    440 }
    441 
    442 static void
    443 beb_bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h,
    444     bus_size_t o, const uint32_t *a, bus_size_t c)
    445 {
    446 
    447 	for (; c; a++, c--)
    448 		__write_4(h, o, *a);
    449 }
    450 
    451 static void
    452 beb_bus_space_write_multi_8(bus_space_tag_t t, bus_space_handle_t h,
    453     bus_size_t o, const uint64_t *a, bus_size_t c)
    454 {
    455 
    456 	for (; c; a++, c--)
    457 		__write_8(h, o, *a);
    458 }
    459 
    460 /*
    461  *	void bus_space_read_region_N(bus_space_tag_t tag,
    462  *		bus_space_handle_t bsh, bus_size_t offset,
    463  *		uintN_t *addr, bus_size_t count);
    464  *
    465  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
    466  * described by tag/handle and starting at `offset' and copy into
    467  * buffer provided.
    468  */
    469 static void
    470 beb_bus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t h,
    471     bus_size_t o, uint8_t *a, bus_size_t c)
    472 {
    473 
    474 	for (; c; a++, o++, c--)
    475 		*a = __read_1(h, o);
    476 }
    477 
    478 static void
    479 beb_bus_space_read_region_2(bus_space_tag_t t, bus_space_handle_t h,
    480     bus_size_t o, uint16_t *a, bus_size_t c)
    481 {
    482 
    483 	for (; c; a++, o += 2, c--)
    484 		*a = __read_2(h, o);
    485 }
    486 
    487 static void
    488 beb_bus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t h,
    489     bus_size_t o, uint32_t *a, bus_size_t c)
    490 {
    491 
    492 	for (; c; a++, o += 4, c--)
    493 		*a = __read_4(h, o);
    494 }
    495 
    496 static void
    497 beb_bus_space_read_region_8(bus_space_tag_t t, bus_space_handle_t h,
    498     bus_size_t o, uint64_t *a, bus_size_t c)
    499 {
    500 
    501 	for (; c; a++, o += 8, c--)
    502 		*a = __read_8(h, o);
    503 }
    504 
    505 /*
    506  *	void bus_space_write_region_N(bus_space_tag_t tag,
    507  *		bus_space_handle_t bsh, bus_size_t offset,
    508  *		uintN_t *addr, bus_size_t count);
    509  *
    510  * Copy `count' 1, 2, 4, or 8 byte quantities from the buffer provided
    511  * into the bus space described by tag/handle and starting at `offset'.
    512  */
    513 static void
    514 beb_bus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t h,
    515     bus_size_t o, const uint8_t *a, bus_size_t c)
    516 {
    517 
    518 	for (; c; a++, o++, c--)
    519 		__write_1(h, o, *a);
    520 }
    521 
    522 static void
    523 beb_bus_space_write_region_2(bus_space_tag_t t, bus_space_handle_t h,
    524     bus_size_t o, const uint16_t *a, bus_size_t c)
    525 {
    526 
    527 	for (; c; a++, o += 2, c--)
    528 		__write_2(h, o, *a);
    529 }
    530 
    531 static void
    532 beb_bus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t h,
    533     bus_size_t o, const uint32_t *a, bus_size_t c)
    534 {
    535 
    536 	for (; c; a++, o += 4, c--)
    537 		__write_4(h, o, *a);
    538 }
    539 
    540 static void
    541 beb_bus_space_write_region_8(bus_space_tag_t t, bus_space_handle_t h,
    542     bus_size_t o, const uint64_t *a, bus_size_t c)
    543 {
    544 
    545 	for (; c; a++, o += 8, c--)
    546 		__write_8(h, o, *a);
    547 }
    548 
    549 /*
    550  *	void bus_space_set_multi_N(bus_space_tag_t tag,
    551  *		bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
    552  *		bus_size_t count);
    553  *
    554  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
    555  * by tag/handle/offset `count' times.
    556  */
    557 
    558 static void
    559 beb_bus_space_set_multi_1(bus_space_tag_t t, bus_space_handle_t h,
    560     bus_size_t o, uint8_t v, bus_size_t c)
    561 {
    562 
    563 	for (; c; c--)
    564 		__write_1(h, o, v);
    565 }
    566 
    567 static void
    568 beb_bus_space_set_multi_2(bus_space_tag_t t, bus_space_handle_t h,
    569     bus_size_t o, uint16_t v, bus_size_t c)
    570 {
    571 
    572 	for (; c; c--)
    573 		__write_2(h, o, v);
    574 }
    575 
    576 static void
    577 beb_bus_space_set_multi_4(bus_space_tag_t t, bus_space_handle_t h,
    578     bus_size_t o, uint32_t v, bus_size_t c)
    579 {
    580 
    581 	for (; c; c--)
    582 		__write_4(h, o, v);
    583 }
    584 
    585 static void
    586 beb_bus_space_set_multi_8(bus_space_tag_t t, bus_space_handle_t h,
    587     bus_size_t o, uint64_t v, bus_size_t c)
    588 {
    589 
    590 	for (; c; c--)
    591 		__write_8(h, o, v);
    592 }
    593 
    594 /*
    595  *	void bus_space_set_region_N(bus_space_tag_t tag,
    596  *		bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
    597  *		bus_size_t count);
    598  *
    599  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
    600  * by tag/handle starting at `offset'.
    601  */
    602 static void
    603 beb_bus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t h,
    604     bus_size_t o, uint8_t v, bus_size_t c)
    605 {
    606 
    607 	for (; c; o++, c--)
    608 		__write_1(h, o, v);
    609 }
    610 
    611 static void
    612 beb_bus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t h,
    613     bus_size_t o, uint16_t v, bus_size_t c)
    614 {
    615 
    616 	for (; c; o += 2, c--)
    617 		__write_2(h, o, v);
    618 }
    619 
    620 static void
    621 beb_bus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t h,
    622     bus_size_t o, uint32_t v, bus_size_t c)
    623 {
    624 
    625 	for (; c; o += 4, c--)
    626 		__write_4(h, o, v);
    627 }
    628 
    629 static void
    630 beb_bus_space_set_region_8(bus_space_tag_t t, bus_space_handle_t h,
    631     bus_size_t o, uint64_t v, bus_size_t c)
    632 {
    633 
    634 	for (; c; o += 8, c--)
    635 		__write_8(h, o, v);
    636 }
    637