Home | History | Annotate | Line # | Download | only in sh3
      1 /*	$NetBSD: sh3_bus_space.c,v 1.1 2011/07/25 21:12:23 dyoung Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1996, 1997, 1998, 2002 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
      9  * Simulation Facility, NASA Ames Research Center.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  * POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 #include <sys/cdefs.h>
     34 __KERNEL_RCSID(0, "$NetBSD: sh3_bus_space.c,v 1.1 2011/07/25 21:12:23 dyoung Exp $");
     35 
     36 #include <sys/types.h>
     37 #include <sys/bus.h>
     38 
     39 /*
     40  *	u_intN_t bus_space_read_N(bus_space_tag_t tag,
     41  *	    bus_space_handle_t bsh, bus_size_t offset);
     42  *
     43  * Read a 1, 2, 4, or 8 byte quantity from bus space
     44  * described by tag/handle/offset.
     45  */
     46 
     47 uint8_t
     48 bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t bsh,
     49     bus_size_t offset)
     50 {
     51 
     52 	return *(volatile uint8_t *)(bsh + offset);
     53 }
     54 
     55 uint16_t
     56 bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t bsh,
     57     bus_size_t offset)
     58 {
     59 
     60 	return bswap16(*(volatile uint16_t *)(bsh + offset));
     61 }
     62 
     63 uint32_t
     64 bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t bsh,
     65     bus_size_t offset)
     66 {
     67 
     68 	return bswap32(*(volatile uint32_t *)(bsh + offset));
     69 }
     70 
     71 uint16_t
     72 bus_space_read_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
     73     bus_size_t offset)
     74 {
     75 
     76 	return *(volatile uint16_t *)(bsh + offset);
     77 }
     78 
     79 uint32_t
     80 bus_space_read_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
     81     bus_size_t offset)
     82 {
     83 
     84 	return *(volatile uint32_t *)(bsh + offset);
     85 }
     86 
     87 /*
     88  *	void bus_space_read_multi_N(bus_space_tag_t tag,
     89  *	    bus_space_handle_t bsh, bus_size_t offset,
     90  *	    u_intN_t *addr, bus_size_t count);
     91  *
     92  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
     93  * described by tag/handle/offset and copy into buffer provided.
     94  */
     95 void
     96 bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
     97     bus_size_t offset, uint8_t *addr, bus_size_t count)
     98 {
     99 
    100 	while (count--)
    101 		*addr++ = bus_space_read_1(tag, bsh, offset);
    102 }
    103 
    104 void
    105 bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
    106     bus_size_t offset, uint16_t *addr, bus_size_t count)
    107 {
    108 
    109 	while (count--)
    110 		*addr++ = bus_space_read_2(tag, bsh, offset);
    111 }
    112 
    113 void
    114 bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
    115     bus_size_t offset, uint32_t *addr, bus_size_t count)
    116 {
    117 
    118 	while (count--)
    119 		*addr++ = bus_space_read_4(tag, bsh, offset);
    120 }
    121 
    122 void
    123 bus_space_read_multi_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
    124     bus_size_t offset, uint16_t *addr, bus_size_t count)
    125 {
    126 
    127 	while (count--)
    128 		*addr++ = *(volatile uint16_t *)(bsh + offset);
    129 }
    130 
    131 void
    132 bus_space_read_multi_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
    133     bus_size_t offset, uint32_t *addr, bus_size_t count)
    134 {
    135 
    136 	while (count--)
    137 		*addr++ = *(volatile uint32_t *)(bsh + offset);
    138 }
    139 
    140 /*
    141  *	void bus_space_read_region_N(bus_space_tag_t tag,
    142  *	    bus_space_handle_t bsh, bus_size_t offset,
    143  *	    u_intN_t *addr, bus_size_t count);
    144  *
    145  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
    146  * described by tag/handle and starting at `offset' and copy into
    147  * buffer provided.
    148  */
    149 void
    150 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
    151     bus_size_t offset, uint8_t *addr, bus_size_t count)
    152 {
    153 	uint8_t *p = (uint8_t *)(bsh + offset);
    154 
    155 	while (count--)
    156 		*addr++ = *p++;
    157 }
    158 
    159 void
    160 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
    161     bus_size_t offset, uint16_t *addr, bus_size_t count)
    162 {
    163 	uint16_t *p = (uint16_t *)(bsh + offset);
    164 
    165 	while (count--)
    166 		*addr++ = bswap16(*p++);
    167 }
    168 
    169 void
    170 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
    171     bus_size_t offset, uint32_t *addr, bus_size_t count)
    172 {
    173 	uint32_t *p = (uint32_t *)(bsh + offset);
    174 
    175 	while (count--)
    176 		*addr++ = bswap32(*p++);
    177 }
    178 
    179 /*
    180  *	void bus_space_read_region_stream_N(bus_space_tag_t tag,
    181  *	    bus_space_handle_t bsh, bus_size_t offset,
    182  *	    u_intN_t *addr, bus_size_t count);
    183  *
    184  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
    185  * described by tag/handle and starting at `offset' and copy into
    186  * buffer provided.
    187  */
    188 void
    189 bus_space_read_region_stream_1(bus_space_tag_t tag, bus_space_handle_t bsh,
    190     bus_size_t offset, uint8_t *addr, bus_size_t count)
    191 {
    192 	uint8_t *p = (uint8_t *)(bsh + offset);
    193 
    194 	while (count--)
    195 		*addr++ = *p++;
    196 }
    197 
    198 void
    199 bus_space_read_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
    200     bus_size_t offset, uint16_t *addr, bus_size_t count)
    201 {
    202 	uint16_t *p = (uint16_t *)(bsh + offset);
    203 
    204 	while (count--)
    205 		*addr++ = *p++;
    206 }
    207 
    208 void
    209 bus_space_read_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
    210     bus_size_t offset, uint32_t *addr, bus_size_t count)
    211 {
    212 	uint32_t *p = (uint32_t *)(bsh + offset);
    213 
    214 	while (count--)
    215 		*addr++ = *p++;
    216 }
    217 
    218 /*
    219  *	void bus_space_write_region_N(bus_space_tag_t tag,
    220  *	    bus_space_handle_t bsh, bus_size_t offset,
    221  *	    const u_intN_t *addr, bus_size_t count);
    222  *
    223  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
    224  * to bus space described by tag/handle starting at `offset'.
    225  */
    226 void
    227 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
    228     bus_size_t offset, const uint8_t *addr, bus_size_t count)
    229 {
    230 	uint8_t *p = (uint8_t *)(bsh + offset);
    231 
    232 	while (count--)
    233 		*p++ = *addr++;
    234 }
    235 
    236 void
    237 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
    238     bus_size_t offset, const uint16_t *addr, bus_size_t count)
    239 {
    240 	uint16_t *p = (uint16_t *)(bsh + offset);
    241 
    242 	while (count--)
    243 		*p++ = bswap16(*addr++);
    244 }
    245 
    246 void
    247 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
    248     bus_size_t offset, const uint32_t *addr, bus_size_t count)
    249 {
    250 	uint32_t *p = (uint32_t *)(bsh + offset);
    251 
    252 	while (count--)
    253 		*p++ = bswap32(*addr++);
    254 }
    255 
    256 /*
    257  *	void bus_space_write_region_stream_N(bus_space_tag_t tag,
    258  *	    bus_space_handle_t bsh, bus_size_t offset,
    259  *	    const u_intN_t *addr, bus_size_t count);
    260  *
    261  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
    262  * to bus space described by tag/handle starting at `offset'.
    263  */
    264 void
    265 bus_space_write_region_stream_1(bus_space_tag_t tag, bus_space_handle_t bsh,
    266     bus_size_t offset, const uint8_t *addr, bus_size_t count)
    267 {
    268 	uint8_t *p = (uint8_t *)(bsh + offset);
    269 
    270 	while (count--)
    271 		*p++ = *addr++;
    272 }
    273 
    274 void
    275 bus_space_write_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
    276     bus_size_t offset, const uint16_t *addr, bus_size_t count)
    277 {
    278 	uint16_t *p = (uint16_t *)(bsh + offset);
    279 
    280 	while (count--)
    281 		*p++ = *addr++;
    282 }
    283 
    284 void
    285 bus_space_write_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
    286     bus_size_t offset, const uint32_t *addr, bus_size_t count)
    287 {
    288 	uint32_t *p = (uint32_t *)(bsh + offset);
    289 
    290 	while (count--)
    291 		*p++ = *addr++;
    292 }
    293 
    294 /*
    295  *	void bus_space_write_N(bus_space_tag_t tag,
    296  *	    bus_space_handle_t bsh, bus_size_t offset,
    297  *	    u_intN_t value);
    298  *
    299  * Write the 1, 2, 4, or 8 byte value `value' to bus space
    300  * described by tag/handle/offset.
    301  */
    302 void
    303 bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
    304     bus_size_t offset, uint8_t value)
    305 {
    306 
    307 	*(volatile uint8_t *)(bsh + offset) = value;
    308 }
    309 
    310 void
    311 bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
    312     bus_size_t offset, uint16_t value)
    313 {
    314 
    315 	*(volatile uint16_t *)(bsh + offset) = bswap16(value);
    316 }
    317 
    318 void
    319 bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
    320     bus_size_t offset, uint32_t value)
    321 {
    322 
    323 	*(volatile uint32_t *)(bsh + offset) = bswap32(value);
    324 }
    325 
    326 void
    327 bus_space_write_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
    328     bus_size_t offset, uint16_t value)
    329 {
    330 
    331 	*(volatile uint16_t *)(bsh + offset) = value;
    332 }
    333 
    334 void
    335 bus_space_write_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
    336     bus_size_t offset, uint32_t value)
    337 {
    338 
    339 	*(volatile uint32_t *)(bsh + offset) = value;
    340 }
    341 
    342 /*
    343  *	void bus_space_write_multi_N(bus_space_tag_t tag,
    344  *	    bus_space_handle_t bsh, bus_size_t offset,
    345  *	    const u_intN_t *addr, bus_size_t count);
    346  *
    347  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
    348  * provided to bus space described by tag/handle/offset.
    349  */
    350 void
    351 bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
    352     bus_size_t offset, const uint8_t *addr, bus_size_t count)
    353 {
    354 
    355 	while (count--)
    356 		bus_space_write_1(tag, bsh, offset, *addr++);
    357 }
    358 
    359 void
    360 bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
    361     bus_size_t offset, const uint16_t *addr, bus_size_t count)
    362 {
    363 
    364 	while (count--)
    365 		bus_space_write_2(tag, bsh, offset, *addr++);
    366 }
    367 
    368 void
    369 bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
    370     bus_size_t offset, const uint32_t *addr, bus_size_t count)
    371 {
    372 
    373 	while (count--)
    374 		bus_space_write_4(tag, bsh, offset, *addr++);
    375 }
    376 
    377 void
    378 bus_space_write_multi_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
    379     bus_size_t offset, const uint16_t *addr, bus_size_t count)
    380 {
    381 
    382 	while (count--)
    383 		bus_space_write_stream_2(tag, bsh, offset, *addr++);
    384 }
    385 
    386 void
    387 bus_space_write_multi_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
    388     bus_size_t offset, const uint32_t *addr, bus_size_t count)
    389 {
    390 
    391 	while (count--)
    392 		bus_space_write_stream_4(tag, bsh, offset, *addr++);
    393 }
    394 
    395 /*
    396  *	void bus_space_set_multi_N(bus_space_tag_t tag,
    397  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
    398  *	    bus_size_t count);
    399  *
    400  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
    401  * by tag/handle/offset `count' times.
    402  */
    403 void
    404 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
    405     bus_size_t offset, uint8_t val, bus_size_t count)
    406 {
    407 
    408 	while (count--)
    409 		bus_space_write_1(tag, bsh, offset, val);
    410 }
    411 
    412 void
    413 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
    414     bus_size_t offset, uint16_t val, bus_size_t count)
    415 {
    416 
    417 	while (count--)
    418 		bus_space_write_2(tag, bsh, offset, val);
    419 }
    420 
    421 void
    422 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
    423     bus_size_t offset, uint32_t val, bus_size_t count)
    424 {
    425 
    426 	while (count--)
    427 		bus_space_write_4(tag, bsh, offset, val);
    428 }
    429 
    430 /*
    431  *	void bus_space_set_region_N(bus_space_tag_t tag,
    432  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
    433  *	    bus_size_t count);
    434  *
    435  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
    436  * by tag/handle starting at `offset'.
    437  */
    438 void
    439 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
    440     bus_size_t offset, uint8_t val, bus_size_t count)
    441 {
    442 	volatile uint8_t *addr = (void *)(bsh + offset);
    443 
    444 	while (count--)
    445 		*addr++ = val;
    446 }
    447 
    448 void
    449 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
    450     bus_size_t offset, uint16_t val, bus_size_t count)
    451 {
    452 	volatile uint16_t *addr = (void *)(bsh + offset);
    453 
    454 	val = bswap16(val);
    455 	while (count--)
    456 		*addr++ = val;
    457 }
    458 
    459 void
    460 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
    461     bus_size_t offset, uint32_t val, bus_size_t count)
    462 {
    463 	volatile uint32_t *addr = (void *)(bsh + offset);
    464 
    465 	val = bswap32(val);
    466 	while (count--)
    467 		*addr++ = val;
    468 }
    469 
    470 /*
    471  *	void bus_space_set_region_stream_N(bus_space_tag_t tag,
    472  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
    473  *	    bus_size_t count);
    474  *
    475  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
    476  * by tag/handle starting at `offset'.
    477  */
    478 void
    479 bus_space_set_region_stream_1(bus_space_tag_t tag, bus_space_handle_t bsh,
    480     bus_size_t offset, uint8_t val, bus_size_t count)
    481 {
    482 	volatile uint8_t *addr = (void *)(bsh + offset);
    483 
    484 	while (count--)
    485 		*addr++ = val;
    486 }
    487 
    488 void
    489 bus_space_set_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
    490     bus_size_t offset, uint16_t val, bus_size_t count)
    491 {
    492 	volatile uint16_t *addr = (void *)(bsh + offset);
    493 
    494 	while (count--)
    495 		*addr++ = val;
    496 }
    497 
    498 void
    499 bus_space_set_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
    500     bus_size_t offset, uint32_t val, bus_size_t count)
    501 {
    502 	volatile uint32_t *addr = (void *)(bsh + offset);
    503 
    504 	while (count--)
    505 		*addr++ = val;
    506 }
    507 
    508 /*
    509  *	void bus_space_copy_region_N(bus_space_tag_t tag,
    510  *	    bus_space_handle_t bsh1, bus_size_t off1,
    511  *	    bus_space_handle_t bsh2, bus_size_t off2,
    512  *	    bus_size_t count);
    513  *
    514  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
    515  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
    516  */
    517 void
    518 bus_space_copy_region_1(bus_space_tag_t t, bus_space_handle_t h1,
    519     bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
    520 {
    521 	volatile uint8_t *addr1 = (void *)(h1 + o1);
    522 	volatile uint8_t *addr2 = (void *)(h2 + o2);
    523 
    524 	if (addr1 >= addr2) {	/* src after dest: copy forward */
    525 		while (c--)
    526 			*addr2++ = *addr1++;
    527 	} else {		/* dest after src: copy backwards */
    528 		addr1 += c - 1;
    529 		addr2 += c - 1;
    530 		while (c--)
    531 			*addr2-- = *addr1--;
    532 	}
    533 }
    534 
    535 void
    536 bus_space_copy_region_2(bus_space_tag_t t, bus_space_handle_t h1,
    537     bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
    538 {
    539 	volatile uint16_t *addr1 = (void *)(h1 + o1);
    540 	volatile uint16_t *addr2 = (void *)(h2 + o2);
    541 
    542 	if (addr1 >= addr2) {	/* src after dest: copy forward */
    543 		while (c--)
    544 			*addr2++ = *addr1++;
    545 	} else {		/* dest after src: copy backwards */
    546 		addr1 += c - 1;
    547 		addr2 += c - 1;
    548 		while (c--)
    549 			*addr2-- = *addr1--;
    550 	}
    551 }
    552 
    553 void
    554 bus_space_copy_region_4(bus_space_tag_t t, bus_space_handle_t h1,
    555     bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
    556 {
    557 	volatile uint32_t *addr1 = (void *)(h1 + o1);
    558 	volatile uint32_t *addr2 = (void *)(h2 + o2);
    559 
    560 	if (addr1 >= addr2) {	/* src after dest: copy forward */
    561 		while (c--)
    562 			*addr2++ = *addr1++;
    563 	} else {		/* dest after src: copy backwards */
    564 		addr1 += c - 1;
    565 		addr2 += c - 1;
    566 		while (c--)
    567 			*addr2-- = *addr1--;
    568 	}
    569 }
    570 
    571