Home | History | Annotate | Line # | Download | only in amiga
      1 /* $NetBSD: simple_busfuncs.c,v 1.11 2012/02/12 16:34:06 matt Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Ignatios Souvatzis.
      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: simple_busfuncs.c,v 1.11 2012/02/12 16:34:06 matt Exp $");
     34 
     35 /*
     36  * Do NOT use this standalone.
     37  * Instead define the stride (linear, not logarithmic!) in the enclosing
     38  * file (AMIGA_SIMPLE_BUS_STRIDE), then include this one.
     39  * If you want to use it only to provide the functions without creating the
     40  * method array, also define AMIGA_SIMPLE_BUS_NO_ARRAY
     41  */
     42 
     43 #ifndef AMIGA_SIMPLE_BUS_STRIDE
     44 Error AMIGA_SIMPLE_BUS_STRIDE not defined in __FILE__, line __LINE__ .
     45 #endif
     46 
     47 #include <sys/bus.h>
     48 #include <sys/null.h>
     49 
     50 #define MKN2(x,y) __CONCAT(x, y)
     51 #define MKN1(x,y) MKN2(x, y)
     52 #define oabs(n) MKN1(n, AMIGA_SIMPLE_BUS_STRIDE)
     53 
     54 /* function declarations */
     55 
     56 int oabs(bsm_)(bus_space_tag_t, bus_addr_t, bus_size_t, int,
     57 	bus_space_handle_t *);
     58 
     59 int oabs(bsms_)(bus_space_handle_t, bus_size_t, bus_size_t,
     60 	bus_space_handle_t *);
     61 
     62 void oabs(bsu_)(bus_space_handle_t, bus_size_t);
     63 
     64 bsr (oabs(bsr1_), u_int8_t);
     65 bsw (oabs(bsw1_), u_int8_t);
     66 bsrm(oabs(bsrm1_), u_int8_t);
     67 bswm(oabs(bswm1_), u_int8_t);
     68 bsrm(oabs(bsrr1_), u_int8_t);
     69 bswm(oabs(bswr1_), u_int8_t);
     70 bssr(oabs(bssr1_), u_int8_t);
     71 bscr(oabs(bscr1_), u_int8_t);
     72 
     73 /* function definitions */
     74 /* ARGSUSED */
     75 int
     76 oabs(bsm_)(
     77 	bus_space_tag_t tag,
     78 	bus_addr_t address,
     79 	bus_size_t size,
     80 	int flags,
     81 	bus_space_handle_t *handlep)
     82 {
     83 	*handlep = tag->base + address * AMIGA_SIMPLE_BUS_STRIDE;
     84 	return 0;
     85 }
     86 
     87 /* ARGSUSED */
     88 int
     89 oabs(bsms_)(
     90 	bus_space_handle_t handle,
     91 	bus_size_t offset,
     92 	bus_size_t size,
     93 	bus_space_handle_t *nhandlep)
     94 {
     95 	*nhandlep = handle + offset * AMIGA_SIMPLE_BUS_STRIDE;
     96 	return 0;
     97 }
     98 
     99 /* ARGSUSED */
    100 void
    101 oabs(bsu_)(
    102 	bus_space_handle_t handle,
    103 	bus_size_t size)
    104 {
    105 	return;
    106 }
    107 
    108 u_int8_t
    109 oabs(bsr1_)(
    110 	bus_space_handle_t handle,
    111 	bus_size_t offset)
    112 {
    113 	u_int8_t *p;
    114 	u_int8_t x;
    115 
    116 	p = (u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    117 	x = *p;
    118 	amiga_bus_reorder_protect();
    119 	return x;
    120 }
    121 
    122 void
    123 oabs(bsw1_)(
    124 	bus_space_handle_t handle,
    125 	bus_size_t offset,
    126 	unsigned value)
    127 {
    128 	u_int8_t *p;
    129 
    130 	p = (u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    131 	*p = (u_int8_t)value;
    132 	amiga_bus_reorder_protect();
    133 }
    134 
    135 void
    136 oabs(bsrm1_)(
    137 	bus_space_handle_t handle,
    138 	bus_size_t offset,
    139 	u_int8_t *pointer,
    140 	bus_size_t count)
    141 {
    142 	volatile u_int8_t *p;
    143 
    144 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    145 
    146 	while (count > 0) {
    147 		*pointer++ = *p;
    148 		amiga_bus_reorder_protect();
    149 		--count;
    150 	}
    151 }
    152 
    153 void
    154 oabs(bswm1_)(
    155 	bus_space_handle_t handle,
    156 	bus_size_t offset,
    157 	const u_int8_t *pointer,
    158 	bus_size_t count)
    159 {
    160 	volatile u_int8_t *p;
    161 
    162 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    163 
    164 	while (count > 0) {
    165 		*p = *pointer++;
    166 		amiga_bus_reorder_protect();
    167 		--count;
    168 	}
    169 }
    170 
    171 void
    172 oabs(bsrr1_)(
    173 	bus_space_handle_t handle,
    174 	bus_size_t offset,
    175 	u_int8_t *pointer,
    176 	bus_size_t count)
    177 {
    178 	volatile u_int8_t *p;
    179 
    180 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    181 
    182 	while (count > 0) {
    183 		*pointer++ = *p;
    184 		amiga_bus_reorder_protect();
    185 		p += AMIGA_SIMPLE_BUS_STRIDE;
    186 		--count;
    187 	}
    188 }
    189 
    190 void
    191 oabs(bswr1_)(
    192 	bus_space_handle_t handle,
    193 	bus_size_t offset,
    194 	const u_int8_t *pointer,
    195 	bus_size_t count)
    196 {
    197 	volatile u_int8_t *p;
    198 
    199 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    200 
    201 	while (count > 0) {
    202 		*p = *pointer++;
    203 		amiga_bus_reorder_protect();
    204 		p += AMIGA_SIMPLE_BUS_STRIDE;
    205 		--count;
    206 	}
    207 }
    208 
    209 void
    210 oabs(bssr1_)(
    211 	bus_space_handle_t handle,
    212 	bus_size_t offset,
    213 	unsigned value,
    214 	bus_size_t count)
    215 {
    216 	volatile u_int8_t *p;
    217 
    218 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    219 
    220 	while (count > 0) {
    221 		*p = value;
    222 		amiga_bus_reorder_protect();
    223 		p += AMIGA_SIMPLE_BUS_STRIDE;
    224 		--count;
    225 	}
    226 }
    227 
    228 void
    229 oabs(bscr1_)(
    230 	bus_space_handle_t handlefrom,
    231 	bus_size_t from,
    232 	bus_space_handle_t handleto,
    233 	bus_size_t to,
    234 	bus_size_t count)
    235 {
    236 	volatile u_int8_t *p, *q;
    237 
    238 	p = (volatile u_int8_t *)(handlefrom + from * AMIGA_SIMPLE_BUS_STRIDE);
    239 	q = (volatile u_int8_t *)(handleto   +   to * AMIGA_SIMPLE_BUS_STRIDE);
    240 
    241 	while (count > 0) {
    242 		*q = *p;
    243 		amiga_bus_reorder_protect();
    244 		p += AMIGA_SIMPLE_BUS_STRIDE;
    245 		q += AMIGA_SIMPLE_BUS_STRIDE;
    246 		--count;
    247 	}
    248 }
    249 
    250 
    251 #ifdef AMIGA_SIMPLE_BUS_WORD_METHODS
    252 
    253 /* word methods */
    254 
    255 bsr (oabs(bsr2_), u_int16_t);
    256 bsw (oabs(bsw2_), u_int16_t);
    257 bsrm(oabs(bsrm2_), u_int16_t);
    258 bswm(oabs(bswm2_), u_int16_t);
    259 bsrm(oabs(bsrr2_), u_int16_t);
    260 bswm(oabs(bswr2_), u_int16_t);
    261 bssr(oabs(bssr2_), u_int16_t);
    262 bscr(oabs(bscr2_), u_int16_t);
    263 
    264 u_int16_t
    265 oabs(bsr2_)(
    266 	bus_space_handle_t handle,
    267 	bus_size_t offset)
    268 {
    269 	u_int16_t *p;
    270 	u_int16_t x;
    271 
    272 	p = (u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    273 	x = *p;
    274 	amiga_bus_reorder_protect();
    275 	return x;
    276 }
    277 
    278 void
    279 oabs(bsw2_)(
    280 	bus_space_handle_t handle,
    281 	bus_size_t offset,
    282 	unsigned value)
    283 {
    284 	u_int16_t *p;
    285 
    286 	p = (u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    287 	*p = (u_int16_t)value;
    288 	amiga_bus_reorder_protect();
    289 }
    290 
    291 void
    292 oabs(bsrm2_)(
    293 	bus_space_handle_t handle,
    294 	bus_size_t offset,
    295 	u_int16_t *pointer,
    296 	bus_size_t count)
    297 {
    298 	volatile u_int16_t *p;
    299 
    300 	p = (volatile u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    301 
    302 	while (count > 0) {
    303 		*pointer++ = *p;
    304 		amiga_bus_reorder_protect();
    305 		--count;
    306 	}
    307 }
    308 
    309 void
    310 oabs(bswm2_)(
    311 	bus_space_handle_t handle,
    312 	bus_size_t offset,
    313 	const u_int16_t *pointer,
    314 	bus_size_t count)
    315 {
    316 	volatile u_int16_t *p;
    317 
    318 	p = (volatile u_int16_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    319 
    320 	while (count > 0) {
    321 		*p = *pointer++;
    322 		amiga_bus_reorder_protect();
    323 		--count;
    324 	}
    325 }
    326 
    327 void
    328 oabs(bsrr2_)(
    329 	bus_space_handle_t handle,
    330 	bus_size_t offset,
    331 	u_int16_t *pointer,
    332 	bus_size_t count)
    333 {
    334 	volatile u_int8_t *p;
    335 
    336 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    337 
    338 	while (count > 0) {
    339 		*pointer++ = *(volatile u_int16_t *)p;
    340 		amiga_bus_reorder_protect();
    341 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int16_t);
    342 		--count;
    343 	}
    344 }
    345 
    346 void
    347 oabs(bswr2_)(
    348 	bus_space_handle_t handle,
    349 	bus_size_t offset,
    350 	const u_int16_t *pointer,
    351 	bus_size_t count)
    352 {
    353 	volatile u_int8_t *p;
    354 
    355 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    356 
    357 	while (count > 0) {
    358 		*(volatile u_int16_t *)p = *pointer++;
    359 		amiga_bus_reorder_protect();
    360 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int16_t);
    361 		--count;
    362 	}
    363 }
    364 
    365 void
    366 oabs(bssr2_)(
    367 	bus_space_handle_t handle,
    368 	bus_size_t offset,
    369 	unsigned value,
    370 	bus_size_t count)
    371 {
    372 	volatile u_int8_t *p;
    373 
    374 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    375 
    376 	while (count > 0) {
    377 		*(volatile u_int16_t *)p = (unsigned)value;
    378 		amiga_bus_reorder_protect();
    379 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int16_t);
    380 		--count;
    381 	}
    382 }
    383 
    384 void
    385 oabs(bscr2_)(
    386 	bus_space_handle_t handlefrom,
    387 	bus_size_t from,
    388 	bus_space_handle_t handleto,
    389 	bus_size_t to,
    390 	bus_size_t count)
    391 {
    392 	volatile u_int8_t *p, *q;
    393 
    394 	p = (volatile u_int8_t *)(handlefrom + from * AMIGA_SIMPLE_BUS_STRIDE);
    395 	q = (volatile u_int8_t *)(handleto   +   to * AMIGA_SIMPLE_BUS_STRIDE);
    396 
    397 	while (count > 0) {
    398 		*(volatile u_int16_t *)q = *(volatile u_int16_t *)p;
    399 		amiga_bus_reorder_protect();
    400 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int16_t);
    401 		q += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int16_t);
    402 		--count;
    403 	}
    404 }
    405 #endif /* AMIGA_SIMPLE_BUS_WORD_METHODS */
    406 
    407 #ifdef AMIGA_SIMPLE_BUS_LONGWORD_METHODS
    408 
    409 /* longword methods */
    410 
    411 bsr (oabs(bsr4_), u_int32_t);
    412 bsw (oabs(bsw4_), u_int32_t);
    413 bsrm(oabs(bsrm4_), u_int32_t);
    414 bswm(oabs(bswm4_), u_int32_t);
    415 bsrm(oabs(bsrr4_), u_int32_t);
    416 bswm(oabs(bswr4_), u_int32_t);
    417 bssr(oabs(bssr4_), u_int32_t);
    418 bscr(oabs(bscr4_), u_int32_t);
    419 
    420 u_int32_t
    421 oabs(bsr4_)(
    422 	bus_space_handle_t handle,
    423 	bus_size_t offset)
    424 {
    425 	u_int32_t *p;
    426 	u_int32_t x;
    427 
    428 	p = (u_int32_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    429 	x = *p;
    430 	amiga_bus_reorder_protect();
    431 	return x;
    432 }
    433 
    434 void
    435 oabs(bsw4_)(
    436 	bus_space_handle_t handle,
    437 	bus_size_t offset,
    438 	unsigned value)
    439 {
    440 	u_int32_t *p;
    441 
    442 	p = (u_int32_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    443 	*p = (u_int32_t)value;
    444 	amiga_bus_reorder_protect();
    445 }
    446 
    447 
    448 void
    449 oabs(bsrm4_)(
    450 	bus_space_handle_t handle,
    451 	bus_size_t offset,
    452 	u_int32_t *pointer,
    453 	bus_size_t count)
    454 {
    455 	volatile u_int32_t *p;
    456 
    457 	p = (volatile u_int32_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    458 
    459 	while (count > 0) {
    460 		*pointer++ = *p;
    461 		amiga_bus_reorder_protect();
    462 		--count;
    463 	}
    464 }
    465 
    466 void
    467 oabs(bswm4_)(
    468 	bus_space_handle_t handle,
    469 	bus_size_t offset,
    470 	const u_int32_t *pointer,
    471 	bus_size_t count)
    472 {
    473 	volatile u_int32_t *p;
    474 
    475 	p = (volatile u_int32_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    476 
    477 	while (count > 0) {
    478 		*p = *pointer++;
    479 		amiga_bus_reorder_protect();
    480 		--count;
    481 	}
    482 }
    483 
    484 void
    485 oabs(bsrr4_)(
    486 	bus_space_handle_t handle,
    487 	bus_size_t offset,
    488 	u_int32_t *pointer,
    489 	bus_size_t count)
    490 {
    491 	volatile u_int8_t *p;
    492 
    493 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    494 
    495 	while (count > 0) {
    496 		*pointer++ = *(volatile u_int32_t *)p;
    497 		amiga_bus_reorder_protect();
    498 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int32_t);
    499 		--count;
    500 	}
    501 }
    502 
    503 void
    504 oabs(bswr4_)(
    505 	bus_space_handle_t handle,
    506 	bus_size_t offset,
    507 	const u_int32_t *pointer,
    508 	bus_size_t count)
    509 {
    510 	volatile u_int8_t *p;
    511 
    512 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    513 
    514 	while (count > 0) {
    515 		*(volatile u_int32_t *)p = *pointer++;
    516 		amiga_bus_reorder_protect();
    517 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int32_t);
    518 		--count;
    519 	}
    520 }
    521 
    522 void
    523 oabs(bssr4_)(
    524 	bus_space_handle_t handle,
    525 	bus_size_t offset,
    526 	unsigned value,
    527 	bus_size_t count)
    528 {
    529 	volatile u_int8_t *p;
    530 
    531 	p = (volatile u_int8_t *)(handle + offset * AMIGA_SIMPLE_BUS_STRIDE);
    532 
    533 	while (count > 0) {
    534 		*(volatile u_int32_t *)p = (unsigned)value;
    535 		amiga_bus_reorder_protect();
    536 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int32_t);
    537 		--count;
    538 	}
    539 }
    540 
    541 void
    542 oabs(bscr4_)(
    543 	bus_space_handle_t handlefrom,
    544 	bus_size_t from,
    545 	bus_space_handle_t handleto,
    546 	bus_size_t to,
    547 	bus_size_t count)
    548 {
    549 	volatile u_int8_t *p, *q;
    550 
    551 	p = (volatile u_int8_t *)(handlefrom + from * AMIGA_SIMPLE_BUS_STRIDE);
    552 	q = (volatile u_int8_t *)(handleto   +   to * AMIGA_SIMPLE_BUS_STRIDE);
    553 
    554 	while (count > 0) {
    555 		*(volatile u_int32_t *)q = *(volatile u_int32_t *)p;
    556 		amiga_bus_reorder_protect();
    557 		p += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int32_t);
    558 		q += AMIGA_SIMPLE_BUS_STRIDE * sizeof(u_int32_t);
    559 		--count;
    560 	}
    561 }
    562 #endif /* AMIGA_SIMPLE_BUS_LONGWORD_METHODS */
    563 
    564 #ifndef AMIGA_SIMPLE_BUS_NO_ARRAY
    565 /* method array */
    566 
    567 const struct amiga_bus_space_methods oabs(amiga_bus_stride_) = {
    568 
    569 	.bsm =		oabs(bsm_),
    570 	.bsms =		oabs(bsms_),
    571 	.bsu =		oabs(bsu_),
    572 	.bsa =		NULL,
    573 	.bsf =		NULL,
    574 
    575 	.bsr1 =	oabs(bsr1_),
    576 	.bsw1 =		oabs(bsw1_),
    577 	.bsrm1 =	oabs(bsrm1_),
    578 	.bswm1 =	oabs(bswm1_),
    579 	.bsrr1 =	oabs(bsrr1_),
    580 	.bswr1 =	oabs(bswr1_),
    581 	.bssr1 =	oabs(bssr1_),
    582 	.bscr1 =	oabs(bscr1_),
    583 
    584 #ifdef AMIGA_SIMPLE_BUS_WORD_METHODS
    585 	.bsr2 =		oabs(bsr2_),
    586 	.bsw2 =		oabs(bsw2_),
    587 	.bsrs2 =	oabs(bsr2_),
    588 	.bsws2 =	oabs(bsw2_),
    589 	.bsrm2 =	oabs(bsrm2_),
    590 	.bswm2 =	oabs(bswm2_),
    591 	.bsrms2 =	oabs(bsrm2_),
    592 	.bswms2 =	oabs(bswm2_),
    593 	.bsrr2 =	oabs(bsrr2_),
    594 	.bswr2 =	oabs(bswr2_),
    595 	.bsrrs2 =	oabs(bsrr2_),
    596 	.bswrs2 =	oabs(bswr2_),
    597 	.bssr2 =	oabs(bssr2_),
    598 	.bscr2 =	oabs(bscr2_),
    599 #endif /* AMIGA_SIMPLE_BUS_WORD_METHODS */
    600 
    601 #ifdef AMIGA_SIMPLE_BUS_LONGWORD_METHODS
    602 	.bsr4 =		oabs(bsr4_),
    603 	.bsw4 =		oabs(bsw4_),
    604 	.bsrs4 =	oabs(bsr4_),
    605 	.bsws4 =	oabs(bsw4_),
    606 	.bsrm4 =	oabs(bsrm4_),
    607 	.bswm4 =	oabs(bswm4_),
    608 	.bsrms4 =	oabs(bsrm4_),
    609 	.bswms4 =	oabs(bswm4_),
    610 	.bsrr4 =	oabs(bsrr4_),
    611 	.bswr4 =	oabs(bswr4_),
    612 	.bsrrs4 =	oabs(bsrr4_),
    613 	.bswrs4 =	oabs(bswr4_),
    614 	.bssr4 =	oabs(bssr4_),
    615 	.bscr4 =	oabs(bscr4_)
    616 #endif /* AMIGA_SIMPLE_BUS_LONGWORD_METHODS */
    617 };
    618 #endif
    619