Home | History | Annotate | Line # | Download | only in g2
g2bus_bus_mem.c revision 1.2
      1 /*	$NetBSD: g2bus_bus_mem.c,v 1.2 2001/01/31 21:58:37 marcus 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 #include <machine/cpufunc.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 u_int8_t g2bus_bus_mem_read_1(void *, bus_space_handle_t, bus_size_t);
     65 u_int16_t g2bus_bus_mem_read_2(void *, bus_space_handle_t, bus_size_t);
     66 u_int32_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 	    u_int8_t);
     70 void	g2bus_bus_mem_write_2(void *, bus_space_handle_t, bus_size_t,
     71 	    u_int16_t);
     72 void	g2bus_bus_mem_write_4(void *, bus_space_handle_t, bus_size_t,
     73 	    u_int32_t);
     74 
     75 void
     76 g2bus_bus_mem_init(struct g2bus_softc *sc)
     77 {
     78 	bus_space_tag_t t = &sc->sc_memt;
     79 
     80 	memset(t, 0, sizeof(*t));
     81 
     82 	t->dbs_map = g2bus_bus_mem_map;
     83 	t->dbs_unmap = g2bus_bus_mem_unmap;
     84 
     85 	t->dbs_r_1 = g2bus_bus_mem_read_1;
     86 	t->dbs_r_2 = g2bus_bus_mem_read_2;
     87 	t->dbs_r_4 = g2bus_bus_mem_read_4;
     88 
     89 	t->dbs_w_1 = g2bus_bus_mem_write_1;
     90 	t->dbs_w_2 = g2bus_bus_mem_write_2;
     91 	t->dbs_w_4 = g2bus_bus_mem_write_4;
     92 }
     93 
     94 int
     95 g2bus_bus_mem_map(void *v, bus_addr_t addr, bus_size_t size, int flags,
     96     bus_space_handle_t *shp)
     97 {
     98 
     99 	KASSERT((addr & SH3_PHYS_MASK) == addr);
    100 	*shp = SH3_PHYS_TO_P2SEG(addr);
    101 
    102 	return (0);
    103 }
    104 
    105 void
    106 g2bus_bus_mem_unmap(void *v, bus_space_handle_t sh, bus_size_t size)
    107 {
    108 
    109 	KASSERT(sh >= SH3_P2SEG_BASE && sh <= SH3_P2SEG_END);
    110 	/* Nothing to do. */
    111 }
    112 
    113 /*
    114  * G2 bus cycles must not be interrupted by IRQs or G2 DMA.
    115  * The following paired macros will take the necessary precautions.
    116  */
    117 
    118 #define G2_LOCK								\
    119 	do {								\
    120 		disable_intr();						\
    121 		/* suspend any G2 DMA here... */			\
    122 		while((*(volatile unsigned int *)0xa05f688c) & 32);	\
    123 	} while(0)
    124 
    125 #define G2_UNLOCK							\
    126 	do {								\
    127 		/* resume any G2 DMA here... */				\
    128 		enable_intr();						\
    129 	} while(0)
    130 
    131 
    132 u_int8_t
    133 g2bus_bus_mem_read_1(void *v, bus_space_handle_t sh, bus_size_t off)
    134 {
    135 	u_int8_t rv;
    136 
    137 	G2_LOCK;
    138 
    139 	rv = *(u_int8_t *)(sh + off);
    140 
    141 	G2_UNLOCK;
    142 
    143 	return (rv);
    144 }
    145 
    146 u_int16_t
    147 g2bus_bus_mem_read_2(void *v, bus_space_handle_t sh, bus_size_t off)
    148 {
    149 	u_int16_t rv;
    150 
    151 	G2_LOCK;
    152 
    153 	rv = *(u_int16_t *)(sh + off);
    154 
    155 	G2_UNLOCK;
    156 
    157 	return (rv);
    158 }
    159 
    160 u_int32_t
    161 g2bus_bus_mem_read_4(void *v, bus_space_handle_t sh, bus_size_t off)
    162 {
    163 	u_int32_t rv;
    164 
    165 	G2_LOCK;
    166 
    167 	rv = *(u_int32_t *)(sh + off);
    168 
    169 	G2_UNLOCK;
    170 
    171 	return (rv);
    172 }
    173 
    174 void
    175 g2bus_bus_mem_write_1(void *v, bus_space_handle_t sh, bus_size_t off,
    176     u_int8_t val)
    177 {
    178 
    179 	G2_LOCK;
    180 
    181 	*(u_int8_t *)(sh + off) = val;
    182 
    183 	G2_UNLOCK;
    184 }
    185 
    186 void
    187 g2bus_bus_mem_write_2(void *v, bus_space_handle_t sh, bus_size_t off,
    188     u_int16_t val)
    189 {
    190 
    191 	G2_LOCK;
    192 
    193 	*(u_int16_t *)(sh + off) = val;
    194 
    195 	G2_UNLOCK;
    196 }
    197 
    198 void
    199 g2bus_bus_mem_write_4(void *v, bus_space_handle_t sh, bus_size_t off,
    200     u_int32_t val)
    201 {
    202 
    203 	G2_LOCK;
    204 
    205 	*(u_int32_t *)(sh + off) = val;
    206 
    207 	G2_UNLOCK;
    208 }
    209