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