Home | History | Annotate | Line # | Download | only in tc
tc_bus_mem.c revision 1.20
      1 /* $NetBSD: tc_bus_mem.c,v 1.20 2000/02/25 00:45:06 thorpej Exp $ */
      2 
      3 /*
      4  * Copyright (c) 1996 Carnegie-Mellon University.
      5  * All rights reserved.
      6  *
      7  * Author: Chris G. Demetriou
      8  *
      9  * Permission to use, copy, modify and distribute this software and
     10  * its documentation is hereby granted, provided that both the copyright
     11  * notice and this permission notice appear in all copies of the
     12  * software, derivative works or modified versions, and any portions
     13  * thereof, and that both notices appear in supporting documentation.
     14  *
     15  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     16  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
     17  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     18  *
     19  * Carnegie Mellon requests users of this software to return to
     20  *
     21  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     22  *  School of Computer Science
     23  *  Carnegie Mellon University
     24  *  Pittsburgh PA 15213-3890
     25  *
     26  * any improvements or extensions that they make and grant Carnegie the
     27  * rights to redistribute these changes.
     28  */
     29 
     30 /*
     31  * Common TurboChannel Chipset "bus memory" functions.
     32  */
     33 
     34 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
     35 
     36 __KERNEL_RCSID(0, "$NetBSD: tc_bus_mem.c,v 1.20 2000/02/25 00:45:06 thorpej Exp $");
     37 
     38 #include <sys/param.h>
     39 #include <sys/systm.h>
     40 #include <sys/malloc.h>
     41 #include <sys/syslog.h>
     42 #include <sys/device.h>
     43 #include <vm/vm.h>
     44 
     45 #include <machine/bus.h>
     46 #include <dev/tc/tcvar.h>
     47 
     48 #define	__C(A,B)	__CONCAT(A,B)
     49 
     50 /* mapping/unmapping */
     51 int		tc_mem_map __P((void *, bus_addr_t, bus_size_t, int,
     52 		    bus_space_handle_t *, int));
     53 void		tc_mem_unmap __P((void *, bus_space_handle_t, bus_size_t, int));
     54 int		tc_mem_subregion __P((void *, bus_space_handle_t, bus_size_t,
     55 		    bus_size_t, bus_space_handle_t *));
     56 
     57 int		tc_mem_translate __P((void *, bus_addr_t, bus_size_t,
     58 		    int, struct alpha_bus_space_translation *));
     59 
     60 /* allocation/deallocation */
     61 int		tc_mem_alloc __P((void *, bus_addr_t, bus_addr_t, bus_size_t,
     62 		    bus_size_t, bus_addr_t, int, bus_addr_t *,
     63 		    bus_space_handle_t *));
     64 void		tc_mem_free __P((void *, bus_space_handle_t, bus_size_t));
     65 
     66 /* barrier */
     67 inline void	tc_mem_barrier __P((void *, bus_space_handle_t,
     68 		    bus_size_t, bus_size_t, int));
     69 
     70 /* read (single) */
     71 inline u_int8_t	tc_mem_read_1 __P((void *, bus_space_handle_t, bus_size_t));
     72 inline u_int16_t tc_mem_read_2 __P((void *, bus_space_handle_t, bus_size_t));
     73 inline u_int32_t tc_mem_read_4 __P((void *, bus_space_handle_t, bus_size_t));
     74 inline u_int64_t tc_mem_read_8 __P((void *, bus_space_handle_t, bus_size_t));
     75 
     76 /* read multiple */
     77 void		tc_mem_read_multi_1 __P((void *, bus_space_handle_t,
     78 		    bus_size_t, u_int8_t *, bus_size_t));
     79 void		tc_mem_read_multi_2 __P((void *, bus_space_handle_t,
     80 		    bus_size_t, u_int16_t *, bus_size_t));
     81 void		tc_mem_read_multi_4 __P((void *, bus_space_handle_t,
     82 		    bus_size_t, u_int32_t *, bus_size_t));
     83 void		tc_mem_read_multi_8 __P((void *, bus_space_handle_t,
     84 		    bus_size_t, u_int64_t *, bus_size_t));
     85 
     86 /* read region */
     87 void		tc_mem_read_region_1 __P((void *, bus_space_handle_t,
     88 		    bus_size_t, u_int8_t *, bus_size_t));
     89 void		tc_mem_read_region_2 __P((void *, bus_space_handle_t,
     90 		    bus_size_t, u_int16_t *, bus_size_t));
     91 void		tc_mem_read_region_4 __P((void *, bus_space_handle_t,
     92 		    bus_size_t, u_int32_t *, bus_size_t));
     93 void		tc_mem_read_region_8 __P((void *, bus_space_handle_t,
     94 		    bus_size_t, u_int64_t *, bus_size_t));
     95 
     96 /* write (single) */
     97 inline void	tc_mem_write_1 __P((void *, bus_space_handle_t, bus_size_t,
     98 		    u_int8_t));
     99 inline void	tc_mem_write_2 __P((void *, bus_space_handle_t, bus_size_t,
    100 		    u_int16_t));
    101 inline void	tc_mem_write_4 __P((void *, bus_space_handle_t, bus_size_t,
    102 		    u_int32_t));
    103 inline void	tc_mem_write_8 __P((void *, bus_space_handle_t, bus_size_t,
    104 		    u_int64_t));
    105 
    106 /* write multiple */
    107 void		tc_mem_write_multi_1 __P((void *, bus_space_handle_t,
    108 		    bus_size_t, const u_int8_t *, bus_size_t));
    109 void		tc_mem_write_multi_2 __P((void *, bus_space_handle_t,
    110 		    bus_size_t, const u_int16_t *, bus_size_t));
    111 void		tc_mem_write_multi_4 __P((void *, bus_space_handle_t,
    112 		    bus_size_t, const u_int32_t *, bus_size_t));
    113 void		tc_mem_write_multi_8 __P((void *, bus_space_handle_t,
    114 		    bus_size_t, const u_int64_t *, bus_size_t));
    115 
    116 /* write region */
    117 void		tc_mem_write_region_1 __P((void *, bus_space_handle_t,
    118 		    bus_size_t, const u_int8_t *, bus_size_t));
    119 void		tc_mem_write_region_2 __P((void *, bus_space_handle_t,
    120 		    bus_size_t, const u_int16_t *, bus_size_t));
    121 void		tc_mem_write_region_4 __P((void *, bus_space_handle_t,
    122 		    bus_size_t, const u_int32_t *, bus_size_t));
    123 void		tc_mem_write_region_8 __P((void *, bus_space_handle_t,
    124 		    bus_size_t, const u_int64_t *, bus_size_t));
    125 
    126 /* set multiple */
    127 void		tc_mem_set_multi_1 __P((void *, bus_space_handle_t,
    128 		    bus_size_t, u_int8_t, bus_size_t));
    129 void		tc_mem_set_multi_2 __P((void *, bus_space_handle_t,
    130 		    bus_size_t, u_int16_t, bus_size_t));
    131 void		tc_mem_set_multi_4 __P((void *, bus_space_handle_t,
    132 		    bus_size_t, u_int32_t, bus_size_t));
    133 void		tc_mem_set_multi_8 __P((void *, bus_space_handle_t,
    134 		    bus_size_t, u_int64_t, bus_size_t));
    135 
    136 /* set region */
    137 void		tc_mem_set_region_1 __P((void *, bus_space_handle_t,
    138 		    bus_size_t, u_int8_t, bus_size_t));
    139 void		tc_mem_set_region_2 __P((void *, bus_space_handle_t,
    140 		    bus_size_t, u_int16_t, bus_size_t));
    141 void		tc_mem_set_region_4 __P((void *, bus_space_handle_t,
    142 		    bus_size_t, u_int32_t, bus_size_t));
    143 void		tc_mem_set_region_8 __P((void *, bus_space_handle_t,
    144 		    bus_size_t, u_int64_t, bus_size_t));
    145 
    146 /* copy */
    147 void		tc_mem_copy_region_1 __P((void *, bus_space_handle_t,
    148 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
    149 void		tc_mem_copy_region_2 __P((void *, bus_space_handle_t,
    150 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
    151 void		tc_mem_copy_region_4 __P((void *, bus_space_handle_t,
    152 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
    153 void		tc_mem_copy_region_8 __P((void *, bus_space_handle_t,
    154 		    bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t));
    155 
    156 static struct alpha_bus_space tc_mem_space = {
    157 	/* cookie */
    158 	NULL,
    159 
    160 	/* mapping/unmapping */
    161 	tc_mem_map,
    162 	tc_mem_unmap,
    163 	tc_mem_subregion,
    164 
    165 	tc_mem_translate,
    166 
    167 	/* allocation/deallocation */
    168 	tc_mem_alloc,
    169 	tc_mem_free,
    170 
    171 	/* barrier */
    172 	tc_mem_barrier,
    173 
    174 	/* read (single) */
    175 	tc_mem_read_1,
    176 	tc_mem_read_2,
    177 	tc_mem_read_4,
    178 	tc_mem_read_8,
    179 
    180 	/* read multiple */
    181 	tc_mem_read_multi_1,
    182 	tc_mem_read_multi_2,
    183 	tc_mem_read_multi_4,
    184 	tc_mem_read_multi_8,
    185 
    186 	/* read region */
    187 	tc_mem_read_region_1,
    188 	tc_mem_read_region_2,
    189 	tc_mem_read_region_4,
    190 	tc_mem_read_region_8,
    191 
    192 	/* write (single) */
    193 	tc_mem_write_1,
    194 	tc_mem_write_2,
    195 	tc_mem_write_4,
    196 	tc_mem_write_8,
    197 
    198 	/* write multiple */
    199 	tc_mem_write_multi_1,
    200 	tc_mem_write_multi_2,
    201 	tc_mem_write_multi_4,
    202 	tc_mem_write_multi_8,
    203 
    204 	/* write region */
    205 	tc_mem_write_region_1,
    206 	tc_mem_write_region_2,
    207 	tc_mem_write_region_4,
    208 	tc_mem_write_region_8,
    209 
    210 	/* set multiple */
    211 	tc_mem_set_multi_1,
    212 	tc_mem_set_multi_2,
    213 	tc_mem_set_multi_4,
    214 	tc_mem_set_multi_8,
    215 
    216 	/* set region */
    217 	tc_mem_set_region_1,
    218 	tc_mem_set_region_2,
    219 	tc_mem_set_region_4,
    220 	tc_mem_set_region_8,
    221 
    222 	/* copy */
    223 	tc_mem_copy_region_1,
    224 	tc_mem_copy_region_2,
    225 	tc_mem_copy_region_4,
    226 	tc_mem_copy_region_8,
    227 };
    228 
    229 bus_space_tag_t
    230 tc_bus_mem_init(memv)
    231 	void *memv;
    232 {
    233 	bus_space_tag_t h = &tc_mem_space;
    234 
    235 	h->abs_cookie = memv;
    236 	return (h);
    237 }
    238 
    239 /* ARGSUSED */
    240 int
    241 tc_mem_translate(v, memaddr, memlen, flags, abst)
    242 	void *v;
    243 	bus_addr_t memaddr;
    244 	bus_size_t memlen;
    245 	int flags;
    246 	struct alpha_bus_space_translation *abst;
    247 {
    248 
    249 	return (EOPNOTSUPP);
    250 }
    251 
    252 /* ARGSUSED */
    253 int
    254 tc_mem_map(v, memaddr, memsize, flags, memhp, acct)
    255 	void *v;
    256 	bus_addr_t memaddr;
    257 	bus_size_t memsize;
    258 	int flags;
    259 	bus_space_handle_t *memhp;
    260 	int acct;
    261 {
    262 	int cacheable = flags & BUS_SPACE_MAP_CACHEABLE;
    263 	int linear = flags & BUS_SPACE_MAP_LINEAR;
    264 
    265 	/* Requests for linear uncacheable space can't be satisfied. */
    266 	if (linear && !cacheable)
    267 		return (EOPNOTSUPP);
    268 
    269 	if (memaddr & 0x7)
    270 		panic("tc_mem_map needs 8 byte alignment");
    271 	if (cacheable)
    272 		*memhp = ALPHA_PHYS_TO_K0SEG(memaddr);
    273 	else
    274 		*memhp = ALPHA_PHYS_TO_K0SEG(TC_DENSE_TO_SPARSE(memaddr));
    275 	return (0);
    276 }
    277 
    278 /* ARGSUSED */
    279 void
    280 tc_mem_unmap(v, memh, memsize, acct)
    281 	void *v;
    282 	bus_space_handle_t memh;
    283 	bus_size_t memsize;
    284 	int acct;
    285 {
    286 
    287 	/* XXX XX XXX nothing to do. */
    288 }
    289 
    290 int
    291 tc_mem_subregion(v, memh, offset, size, nmemh)
    292 	void *v;
    293 	bus_space_handle_t memh, *nmemh;
    294 	bus_size_t offset, size;
    295 {
    296 
    297 	/* Disallow subregioning that would make the handle unaligned. */
    298 	if ((offset & 0x7) != 0)
    299 		return (1);
    300 
    301 	if ((memh & TC_SPACE_SPARSE) != 0)
    302 		*nmemh = memh + (offset << 1);
    303 	else
    304 		*nmemh = memh + offset;
    305 
    306 	return (0);
    307 }
    308 
    309 int
    310 tc_mem_alloc(v, rstart, rend, size, align, boundary, flags, addrp, bshp)
    311 	void *v;
    312 	bus_addr_t rstart, rend, *addrp;
    313 	bus_size_t size, align, boundary;
    314 	int flags;
    315 	bus_space_handle_t *bshp;
    316 {
    317 
    318 	/* XXX XXX XXX XXX XXX XXX */
    319 	panic("tc_mem_alloc unimplemented");
    320 }
    321 
    322 void
    323 tc_mem_free(v, bsh, size)
    324 	void *v;
    325 	bus_space_handle_t bsh;
    326 	bus_size_t size;
    327 {
    328 
    329 	/* XXX XXX XXX XXX XXX XXX */
    330 	panic("tc_mem_free unimplemented");
    331 }
    332 
    333 inline void
    334 tc_mem_barrier(v, h, o, l, f)
    335 	void *v;
    336 	bus_space_handle_t h;
    337 	bus_size_t o, l;
    338 	int f;
    339 {
    340 
    341 	if ((f & BUS_SPACE_BARRIER_READ) != 0)
    342 		alpha_mb();
    343 	else if ((f & BUS_SPACE_BARRIER_WRITE) != 0)
    344 		alpha_wmb();
    345 }
    346 
    347 inline u_int8_t
    348 tc_mem_read_1(v, memh, off)
    349 	void *v;
    350 	bus_space_handle_t memh;
    351 	bus_size_t off;
    352 {
    353 	volatile u_int8_t *p;
    354 
    355 	alpha_mb();		/* XXX XXX XXX */
    356 
    357 	if ((memh & TC_SPACE_SPARSE) != 0)
    358 		panic("tc_mem_read_1 not implemented for sparse space");
    359 
    360 	p = (u_int8_t *)(memh + off);
    361 	return (*p);
    362 }
    363 
    364 inline u_int16_t
    365 tc_mem_read_2(v, memh, off)
    366 	void *v;
    367 	bus_space_handle_t memh;
    368 	bus_size_t off;
    369 {
    370 	volatile u_int16_t *p;
    371 
    372 	alpha_mb();		/* XXX XXX XXX */
    373 
    374 	if ((memh & TC_SPACE_SPARSE) != 0)
    375 		panic("tc_mem_read_2 not implemented for sparse space");
    376 
    377 	p = (u_int16_t *)(memh + off);
    378 	return (*p);
    379 }
    380 
    381 inline u_int32_t
    382 tc_mem_read_4(v, memh, off)
    383 	void *v;
    384 	bus_space_handle_t memh;
    385 	bus_size_t off;
    386 {
    387 	volatile u_int32_t *p;
    388 
    389 	alpha_mb();		/* XXX XXX XXX */
    390 
    391 	if ((memh & TC_SPACE_SPARSE) != 0)
    392 		/* Nothing special to do for 4-byte sparse space accesses */
    393 		p = (u_int32_t *)(memh + (off << 1));
    394 	else
    395 		p = (u_int32_t *)(memh + off);
    396 	return (*p);
    397 }
    398 
    399 inline u_int64_t
    400 tc_mem_read_8(v, memh, off)
    401 	void *v;
    402 	bus_space_handle_t memh;
    403 	bus_size_t off;
    404 {
    405 	volatile u_int64_t *p;
    406 
    407 	alpha_mb();		/* XXX XXX XXX */
    408 
    409 	if ((memh & TC_SPACE_SPARSE) != 0)
    410 		panic("tc_mem_read_8 not implemented for sparse space");
    411 
    412 	p = (u_int64_t *)(memh + off);
    413 	return (*p);
    414 }
    415 
    416 #define	tc_mem_read_multi_N(BYTES,TYPE)					\
    417 void									\
    418 __C(tc_mem_read_multi_,BYTES)(v, h, o, a, c)				\
    419 	void *v;							\
    420 	bus_space_handle_t h;						\
    421 	bus_size_t o, c;						\
    422 	TYPE *a;							\
    423 {									\
    424 									\
    425 	while (c-- > 0) {						\
    426 		tc_mem_barrier(v, h, o, sizeof *a, BUS_SPACE_BARRIER_READ); \
    427 		*a++ = __C(tc_mem_read_,BYTES)(v, h, o);		\
    428 	}								\
    429 }
    430 tc_mem_read_multi_N(1,u_int8_t)
    431 tc_mem_read_multi_N(2,u_int16_t)
    432 tc_mem_read_multi_N(4,u_int32_t)
    433 tc_mem_read_multi_N(8,u_int64_t)
    434 
    435 #define	tc_mem_read_region_N(BYTES,TYPE)				\
    436 void									\
    437 __C(tc_mem_read_region_,BYTES)(v, h, o, a, c)				\
    438 	void *v;							\
    439 	bus_space_handle_t h;						\
    440 	bus_size_t o, c;						\
    441 	TYPE *a;							\
    442 {									\
    443 									\
    444 	while (c-- > 0) {						\
    445 		*a++ = __C(tc_mem_read_,BYTES)(v, h, o);		\
    446 		o += sizeof *a;						\
    447 	}								\
    448 }
    449 tc_mem_read_region_N(1,u_int8_t)
    450 tc_mem_read_region_N(2,u_int16_t)
    451 tc_mem_read_region_N(4,u_int32_t)
    452 tc_mem_read_region_N(8,u_int64_t)
    453 
    454 inline void
    455 tc_mem_write_1(v, memh, off, val)
    456 	void *v;
    457 	bus_space_handle_t memh;
    458 	bus_size_t off;
    459 	u_int8_t val;
    460 {
    461 
    462 	if ((memh & TC_SPACE_SPARSE) != 0) {
    463 		volatile u_int64_t *p, v;
    464 		u_int64_t shift, msk;
    465 
    466 		shift = off & 0x3;
    467 		off &= 0x3;
    468 
    469 		p = (u_int64_t *)(memh + (off << 1));
    470 
    471 		msk = ~(0x1 << shift) & 0xf;
    472 		v = (msk << 32) | (((u_int64_t)val) << (shift * 8));
    473 
    474 		*p = val;
    475 	} else {
    476 		volatile u_int8_t *p;
    477 
    478 		p = (u_int8_t *)(memh + off);
    479 		*p = val;
    480 	}
    481         alpha_mb();		/* XXX XXX XXX */
    482 }
    483 
    484 inline void
    485 tc_mem_write_2(v, memh, off, val)
    486 	void *v;
    487 	bus_space_handle_t memh;
    488 	bus_size_t off;
    489 	u_int16_t val;
    490 {
    491 
    492 	if ((memh & TC_SPACE_SPARSE) != 0) {
    493 		volatile u_int64_t *p, v;
    494 		u_int64_t shift, msk;
    495 
    496 		shift = off & 0x2;
    497 		off &= 0x3;
    498 
    499 		p = (u_int64_t *)(memh + (off << 1));
    500 
    501 		msk = ~(0x3 << shift) & 0xf;
    502 		v = (msk << 32) | (((u_int64_t)val) << (shift * 8));
    503 
    504 		*p = val;
    505 	} else {
    506 		volatile u_int16_t *p;
    507 
    508 		p = (u_int16_t *)(memh + off);
    509 		*p = val;
    510 	}
    511         alpha_mb();		/* XXX XXX XXX */
    512 }
    513 
    514 inline void
    515 tc_mem_write_4(v, memh, off, val)
    516 	void *v;
    517 	bus_space_handle_t memh;
    518 	bus_size_t off;
    519 	u_int32_t val;
    520 {
    521 	volatile u_int32_t *p;
    522 
    523 	if ((memh & TC_SPACE_SPARSE) != 0)
    524 		/* Nothing special to do for 4-byte sparse space accesses */
    525 		p = (u_int32_t *)(memh + (off << 1));
    526 	else
    527 		p = (u_int32_t *)(memh + off);
    528 	*p = val;
    529         alpha_mb();		/* XXX XXX XXX */
    530 }
    531 
    532 inline void
    533 tc_mem_write_8(v, memh, off, val)
    534 	void *v;
    535 	bus_space_handle_t memh;
    536 	bus_size_t off;
    537 	u_int64_t val;
    538 {
    539 	volatile u_int64_t *p;
    540 
    541 	if ((memh & TC_SPACE_SPARSE) != 0)
    542 		panic("tc_mem_read_8 not implemented for sparse space");
    543 
    544 	p = (u_int64_t *)(memh + off);
    545 	*p = val;
    546         alpha_mb();		/* XXX XXX XXX */
    547 }
    548 
    549 #define	tc_mem_write_multi_N(BYTES,TYPE)				\
    550 void									\
    551 __C(tc_mem_write_multi_,BYTES)(v, h, o, a, c)				\
    552 	void *v;							\
    553 	bus_space_handle_t h;						\
    554 	bus_size_t o, c;						\
    555 	const TYPE *a;							\
    556 {									\
    557 									\
    558 	while (c-- > 0) {						\
    559 		__C(tc_mem_write_,BYTES)(v, h, o, *a++);		\
    560 		tc_mem_barrier(v, h, o, sizeof *a, BUS_SPACE_BARRIER_WRITE); \
    561 	}								\
    562 }
    563 tc_mem_write_multi_N(1,u_int8_t)
    564 tc_mem_write_multi_N(2,u_int16_t)
    565 tc_mem_write_multi_N(4,u_int32_t)
    566 tc_mem_write_multi_N(8,u_int64_t)
    567 
    568 #define	tc_mem_write_region_N(BYTES,TYPE)				\
    569 void									\
    570 __C(tc_mem_write_region_,BYTES)(v, h, o, a, c)				\
    571 	void *v;							\
    572 	bus_space_handle_t h;						\
    573 	bus_size_t o, c;						\
    574 	const TYPE *a;							\
    575 {									\
    576 									\
    577 	while (c-- > 0) {						\
    578 		__C(tc_mem_write_,BYTES)(v, h, o, *a++);		\
    579 		o += sizeof *a;						\
    580 	}								\
    581 }
    582 tc_mem_write_region_N(1,u_int8_t)
    583 tc_mem_write_region_N(2,u_int16_t)
    584 tc_mem_write_region_N(4,u_int32_t)
    585 tc_mem_write_region_N(8,u_int64_t)
    586 
    587 #define	tc_mem_set_multi_N(BYTES,TYPE)					\
    588 void									\
    589 __C(tc_mem_set_multi_,BYTES)(v, h, o, val, c)				\
    590 	void *v;							\
    591 	bus_space_handle_t h;						\
    592 	bus_size_t o, c;						\
    593 	TYPE val;							\
    594 {									\
    595 									\
    596 	while (c-- > 0) {						\
    597 		__C(tc_mem_write_,BYTES)(v, h, o, val);			\
    598 		tc_mem_barrier(v, h, o, sizeof val, BUS_SPACE_BARRIER_WRITE); \
    599 	}								\
    600 }
    601 tc_mem_set_multi_N(1,u_int8_t)
    602 tc_mem_set_multi_N(2,u_int16_t)
    603 tc_mem_set_multi_N(4,u_int32_t)
    604 tc_mem_set_multi_N(8,u_int64_t)
    605 
    606 #define	tc_mem_set_region_N(BYTES,TYPE)					\
    607 void									\
    608 __C(tc_mem_set_region_,BYTES)(v, h, o, val, c)				\
    609 	void *v;							\
    610 	bus_space_handle_t h;						\
    611 	bus_size_t o, c;						\
    612 	TYPE val;							\
    613 {									\
    614 									\
    615 	while (c-- > 0) {						\
    616 		__C(tc_mem_write_,BYTES)(v, h, o, val);			\
    617 		o += sizeof val;					\
    618 	}								\
    619 }
    620 tc_mem_set_region_N(1,u_int8_t)
    621 tc_mem_set_region_N(2,u_int16_t)
    622 tc_mem_set_region_N(4,u_int32_t)
    623 tc_mem_set_region_N(8,u_int64_t)
    624 
    625 #define	tc_mem_copy_region_N(BYTES)					\
    626 void									\
    627 __C(tc_mem_copy_region_,BYTES)(v, h1, o1, h2, o2, c)			\
    628 	void *v;							\
    629 	bus_space_handle_t h1, h2;					\
    630 	bus_size_t o1, o2, c;						\
    631 {									\
    632 	bus_size_t o;							\
    633 									\
    634 	if ((h1 & TC_SPACE_SPARSE) != 0 &&				\
    635 	    (h2 & TC_SPACE_SPARSE) != 0) {				\
    636 		memmove((void *)(h2 + o2), (void *)(h1 + o1), c * BYTES); \
    637 		return;							\
    638 	}								\
    639 									\
    640 	if (h1 + o1 >= h2 + o2)						\
    641 		/* src after dest: copy forward */			\
    642 		for (o = 0; c > 0; c--, o += BYTES)			\
    643 			__C(tc_mem_write_,BYTES)(v, h2, o2 + o,		\
    644 			    __C(tc_mem_read_,BYTES)(v, h1, o1 + o));	\
    645 	else								\
    646 		/* dest after src: copy backwards */			\
    647 		for (o = (c - 1) * BYTES; c > 0; c--, o -= BYTES)	\
    648 			__C(tc_mem_write_,BYTES)(v, h2, o2 + o,		\
    649 			    __C(tc_mem_read_,BYTES)(v, h1, o1 + o));	\
    650 }
    651 tc_mem_copy_region_N(1)
    652 tc_mem_copy_region_N(2)
    653 tc_mem_copy_region_N(4)
    654 tc_mem_copy_region_N(8)
    655