neptune.c revision 1.1.2.3 1 /* $NetBSD: neptune.c,v 1.1.2.3 1998/12/28 14:30:21 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 if (strcmp(ia->ia_name, "neptune") != 0)
165 return 0;
166
167 ia->ia_size = 0x400;
168 if (intio_map_allocate_region (parent, ia, INTIO_MAP_TESTONLY))
169 return 0;
170
171 /* Neptune is a virtual device. Always there. */
172
173 return (1);
174 }
175
176
177 static void
178 neptune_attach(parent, self, aux)
179 struct device *parent, *self;
180 void *aux;
181 {
182 struct neptune_softc *sc = (struct neptune_softc *)self;
183 struct intio_attach_args *ia = aux;
184 struct neptune_attach_args na;
185 int r;
186 struct cfdata *cf;
187
188 ia->ia_size = 0x400;
189 r = intio_map_allocate_region (parent, ia, INTIO_MAP_ALLOCATE);
190 #ifdef DIAGNOSTIC
191 if (r)
192 panic ("IO map for Neptune corruption??");
193 #endif
194
195 sc->sc_bst = malloc(sizeof(struct x68k_bus_space), M_DEVBUF, M_NOWAIT);
196 if (sc->sc_bst == NULL)
197 panic("neptune_attach: can't allocate bus_space structure");
198 *sc->sc_bst = neptune_bus;
199 sc->sc_bst->x68k_bus_device = self;
200
201 sc->sc_addr = (vaddr_t) (ia->ia_addr - PHYS_INTIODEV + intiobase);
202
203 na.na_bst = sc->sc_bst;
204 na.na_intr = ia->ia_intr;
205
206 cf = config_search (neptune_search, self, &na);
207 if (cf) {
208 printf (": Neptune-X ISA bridge\n");
209 config_attach(self, cf, &na, neptune_print);
210 } else {
211 printf (": no device found.\n");
212 intio_map_free_region(parent, ia);
213 }
214 }
215
216 static int
217 neptune_search(parent, cf, aux)
218 struct device *parent;
219 struct cfdata *cf;
220 void *aux;
221 {
222 struct neptune_attach_args *na = aux;
223
224 na->na_addr = cf->neptune_cf_addr;
225
226 return (*cf->cf_attach->ca_match)(parent, cf, na);
227 }
228
229 static int
230 neptune_print(aux, name)
231 void *aux;
232 const char *name;
233 {
234 struct neptune_attach_args *na = aux;
235
236 /* if (na->na_addr > 0) */
237 printf (" addr 0x%06x", na->na_addr);
238
239 return (QUIET);
240 }
241
242
243 /*
244 * neptune bus space stuff.
245 */
246 static int
247 neptune_bus_space_map(t, bpa, size, flags, bshp)
248 bus_space_tag_t t;
249 bus_addr_t bpa;
250 bus_size_t size;
251 int flags;
252 bus_space_handle_t *bshp;
253 {
254 vaddr_t start = ((struct neptune_softc*) ((struct x68k_bus_space*) t)
255 ->x68k_bus_device)->sc_addr;
256
257 /*
258 * Neptune bus is mapped permanently.
259 */
260 *bshp = (bus_space_handle_t) ((u_int)start + ((u_int)bpa - 0x200) * 2);
261
262 if (badaddr(*bshp)) {
263 printf ("XXX\n");
264 return 1;
265 }
266
267 return (0);
268 }
269
270 static void
271 neptune_bus_space_unmap(t, bsh, size)
272 bus_space_tag_t t;
273 bus_space_handle_t bsh;
274 bus_size_t size;
275 {
276 return;
277 }
278
279 static int
280 neptune_bus_space_subregion(t, bsh, offset, size, nbshp)
281 bus_space_tag_t t;
282 bus_space_handle_t bsh;
283 bus_size_t offset, size;
284 bus_space_handle_t *nbshp;
285 {
286
287 *nbshp = bsh + offset*2;
288 return (0);
289 }
290
291 u_int8_t
292 neptune_bus_space_read_1(t, bsh, offset)
293 bus_space_tag_t t;
294 bus_space_handle_t bsh;
295 bus_size_t offset;
296 {
297 return (*((volatile u_int8_t *) (bsh + offset*2)));
298 }
299
300 u_int16_t
301 neptune_bus_space_read_2(t, bsh, offset)
302 bus_space_tag_t t;
303 bus_space_handle_t bsh;
304 bus_size_t offset;
305 {
306 return (*((volatile u_int16_t *) (bsh + offset*2)));
307 }
308
309 void
310 neptune_bus_space_write_1(t, bsh, offset, value)
311 bus_space_tag_t t;
312 bus_space_handle_t bsh;
313 bus_size_t offset;
314 u_int8_t value;
315 {
316 *(volatile u_int8_t *) (bsh + offset*2) = value;
317 }
318
319 void
320 neptune_bus_space_write_2(t, bsh, offset, value)
321 bus_space_tag_t t;
322 bus_space_handle_t bsh;
323 bus_size_t offset;
324 u_int16_t value;
325 {
326 *(volatile u_int16_t *) (bsh + offset*2) = value;
327 }
328
329 void
330 neptune_bus_space_read_multi_1(t, bsh, offset, datap, count)
331 bus_space_tag_t t;
332 bus_space_handle_t bsh;
333 bus_size_t offset;
334 u_int8_t *datap;
335 bus_size_t count;
336 {
337 offset *= 2;
338 while (count-- > 0) {
339 *datap++ = *(volatile u_int8_t *) (bsh + offset);
340 }
341 }
342
343 void
344 neptune_bus_space_read_multi_2(t, bsh, offset, datap, count)
345 bus_space_tag_t t;
346 bus_space_handle_t bsh;
347 bus_size_t offset;
348 u_int16_t *datap;
349 bus_size_t count;
350 {
351 offset *= 2;
352 while (count-- > 0) {
353 *datap++ = *(volatile u_int16_t *) (bsh + offset);
354 }
355 }
356
357 void
358 neptune_bus_space_write_multi_1(t, bsh, offset, datap, count)
359 bus_space_tag_t t;
360 bus_space_handle_t bsh;
361 bus_size_t offset;
362 u_int8_t *datap;
363 bus_size_t count;
364 {
365 offset *= 2;
366 while (count-- > 0) {
367 *(volatile u_int8_t *) (bsh + offset) = *datap++;
368 }
369 }
370
371 void
372 neptune_bus_space_write_multi_2(t, bsh, offset, datap, count)
373 bus_space_tag_t t;
374 bus_space_handle_t bsh;
375 bus_size_t offset;
376 u_int16_t *datap;
377 bus_size_t count;
378 {
379 offset *= 2;
380 while (count-- > 0) {
381 *(volatile u_int16_t *) (bsh + offset) = *datap++;
382 }
383 }
384