neptune.c revision 1.1.2.1 1 /* $NetBSD: neptune.c,v 1.1.2.1 1998/12/23 16:47:31 minoura Exp $ */
2
3 /*
4 *
5 * Copyright (c) 1998 NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Minoura Makoto.
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 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by Charles D. Cranor and
22 * Washington University.
23 * 4. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 /*
39 * Neptune-X -- X68k-ISA Bus Bridge
40 */
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/device.h>
45 #include <sys/malloc.h>
46
47 #include <machine/bus.h>
48 #include <machine/cpu.h>
49 #include <machine/frame.h>
50
51 #include <arch/x68k/dev/intiovar.h>
52 #include <arch/x68k/dev/neptunevar.h>
53
54
55 /*
56 * We currently implement only some, to support NE2000 and clones.
57 */
58
59 #define neptune_bus_space_read_4 ((u_int32_t(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t))) neptune_dummy)
60 #define neptune_bus_space_read_multi_4 ((void(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t*, bus_size_t))) neptune_dummy)
61 #define neptune_bus_space_read_region_1 ((void(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t*, bus_size_t))) neptune_dummy)
62 #define neptune_bus_space_read_region_2 ((void(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t*, bus_size_t))) neptune_dummy)
63 #define neptune_bus_space_read_region_4 ((void(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t*, bus_size_t))) neptune_dummy)
64 #define neptune_bus_space_write_4 ((void(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t))) neptune_dummy)
65 #define neptune_bus_space_write_multi_4 ((void(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t*, bus_size_t))) neptune_dummy)
66 #define neptune_bus_space_write_region_1 ((void(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t*, bus_size_t))) neptune_dummy)
67 #define neptune_bus_space_write_region_2 ((void(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t*, bus_size_t))) neptune_dummy)
68 #define neptune_bus_space_write_region_4 ((void(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t*, bus_size_t))) neptune_dummy)
69 #define neptune_bus_space_set_region_1 ((void(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t, bus_size_t))) neptune_dummy)
70 #define neptune_bus_space_set_region_2 ((void(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t, bus_size_t))) neptune_dummy)
71 #define neptune_bus_space_set_region_4 ((void(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t, bus_size_t))) neptune_dummy)
72 #define neptune_bus_space_copy_region_1 ((void(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t))) neptune_dummy)
73 #define neptune_bus_space_copy_region_2 ((void(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t))) neptune_dummy)
74 #define neptune_bus_space_copy_region_4 ((void(*) __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, bus_space_handle_t, bus_size_t, bus_size_t))) neptune_dummy)
75
76
77 static int neptune_bus_space_map __P((bus_space_tag_t, bus_addr_t, bus_size_t,
78 int, bus_space_handle_t*));
79 static void neptune_bus_space_unmap __P((bus_space_tag_t,
80 bus_space_handle_t, bus_size_t));
81 static int neptune_bus_space_subregion __P((bus_space_tag_t, bus_space_handle_t,
82 bus_size_t, bus_size_t,
83 bus_space_handle_t*));
84 u_int8_t neptune_bus_space_read_1 __P((bus_space_tag_t,
85 bus_space_handle_t, bus_size_t));
86 u_int16_t neptune_bus_space_read_2 __P((bus_space_tag_t,
87 bus_space_handle_t, bus_size_t));
88 void neptune_bus_space_write_1 __P((bus_space_tag_t,
89 bus_space_handle_t, bus_size_t, u_int8_t));
90 void neptune_bus_space_write_2 __P((bus_space_tag_t,
91 bus_space_handle_t, bus_size_t, u_int16_t));
92 void neptune_bus_space_read_multi_1 __P((bus_space_tag_t, bus_space_handle_t,
93 bus_size_t, u_int8_t *, bus_size_t));
94 void neptune_bus_space_read_multi_2 __P((bus_space_tag_t, bus_space_handle_t,
95 bus_size_t, u_int16_t *, bus_size_t));
96 void neptune_bus_space_write_multi_1 __P((bus_space_tag_t, bus_space_handle_t,
97 bus_size_t, u_int8_t *, bus_size_t));
98 void neptune_bus_space_write_multi_2 __P((bus_space_tag_t, bus_space_handle_t,
99 bus_size_t, u_int16_t *, bus_size_t));
100
101
102 void neptune_dummy __P((void));
103
104 static struct x68k_bus_space neptune_bus = {
105 #if 0
106 X68K_NEPUTUNE_BUS,
107 #endif
108 neptune_bus_space_map, neptune_bus_space_unmap,
109 neptune_bus_space_subregion,
110 x68k_bus_space_alloc, x68k_bus_space_free,
111
112 neptune_bus_space_read_1,
113 neptune_bus_space_read_2,
114 neptune_bus_space_read_4,
115 neptune_bus_space_read_multi_1,
116 neptune_bus_space_read_multi_2,
117 neptune_bus_space_read_multi_4,
118 neptune_bus_space_read_region_1,
119 neptune_bus_space_read_region_2,
120 neptune_bus_space_read_region_4,
121
122 neptune_bus_space_write_1,
123 neptune_bus_space_write_2,
124 neptune_bus_space_write_4,
125 neptune_bus_space_write_multi_1,
126 neptune_bus_space_write_multi_2,
127 neptune_bus_space_write_multi_4,
128 neptune_bus_space_write_region_1,
129 neptune_bus_space_write_region_2,
130 neptune_bus_space_write_region_4,
131
132 neptune_bus_space_set_region_1,
133 neptune_bus_space_set_region_2,
134 neptune_bus_space_set_region_4,
135 neptune_bus_space_copy_region_1,
136 neptune_bus_space_copy_region_2,
137 neptune_bus_space_copy_region_4
138 };
139
140 void
141 neptune_dummy (void)
142 {
143 panic ("neptune: Unimplemented bus_space operation");
144 }
145
146
147 static int neptune_match __P((struct device *, struct cfdata *, void *));
148 static void neptune_attach __P((struct device *, struct device *, void *));
149 static int neptune_search __P((struct device *, struct cfdata *cf, void *));
150 static int neptune_print __P((void *, const char *));
151
152 struct cfattach neptune_ca = {
153 sizeof(struct neptune_softc), neptune_match, neptune_attach
154 };
155
156 static int
157 neptune_match(parent, cf, aux)
158 struct device *parent;
159 struct cfdata *cf;
160 void *aux;
161 {
162 struct intio_attach_args *ia = aux;
163
164 ia->ia_size = 0x400;
165 if (intio_map_allocate_region (parent, ia, INTIO_MAP_TESTONLY))
166 return 0;
167
168 /* Neptune is a virtual device. Always there. */
169
170 return (1);
171 }
172
173
174 static void
175 neptune_attach(parent, self, aux)
176 struct device *parent, *self;
177 void *aux;
178 {
179 struct neptune_softc *sc = (struct neptune_softc *)self;
180 struct intio_attach_args *ia = aux;
181 struct neptune_attach_args na;
182 int r;
183 struct cfdata *cf;
184
185 ia->ia_size = 0x400;
186 r = intio_map_allocate_region (parent, ia, INTIO_MAP_ALLOCATE);
187 #ifdef DIAGNOSTIC
188 if (r)
189 panic ("IO map for Neptune corruption??");
190 #endif
191
192 sc->sc_bst = malloc(sizeof(struct x68k_bus_space), M_DEVBUF, M_NOWAIT);
193 if (sc->sc_bst == NULL)
194 panic("neptune_attach: can't allocate bus_space structure");
195 *sc->sc_bst = neptune_bus;
196 sc->sc_bst->x68k_bus_device = self;
197
198 sc->sc_addr = (vaddr_t) (ia->ia_addr - PHYS_INTIODEV + intiobase);
199
200 na.na_bst = sc->sc_bst;
201 na.na_intr = ia->ia_intr;
202
203 cf = config_search (neptune_search, self, &na);
204 if (cf) {
205 printf (": Neptune-X ISA bridge\n");
206 config_attach(self, cf, &na, neptune_print);
207 } else {
208 printf (": no device found.\n");
209 }
210 }
211
212 static int
213 neptune_search(parent, cf, aux)
214 struct device *parent;
215 struct cfdata *cf;
216 void *aux;
217 {
218 struct neptune_attach_args *na = aux;
219
220 na->na_addr = cf->neptune_cf_addr;
221
222 return (*cf->cf_attach->ca_match)(parent, cf, na);
223 }
224
225 static int
226 neptune_print(aux, name)
227 void *aux;
228 const char *name;
229 {
230 struct neptune_attach_args *na = aux;
231
232 /* if (na->na_addr > 0) */
233 printf (" addr 0x%06x", na->na_addr);
234
235 return (QUIET);
236 }
237
238
239 /*
240 * neptune bus space stuff.
241 */
242 static int
243 neptune_bus_space_map(t, bpa, size, flags, bshp)
244 bus_space_tag_t t;
245 bus_addr_t bpa;
246 bus_size_t size;
247 int flags;
248 bus_space_handle_t *bshp;
249 {
250 vaddr_t start = ((struct neptune_softc*) ((struct x68k_bus_space*) t)
251 ->x68k_bus_device)->sc_addr;
252
253 /*
254 * Neptune bus is mapped permanently.
255 */
256 *bshp = (bus_space_handle_t) ((u_int)start + ((u_int)bpa - 0x200) * 2);
257
258 if (badaddr(*bshp)) {
259 printf ("XXX\n");
260 return 1;
261 }
262
263 return (0);
264 }
265
266 static void
267 neptune_bus_space_unmap(t, bsh, size)
268 bus_space_tag_t t;
269 bus_space_handle_t bsh;
270 bus_size_t size;
271 {
272 return;
273 }
274
275 static int
276 neptune_bus_space_subregion(t, bsh, offset, size, nbshp)
277 bus_space_tag_t t;
278 bus_space_handle_t bsh;
279 bus_size_t offset, size;
280 bus_space_handle_t *nbshp;
281 {
282
283 *nbshp = bsh + offset*2;
284 return (0);
285 }
286
287 u_int8_t
288 neptune_bus_space_read_1(t, bsh, offset)
289 bus_space_tag_t t;
290 bus_space_handle_t bsh;
291 bus_size_t offset;
292 {
293 return (*((volatile u_int8_t *) (bsh + offset*2)));
294 }
295
296 u_int16_t
297 neptune_bus_space_read_2(t, bsh, offset)
298 bus_space_tag_t t;
299 bus_space_handle_t bsh;
300 bus_size_t offset;
301 {
302 return (*((volatile u_int16_t *) (bsh + offset*2)));
303 }
304
305 void
306 neptune_bus_space_write_1(t, bsh, offset, value)
307 bus_space_tag_t t;
308 bus_space_handle_t bsh;
309 bus_size_t offset;
310 u_int8_t value;
311 {
312 *(volatile u_int8_t *) (bsh + offset*2) = value;
313 }
314
315 void
316 neptune_bus_space_write_2(t, bsh, offset, value)
317 bus_space_tag_t t;
318 bus_space_handle_t bsh;
319 bus_size_t offset;
320 u_int16_t value;
321 {
322 *(volatile u_int16_t *) (bsh + offset*2) = value;
323 }
324
325 void
326 neptune_bus_space_read_multi_1(t, bsh, offset, datap, count)
327 bus_space_tag_t t;
328 bus_space_handle_t bsh;
329 bus_size_t offset;
330 u_int8_t *datap;
331 bus_size_t count;
332 {
333 offset *= 2;
334 while (count-- > 0) {
335 *datap++ = *(volatile u_int8_t *) (bsh + offset);
336 }
337 }
338
339 void
340 neptune_bus_space_read_multi_2(t, bsh, offset, datap, count)
341 bus_space_tag_t t;
342 bus_space_handle_t bsh;
343 bus_size_t offset;
344 u_int16_t *datap;
345 bus_size_t count;
346 {
347 offset *= 2;
348 while (count-- > 0) {
349 *datap++ = *(volatile u_int16_t *) (bsh + offset);
350 }
351 }
352
353 void
354 neptune_bus_space_write_multi_1(t, bsh, offset, datap, count)
355 bus_space_tag_t t;
356 bus_space_handle_t bsh;
357 bus_size_t offset;
358 u_int8_t *datap;
359 bus_size_t count;
360 {
361 offset *= 2;
362 while (count-- > 0) {
363 *(volatile u_int8_t *) (bsh + offset) = *datap++;
364 }
365 }
366
367 void
368 neptune_bus_space_write_multi_2(t, bsh, offset, datap, count)
369 bus_space_tag_t t;
370 bus_space_handle_t bsh;
371 bus_size_t offset;
372 u_int16_t *datap;
373 bus_size_t count;
374 {
375 offset *= 2;
376 while (count-- > 0) {
377 *(volatile u_int16_t *) (bsh + offset) = *datap++;
378 }
379 }
380