Home | History | Annotate | Line # | Download | only in g2
g2bus_bus_mem.c revision 1.3.6.1
      1 /*	$NetBSD: g2bus_bus_mem.c,v 1.3.6.1 2002/03/16 15:57:24 jdolecek 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 
     50 #include <sys/param.h>
     51 #include <sys/systm.h>
     52 #include <sys/device.h>
     53 
     54 #include <machine/cpu.h>
     55 #include <machine/bus.h>
     56 
     57 #include <dreamcast/dev/g2/g2busvar.h>
     58 
     59 int	g2bus_bus_mem_map(void *, bus_addr_t, bus_size_t, int,
     60 	    bus_space_handle_t *);
     61 void	g2bus_bus_mem_unmap(void *, bus_space_handle_t, bus_size_t);
     62 
     63 u_int8_t g2bus_bus_mem_read_1(void *, bus_space_handle_t, bus_size_t);
     64 u_int16_t g2bus_bus_mem_read_2(void *, bus_space_handle_t, bus_size_t);
     65 u_int32_t g2bus_bus_mem_read_4(void *, bus_space_handle_t, bus_size_t);
     66 
     67 void	g2bus_bus_mem_write_1(void *, bus_space_handle_t, bus_size_t,
     68 	    u_int8_t);
     69 void	g2bus_bus_mem_write_2(void *, bus_space_handle_t, bus_size_t,
     70 	    u_int16_t);
     71 void	g2bus_bus_mem_write_4(void *, bus_space_handle_t, bus_size_t,
     72 	    u_int32_t);
     73 
     74 void	g2bus_bus_mem_read_region_1(void *, bus_space_handle_t, bus_size_t,
     75 	    u_int8_t *, bus_size_t);
     76 
     77 void	g2bus_bus_mem_write_region_1(void *, bus_space_handle_t, bus_size_t,
     78 	    const u_int8_t *, bus_size_t);
     79 
     80 void
     81 g2bus_bus_mem_init(struct g2bus_softc *sc)
     82 {
     83 	bus_space_tag_t t = &sc->sc_memt;
     84 
     85 	memset(t, 0, sizeof(*t));
     86 
     87 	t->dbs_map = g2bus_bus_mem_map;
     88 	t->dbs_unmap = g2bus_bus_mem_unmap;
     89 
     90 	t->dbs_r_1 = g2bus_bus_mem_read_1;
     91 	t->dbs_r_2 = g2bus_bus_mem_read_2;
     92 	t->dbs_r_4 = g2bus_bus_mem_read_4;
     93 
     94 	t->dbs_w_1 = g2bus_bus_mem_write_1;
     95 	t->dbs_w_2 = g2bus_bus_mem_write_2;
     96 	t->dbs_w_4 = g2bus_bus_mem_write_4;
     97 
     98 	t->dbs_rr_1 = g2bus_bus_mem_read_region_1;
     99 
    100 	t->dbs_wr_1 = g2bus_bus_mem_write_region_1;
    101 }
    102 
    103 int
    104 g2bus_bus_mem_map(void *v, bus_addr_t addr, bus_size_t size, int flags,
    105     bus_space_handle_t *shp)
    106 {
    107 
    108 	KASSERT((addr & SH3_PHYS_MASK) == addr);
    109 	*shp = SH3_PHYS_TO_P2SEG(addr);
    110 
    111 	return (0);
    112 }
    113 
    114 void
    115 g2bus_bus_mem_unmap(void *v, bus_space_handle_t sh, bus_size_t size)
    116 {
    117 
    118 	KASSERT(sh >= SH3_P2SEG_BASE && sh <= SH3_P2SEG_END);
    119 	/* Nothing to do. */
    120 }
    121 
    122 /*
    123  * G2 bus cycles must not be interrupted by IRQs or G2 DMA.
    124  * The following paired macros will take the necessary precautions.
    125  */
    126 
    127 #define G2_LOCK								\
    128 	do {								\
    129 		_cpu_exception_suspend();				\
    130 		/* suspend any G2 DMA here... */			\
    131 		while((*(volatile unsigned int *)0xa05f688c) & 32);	\
    132 	} while(/*CONSTCOND*/0)
    133 
    134 #define G2_UNLOCK							\
    135 	do {								\
    136 		/* resume any G2 DMA here... */				\
    137 		_cpu_exception_resume(0);				\
    138 	} while(/*CONSTCOND*/0)
    139 
    140 
    141 u_int8_t
    142 g2bus_bus_mem_read_1(void *v, bus_space_handle_t sh, bus_size_t off)
    143 {
    144 	u_int8_t rv;
    145 
    146 	G2_LOCK;
    147 
    148 	rv = *(__volatile u_int8_t *)(sh + off);
    149 
    150 	G2_UNLOCK;
    151 
    152 	return (rv);
    153 }
    154 
    155 u_int16_t
    156 g2bus_bus_mem_read_2(void *v, bus_space_handle_t sh, bus_size_t off)
    157 {
    158 	u_int16_t rv;
    159 
    160 	G2_LOCK;
    161 
    162 	rv = *(__volatile u_int16_t *)(sh + off);
    163 
    164 	G2_UNLOCK;
    165 
    166 	return (rv);
    167 }
    168 
    169 u_int32_t
    170 g2bus_bus_mem_read_4(void *v, bus_space_handle_t sh, bus_size_t off)
    171 {
    172 	u_int32_t rv;
    173 
    174 	G2_LOCK;
    175 
    176 	rv = *(__volatile u_int32_t *)(sh + off);
    177 
    178 	G2_UNLOCK;
    179 
    180 	return (rv);
    181 }
    182 
    183 void
    184 g2bus_bus_mem_write_1(void *v, bus_space_handle_t sh, bus_size_t off,
    185     u_int8_t val)
    186 {
    187 
    188 	G2_LOCK;
    189 
    190 	*(__volatile u_int8_t *)(sh + off) = val;
    191 
    192 	G2_UNLOCK;
    193 }
    194 
    195 void
    196 g2bus_bus_mem_write_2(void *v, bus_space_handle_t sh, bus_size_t off,
    197     u_int16_t val)
    198 {
    199 
    200 	G2_LOCK;
    201 
    202 	*(__volatile u_int16_t *)(sh + off) = val;
    203 
    204 	G2_UNLOCK;
    205 }
    206 
    207 void
    208 g2bus_bus_mem_write_4(void *v, bus_space_handle_t sh, bus_size_t off,
    209     u_int32_t val)
    210 {
    211 
    212 	G2_LOCK;
    213 
    214 	*(__volatile u_int32_t *)(sh + off) = val;
    215 
    216 	G2_UNLOCK;
    217 }
    218 
    219 void
    220 g2bus_bus_mem_read_region_1(void *v, bus_space_handle_t sh, bus_size_t off,
    221     u_int8_t *addr, bus_size_t len)
    222 {
    223 	__volatile const u_int8_t *baddr = (u_int8_t *)(sh + off);
    224 
    225 	G2_LOCK;
    226 
    227 	while (len--)
    228 		*addr++ = *baddr++;
    229 
    230 	G2_UNLOCK;
    231 }
    232 
    233 void
    234 g2bus_bus_mem_write_region_1(void *v, bus_space_handle_t sh, bus_size_t off,
    235     const u_int8_t *addr, bus_size_t len)
    236 {
    237 	__volatile u_int8_t *baddr = (u_int8_t *)(sh + off);
    238 
    239 	G2_LOCK;
    240 
    241 	while (len--)
    242 		*baddr++ = *addr++;
    243 
    244 	G2_UNLOCK;
    245 }
    246