Home | History | Annotate | Line # | Download | only in g2
g2bus_bus_mem.c revision 1.10
      1 /*	$NetBSD: g2bus_bus_mem.c,v 1.10 2005/02/19 15:37:34 tsutsui Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2001 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Jason R. Thorpe.
      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  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *	This product includes software developed by the NetBSD
     21  *	Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 
     39 /*
     40  * Bus space implementation for the SEGA G2 bus.
     41  *
     42  * NOTE: We only implement a small subset of what the bus_space(9)
     43  * API specifies.  Right now, the GAPS PCI bridge is only used for
     44  * the Dreamcast Broadband Adatper, so we only provide what the
     45  * pci(4) and rtk(4) drivers need.
     46  */
     47 
     48 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
     49 __KERNEL_RCSID(0, "$NetBSD: g2bus_bus_mem.c,v 1.10 2005/02/19 15:37:34 tsutsui Exp $");
     50 
     51 #include <sys/param.h>
     52 #include <sys/systm.h>
     53 #include <sys/device.h>
     54 
     55 #include <machine/cpu.h>
     56 #include <machine/bus.h>
     57 
     58 #include <dreamcast/dev/g2/g2busvar.h>
     59 
     60 int	g2bus_bus_mem_map(void *, bus_addr_t, bus_size_t, int,
     61 	    bus_space_handle_t *);
     62 void	g2bus_bus_mem_unmap(void *, bus_space_handle_t, bus_size_t);
     63 
     64 uint8_t g2bus_bus_mem_read_1(void *, bus_space_handle_t, bus_size_t);
     65 uint16_t g2bus_bus_mem_read_2(void *, bus_space_handle_t, bus_size_t);
     66 uint32_t g2bus_bus_mem_read_4(void *, bus_space_handle_t, bus_size_t);
     67 
     68 void	g2bus_bus_mem_write_1(void *, bus_space_handle_t, bus_size_t,
     69 	    uint8_t);
     70 void	g2bus_bus_mem_write_2(void *, bus_space_handle_t, bus_size_t,
     71 	    uint16_t);
     72 void	g2bus_bus_mem_write_4(void *, bus_space_handle_t, bus_size_t,
     73 	    uint32_t);
     74 
     75 void	g2bus_bus_mem_read_region_1(void *, bus_space_handle_t, bus_size_t,
     76 	    uint8_t *, bus_size_t);
     77 void	g2bus_bus_mem_read_region_2(void *, bus_space_handle_t, bus_size_t,
     78 	    uint16_t *, bus_size_t);
     79 void	g2bus_bus_mem_read_region_4(void *, bus_space_handle_t, bus_size_t,
     80 	    uint32_t *, bus_size_t);
     81 
     82 void	g2bus_bus_mem_write_region_1(void *, bus_space_handle_t, bus_size_t,
     83 	    const uint8_t *, bus_size_t);
     84 void	g2bus_bus_mem_write_region_2(void *, bus_space_handle_t, bus_size_t,
     85 	    const uint16_t *, bus_size_t);
     86 void	g2bus_bus_mem_write_region_4(void *, bus_space_handle_t, bus_size_t,
     87 	    const uint32_t *, bus_size_t);
     88 
     89 void	g2bus_bus_mem_set_region_4(void *, bus_space_handle_t, bus_size_t,
     90 	    uint32_t, bus_size_t);
     91 
     92 uint8_t g2bus_sparse_bus_mem_read_1(void *, bus_space_handle_t, bus_size_t);
     93 uint16_t g2bus_sparse_bus_mem_read_2(void *, bus_space_handle_t, bus_size_t);
     94 uint32_t g2bus_sparse_bus_mem_read_4(void *, bus_space_handle_t, bus_size_t);
     95 
     96 void	g2bus_sparse_bus_mem_write_1(void *, bus_space_handle_t, bus_size_t,
     97 	    uint8_t);
     98 void	g2bus_sparse_bus_mem_write_2(void *, bus_space_handle_t, bus_size_t,
     99 	    uint16_t);
    100 void	g2bus_sparse_bus_mem_write_4(void *, bus_space_handle_t, bus_size_t,
    101 	    uint32_t);
    102 
    103 void	g2bus_sparse_bus_mem_read_region_1(void *, bus_space_handle_t,
    104 	    bus_size_t, uint8_t *, bus_size_t);
    105 
    106 void	g2bus_sparse_bus_mem_write_region_1(void *, bus_space_handle_t,
    107 	    bus_size_t, const uint8_t *, bus_size_t);
    108 
    109 void	g2bus_sparse_bus_mem_read_multi_1(void *, bus_space_handle_t,
    110 	    bus_size_t, uint8_t *, bus_size_t);
    111 
    112 void	g2bus_sparse_bus_mem_write_multi_1(void *, bus_space_handle_t,
    113 	    bus_size_t, const uint8_t *, bus_size_t);
    114 
    115 void
    116 g2bus_bus_mem_init(struct g2bus_softc *sc)
    117 {
    118 	bus_space_tag_t t = &sc->sc_memt;
    119 
    120 	memset(t, 0, sizeof(*t));
    121 
    122 	t->dbs_map = g2bus_bus_mem_map;
    123 	t->dbs_unmap = g2bus_bus_mem_unmap;
    124 
    125 	t->dbs_r_1 = g2bus_bus_mem_read_1;
    126 	t->dbs_r_2 = g2bus_bus_mem_read_2;
    127 	t->dbs_r_4 = g2bus_bus_mem_read_4;
    128 
    129 	t->dbs_w_1 = g2bus_bus_mem_write_1;
    130 	t->dbs_w_2 = g2bus_bus_mem_write_2;
    131 	t->dbs_w_4 = g2bus_bus_mem_write_4;
    132 
    133 	t->dbs_rr_1 = g2bus_bus_mem_read_region_1;
    134 	t->dbs_rr_2 = g2bus_bus_mem_read_region_2;
    135 	t->dbs_rr_4 = g2bus_bus_mem_read_region_4;
    136 
    137 	t->dbs_wr_1 = g2bus_bus_mem_write_region_1;
    138 	t->dbs_wr_2 = g2bus_bus_mem_write_region_2;
    139 	t->dbs_wr_4 = g2bus_bus_mem_write_region_4;
    140 
    141 	t->dbs_sr_4 = g2bus_bus_mem_set_region_4;
    142 }
    143 
    144 int
    145 g2bus_bus_mem_map(void *v, bus_addr_t addr, bus_size_t size, int flags,
    146     bus_space_handle_t *shp)
    147 {
    148 
    149 	KASSERT((addr & SH3_PHYS_MASK) == addr);
    150 	*shp = SH3_PHYS_TO_P2SEG(addr);
    151 
    152 	return 0;
    153 }
    154 
    155 void
    156 g2bus_bus_mem_unmap(void *v, bus_space_handle_t sh, bus_size_t size)
    157 {
    158 
    159 	KASSERT(sh >= SH3_P2SEG_BASE && sh <= SH3_P2SEG_END);
    160 	/* Nothing to do. */
    161 }
    162 
    163 /*
    164  * G2 bus cycles must not be interrupted by IRQs or G2 DMA.
    165  * The following paired macros will take the necessary precautions.
    166  */
    167 
    168 #define G2LOCK_DECL							\
    169 	int __s
    170 
    171 #define G2_LOCK()							\
    172 	do {								\
    173 		__s = _cpu_intr_suspend();				\
    174 		/* suspend any G2 DMA here... */			\
    175 		while ((*(__volatile uint32_t *)0xa05f688c) & 0x20)	\
    176 			;						\
    177 	} while (/*CONSTCOND*/0)
    178 
    179 #define G2_UNLOCK()							\
    180 	do {								\
    181 		/* resume any G2 DMA here... */				\
    182 		_cpu_intr_resume(__s);					\
    183 	} while (/*CONSTCOND*/0)
    184 
    185 uint8_t
    186 g2bus_bus_mem_read_1(void *v, bus_space_handle_t sh, bus_size_t off)
    187 {
    188 	G2LOCK_DECL;
    189 	uint8_t rv;
    190 
    191 	G2_LOCK();
    192 
    193 	rv = *(__volatile uint8_t *)(sh + off);
    194 
    195 	G2_UNLOCK();
    196 
    197 	return rv;
    198 }
    199 
    200 uint16_t
    201 g2bus_bus_mem_read_2(void *v, bus_space_handle_t sh, bus_size_t off)
    202 {
    203 	G2LOCK_DECL;
    204 	uint16_t rv;
    205 
    206 	G2_LOCK();
    207 
    208 	rv = *(__volatile uint16_t *)(sh + off);
    209 
    210 	G2_UNLOCK();
    211 
    212 	return rv;
    213 }
    214 
    215 uint32_t
    216 g2bus_bus_mem_read_4(void *v, bus_space_handle_t sh, bus_size_t off)
    217 {
    218 	G2LOCK_DECL;
    219 	uint32_t rv;
    220 
    221 	G2_LOCK();
    222 
    223 	rv = *(__volatile uint32_t *)(sh + off);
    224 
    225 	G2_UNLOCK();
    226 
    227 	return rv;
    228 }
    229 
    230 void
    231 g2bus_bus_mem_write_1(void *v, bus_space_handle_t sh, bus_size_t off,
    232     uint8_t val)
    233 {
    234 	G2LOCK_DECL;
    235 
    236 	G2_LOCK();
    237 
    238 	*(__volatile uint8_t *)(sh + off) = val;
    239 
    240 	G2_UNLOCK();
    241 }
    242 
    243 void
    244 g2bus_bus_mem_write_2(void *v, bus_space_handle_t sh, bus_size_t off,
    245     uint16_t val)
    246 {
    247 	G2LOCK_DECL;
    248 
    249 	G2_LOCK();
    250 
    251 	*(__volatile uint16_t *)(sh + off) = val;
    252 
    253 	G2_UNLOCK();
    254 }
    255 
    256 void
    257 g2bus_bus_mem_write_4(void *v, bus_space_handle_t sh, bus_size_t off,
    258     uint32_t val)
    259 {
    260 	G2LOCK_DECL;
    261 
    262 	G2_LOCK();
    263 
    264 	*(__volatile uint32_t *)(sh + off) = val;
    265 
    266 	G2_UNLOCK();
    267 }
    268 
    269 void
    270 g2bus_bus_mem_read_region_1(void *v, bus_space_handle_t sh, bus_size_t off,
    271     uint8_t *addr, bus_size_t len)
    272 {
    273 	G2LOCK_DECL;
    274 	__volatile const uint8_t *baddr = (uint8_t *)(sh + off);
    275 
    276 	G2_LOCK();
    277 
    278 	while (len--)
    279 		*addr++ = *baddr++;
    280 
    281 	G2_UNLOCK();
    282 }
    283 
    284 void
    285 g2bus_bus_mem_read_region_2(void *v, bus_space_handle_t sh, bus_size_t off,
    286     uint16_t *addr, bus_size_t len)
    287 {
    288 	G2LOCK_DECL;
    289 	__volatile const uint16_t *baddr = (uint16_t *)(sh + off);
    290 
    291 	G2_LOCK();
    292 
    293 	while (len--)
    294 		*addr++ = *baddr++;
    295 
    296 	G2_UNLOCK();
    297 }
    298 
    299 void
    300 g2bus_bus_mem_read_region_4(void *v, bus_space_handle_t sh, bus_size_t off,
    301     uint32_t *addr, bus_size_t len)
    302 {
    303 	G2LOCK_DECL;
    304 	__volatile const uint32_t *baddr = (uint32_t *)(sh + off);
    305 
    306 	G2_LOCK();
    307 
    308 	while (len--)
    309 		*addr++ = *baddr++;
    310 
    311 	G2_UNLOCK();
    312 }
    313 
    314 void
    315 g2bus_bus_mem_write_region_1(void *v, bus_space_handle_t sh, bus_size_t off,
    316     const uint8_t *addr, bus_size_t len)
    317 {
    318 	G2LOCK_DECL;
    319 	__volatile uint8_t *baddr = (uint8_t *)(sh + off);
    320 
    321 	G2_LOCK();
    322 
    323 	while (len--)
    324 		*baddr++ = *addr++;
    325 
    326 	G2_UNLOCK();
    327 }
    328 
    329 void
    330 g2bus_bus_mem_write_region_2(void *v, bus_space_handle_t sh, bus_size_t off,
    331     const uint16_t *addr, bus_size_t len)
    332 {
    333 	G2LOCK_DECL;
    334 	__volatile uint16_t *baddr = (uint16_t *)(sh + off);
    335 
    336 	G2_LOCK();
    337 
    338 	while (len--)
    339 		*baddr++ = *addr++;
    340 
    341 	G2_UNLOCK();
    342 }
    343 
    344 void
    345 g2bus_bus_mem_write_region_4(void *v, bus_space_handle_t sh, bus_size_t off,
    346     const uint32_t *addr, bus_size_t len)
    347 {
    348 	G2LOCK_DECL;
    349 	__volatile uint32_t *baddr = (uint32_t *)(sh + off);
    350 
    351 	G2_LOCK();
    352 
    353 	while (len--)
    354 		*baddr++ = *addr++;
    355 
    356 	G2_UNLOCK();
    357 }
    358 
    359 void
    360 g2bus_bus_mem_set_region_4(void *v, bus_space_handle_t sh, bus_size_t off,
    361     uint32_t val, bus_size_t len)
    362 {
    363 	G2LOCK_DECL;
    364 	__volatile uint32_t *baddr = (uint32_t *)(sh + off);
    365 
    366 	G2_LOCK();
    367 
    368 	while (len--)
    369 		*baddr++ = val;
    370 
    371 	G2_UNLOCK();
    372 }
    373 
    374 void
    375 g2bus_set_bus_mem_sparse(bus_space_tag_t memt)
    376 {
    377 
    378 	memt->dbs_r_1 = g2bus_sparse_bus_mem_read_1;
    379 	memt->dbs_r_2 = g2bus_sparse_bus_mem_read_2;
    380 	memt->dbs_r_4 = g2bus_sparse_bus_mem_read_4;
    381 
    382 	memt->dbs_w_1 = g2bus_sparse_bus_mem_write_1;
    383 	memt->dbs_w_2 = g2bus_sparse_bus_mem_write_2;
    384 	memt->dbs_w_4 = g2bus_sparse_bus_mem_write_4;
    385 
    386 	memt->dbs_rr_1 = g2bus_sparse_bus_mem_read_region_1;
    387 
    388 	memt->dbs_wr_1 = g2bus_sparse_bus_mem_write_region_1;
    389 
    390 	memt->dbs_rm_1 = g2bus_sparse_bus_mem_read_multi_1;
    391 
    392 	memt->dbs_wm_1 = g2bus_sparse_bus_mem_write_multi_1;
    393 }
    394 
    395 uint8_t
    396 g2bus_sparse_bus_mem_read_1(void *v, bus_space_handle_t sh, bus_size_t off)
    397 {
    398 	G2LOCK_DECL;
    399 	uint8_t rv;
    400 
    401 	G2_LOCK();
    402 
    403 	rv = *(__volatile uint8_t *)(sh + (off * 4));
    404 
    405 	G2_UNLOCK();
    406 
    407 	return rv;
    408 }
    409 
    410 uint16_t
    411 g2bus_sparse_bus_mem_read_2(void *v, bus_space_handle_t sh, bus_size_t off)
    412 {
    413 	G2LOCK_DECL;
    414 	uint16_t rv;
    415 
    416 	G2_LOCK();
    417 
    418 	rv = *(__volatile uint16_t *)(sh + (off * 4));
    419 
    420 	G2_UNLOCK();
    421 
    422 	return rv;
    423 }
    424 
    425 uint32_t
    426 g2bus_sparse_bus_mem_read_4(void *v, bus_space_handle_t sh, bus_size_t off)
    427 {
    428 	G2LOCK_DECL;
    429 	uint32_t rv;
    430 
    431 	G2_LOCK();
    432 
    433 	rv = *(__volatile uint32_t *)(sh + (off * 4));
    434 
    435 	G2_UNLOCK();
    436 
    437 	return rv;
    438 }
    439 
    440 void
    441 g2bus_sparse_bus_mem_write_1(void *v, bus_space_handle_t sh, bus_size_t off,
    442     uint8_t val)
    443 {
    444 	G2LOCK_DECL;
    445 
    446 	G2_LOCK();
    447 
    448 	*(__volatile uint8_t *)(sh + (off * 4)) = val;
    449 
    450 	G2_UNLOCK();
    451 }
    452 
    453 void
    454 g2bus_sparse_bus_mem_write_2(void *v, bus_space_handle_t sh, bus_size_t off,
    455     uint16_t val)
    456 {
    457 	G2LOCK_DECL;
    458 
    459 	G2_LOCK();
    460 
    461 	*(__volatile uint16_t *)(sh + (off * 4)) = val;
    462 
    463 	G2_UNLOCK();
    464 }
    465 
    466 void
    467 g2bus_sparse_bus_mem_write_4(void *v, bus_space_handle_t sh, bus_size_t off,
    468     uint32_t val)
    469 {
    470 	G2LOCK_DECL;
    471 
    472 	G2_LOCK();
    473 
    474 	*(__volatile uint32_t *)(sh + (off * 4)) = val;
    475 
    476 	G2_UNLOCK();
    477 }
    478 
    479 void
    480 g2bus_sparse_bus_mem_read_region_1(void *v, bus_space_handle_t sh,
    481     bus_size_t off, uint8_t *addr, bus_size_t len)
    482 {
    483 	G2LOCK_DECL;
    484 	__volatile const uint8_t *baddr = (uint8_t *)(sh + (off * 4));
    485 
    486 	G2_LOCK();
    487 
    488 	while (len--) {
    489 		*addr++ = *baddr;
    490 		baddr += 4;
    491 	}
    492 
    493 	G2_UNLOCK();
    494 }
    495 
    496 void
    497 g2bus_sparse_bus_mem_write_region_1(void *v, bus_space_handle_t sh,
    498     bus_size_t off, const uint8_t *addr, bus_size_t len)
    499 {
    500 	G2LOCK_DECL;
    501 	__volatile uint8_t *baddr = (uint8_t *)(sh + (off * 4));
    502 
    503 	G2_LOCK();
    504 
    505 	while (len--) {
    506 		*baddr = *addr++;
    507 		baddr += 4;
    508 	}
    509 
    510 	G2_UNLOCK();
    511 }
    512 
    513 void
    514 g2bus_sparse_bus_mem_read_multi_1(void *v, bus_space_handle_t sh,
    515     bus_size_t off, uint8_t *addr, bus_size_t len)
    516 {
    517 	G2LOCK_DECL;
    518 	__volatile const uint8_t *baddr = (uint8_t *)(sh + (off * 4));
    519 
    520 	G2_LOCK();
    521 
    522 	while (len--)
    523 		*addr++ = *baddr;
    524 
    525 	G2_UNLOCK();
    526 }
    527 
    528 void
    529 g2bus_sparse_bus_mem_write_multi_1(void *v, bus_space_handle_t sh,
    530     bus_size_t off, const uint8_t *addr, bus_size_t len)
    531 {
    532 	G2LOCK_DECL;
    533 	__volatile uint8_t *baddr = (uint8_t *)(sh + (off * 4));
    534 
    535 	G2_LOCK();
    536 
    537 	while (len--)
    538 		*baddr = *addr++;
    539 
    540 	G2_UNLOCK();
    541 }
    542