intio.c revision 1.1.2.2 1 1.1.2.2 minoura /* $NetBSD: intio.c,v 1.1.2.2 1998/12/27 14:13:04 minoura Exp $ */
2 1.1.2.1 minoura
3 1.1.2.1 minoura /*
4 1.1.2.1 minoura *
5 1.1.2.1 minoura * Copyright (c) 1998 NetBSD Foundation, Inc.
6 1.1.2.1 minoura * All rights reserved.
7 1.1.2.1 minoura *
8 1.1.2.1 minoura * Redistribution and use in source and binary forms, with or without
9 1.1.2.1 minoura * modification, are permitted provided that the following conditions
10 1.1.2.1 minoura * are met:
11 1.1.2.1 minoura * 1. Redistributions of source code must retain the above copyright
12 1.1.2.1 minoura * notice, this list of conditions and the following disclaimer.
13 1.1.2.1 minoura * 2. Redistributions in binary form must reproduce the above copyright
14 1.1.2.1 minoura * notice, this list of conditions and the following disclaimer in the
15 1.1.2.1 minoura * documentation and/or other materials provided with the distribution.
16 1.1.2.1 minoura * 3. All advertising materials mentioning features or use of this software
17 1.1.2.1 minoura * must display the following acknowledgement:
18 1.1.2.1 minoura * This product includes software developed by Charles D. Cranor and
19 1.1.2.1 minoura * Washington University.
20 1.1.2.1 minoura * 4. The name of the author may not be used to endorse or promote products
21 1.1.2.1 minoura * derived from this software without specific prior written permission.
22 1.1.2.1 minoura *
23 1.1.2.1 minoura * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 1.1.2.1 minoura * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 1.1.2.1 minoura * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 1.1.2.1 minoura * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 1.1.2.1 minoura * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 1.1.2.1 minoura * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 1.1.2.1 minoura * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 1.1.2.1 minoura * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 1.1.2.1 minoura * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 1.1.2.1 minoura * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 1.1.2.1 minoura */
34 1.1.2.1 minoura
35 1.1.2.1 minoura /*
36 1.1.2.1 minoura * NetBSD/x68k internal I/O virtual bus.
37 1.1.2.1 minoura */
38 1.1.2.1 minoura
39 1.1.2.1 minoura #include <sys/param.h>
40 1.1.2.1 minoura #include <sys/systm.h>
41 1.1.2.1 minoura #include <sys/device.h>
42 1.1.2.1 minoura #include <sys/malloc.h>
43 1.1.2.1 minoura #include <sys/extent.h>
44 1.1.2.1 minoura
45 1.1.2.1 minoura #include <machine/bus.h>
46 1.1.2.1 minoura #include <machine/cpu.h>
47 1.1.2.1 minoura #include <machine/frame.h>
48 1.1.2.1 minoura
49 1.1.2.1 minoura #include <arch/x68k/dev/intiovar.h>
50 1.1.2.1 minoura #include <arch/x68k/dev/mfp.h>
51 1.1.2.1 minoura
52 1.1.2.1 minoura
53 1.1.2.1 minoura /*
54 1.1.2.1 minoura * bus_space(9) interface
55 1.1.2.1 minoura */
56 1.1.2.1 minoura static int intio_bus_space_map __P((bus_space_tag_t, bus_addr_t, bus_size_t, int, bus_space_handle_t *));
57 1.1.2.1 minoura static void intio_bus_space_unmap __P((bus_space_tag_t, bus_space_handle_t, bus_size_t));
58 1.1.2.1 minoura static int intio_bus_space_subregion __P((bus_space_tag_t, bus_space_handle_t, bus_size_t, bus_size_t, bus_space_handle_t *));
59 1.1.2.1 minoura
60 1.1.2.1 minoura static struct x68k_bus_space intio_bus = {
61 1.1.2.1 minoura #if 0
62 1.1.2.1 minoura X68K_INTIO_BUS,
63 1.1.2.1 minoura #endif
64 1.1.2.1 minoura intio_bus_space_map, intio_bus_space_unmap, intio_bus_space_subregion,
65 1.1.2.1 minoura x68k_bus_space_alloc, x68k_bus_space_free,
66 1.1.2.1 minoura #if 0
67 1.1.2.1 minoura x68k_bus_space_barrier,
68 1.1.2.1 minoura #endif
69 1.1.2.1 minoura x68k_bus_space_read_1, x68k_bus_space_read_2, x68k_bus_space_read_4,
70 1.1.2.1 minoura x68k_bus_space_read_multi_1, x68k_bus_space_read_multi_2,
71 1.1.2.1 minoura x68k_bus_space_read_multi_4,
72 1.1.2.1 minoura x68k_bus_space_read_region_1, x68k_bus_space_read_region_2,
73 1.1.2.1 minoura x68k_bus_space_read_region_4,
74 1.1.2.1 minoura
75 1.1.2.1 minoura x68k_bus_space_write_1, x68k_bus_space_write_2, x68k_bus_space_write_4,
76 1.1.2.1 minoura x68k_bus_space_write_multi_1, x68k_bus_space_write_multi_2,
77 1.1.2.1 minoura x68k_bus_space_write_multi_4,
78 1.1.2.1 minoura x68k_bus_space_write_region_1, x68k_bus_space_write_region_2,
79 1.1.2.1 minoura x68k_bus_space_write_region_4,
80 1.1.2.1 minoura
81 1.1.2.1 minoura x68k_bus_space_set_region_1, x68k_bus_space_set_region_2,
82 1.1.2.1 minoura x68k_bus_space_set_region_4,
83 1.1.2.1 minoura x68k_bus_space_copy_region_1, x68k_bus_space_copy_region_2,
84 1.1.2.1 minoura x68k_bus_space_copy_region_4,
85 1.1.2.1 minoura
86 1.1.2.1 minoura 0
87 1.1.2.1 minoura };
88 1.1.2.1 minoura
89 1.1.2.1 minoura
90 1.1.2.1 minoura /*
91 1.1.2.1 minoura * autoconf stuff
92 1.1.2.1 minoura */
93 1.1.2.1 minoura static int intio_match __P((struct device *, struct cfdata *, void *));
94 1.1.2.1 minoura static void intio_attach __P((struct device *, struct device *, void *));
95 1.1.2.1 minoura static int intio_search __P((struct device *, struct cfdata *cf, void *));
96 1.1.2.1 minoura static int intio_print __P((void *, const char *));
97 1.1.2.1 minoura static void intio_alloc_system_ports __P((struct intio_softc*));
98 1.1.2.1 minoura
99 1.1.2.1 minoura struct cfattach intio_ca = {
100 1.1.2.1 minoura sizeof(struct intio_softc), intio_match, intio_attach
101 1.1.2.1 minoura };
102 1.1.2.1 minoura
103 1.1.2.1 minoura static struct intio_interrupt_vector {
104 1.1.2.1 minoura intio_intr_handler_t iiv_handler;
105 1.1.2.1 minoura void *iiv_arg;
106 1.1.2.1 minoura } iiv[256] = {0,};
107 1.1.2.1 minoura
108 1.1.2.1 minoura extern struct cfdriver intio_cd;
109 1.1.2.1 minoura
110 1.1.2.1 minoura /* used in console initialization */
111 1.1.2.1 minoura extern int x68k_realconfig;
112 1.1.2.1 minoura int x68k_config_found __P((struct cfdata *, struct device *,
113 1.1.2.1 minoura void *, cfprint_t));
114 1.1.2.1 minoura static struct cfdata *cfdata_intiobus = NULL;
115 1.1.2.1 minoura
116 1.1.2.1 minoura static int
117 1.1.2.1 minoura intio_match(parent, cf, aux)
118 1.1.2.1 minoura struct device *parent;
119 1.1.2.1 minoura struct cfdata *cf;
120 1.1.2.1 minoura void *aux; /* NULL */
121 1.1.2.1 minoura {
122 1.1.2.1 minoura if (strcmp(aux, intio_cd.cd_name) != 0)
123 1.1.2.1 minoura return (0);
124 1.1.2.1 minoura if (cf->cf_unit != 0)
125 1.1.2.1 minoura return (0);
126 1.1.2.1 minoura if (x68k_realconfig == 0)
127 1.1.2.1 minoura cfdata_intiobus = cf; /* XXX */
128 1.1.2.1 minoura
129 1.1.2.1 minoura return (1);
130 1.1.2.1 minoura }
131 1.1.2.1 minoura
132 1.1.2.1 minoura
133 1.1.2.1 minoura /* used in console initialization: configure only MFP */
134 1.1.2.1 minoura static struct intio_attach_args initial_ia = {
135 1.1.2.1 minoura &intio_bus,
136 1.1.2.1 minoura 0/*XXX*/,
137 1.1.2.1 minoura
138 1.1.2.2 minoura "mfp", /* ia_name */
139 1.1.2.1 minoura MFP_ADDR, /* ia_addr */
140 1.1.2.1 minoura MFP_INTR, /* ia_intr */
141 1.1.2.1 minoura -1, /* ia_errintr */
142 1.1.2.1 minoura -1 /* ia_dma */
143 1.1.2.1 minoura };
144 1.1.2.1 minoura
145 1.1.2.1 minoura static void
146 1.1.2.1 minoura intio_attach(parent, self, aux)
147 1.1.2.1 minoura struct device *parent, *self;
148 1.1.2.1 minoura void *aux; /* NULL */
149 1.1.2.1 minoura {
150 1.1.2.1 minoura struct intio_softc *sc = (struct intio_softc *)self;
151 1.1.2.1 minoura struct intio_attach_args ia;
152 1.1.2.1 minoura
153 1.1.2.1 minoura if (self == NULL) {
154 1.1.2.1 minoura /* console only init */
155 1.1.2.1 minoura x68k_config_found(cfdata_intiobus, NULL, &initial_ia, NULL);
156 1.1.2.1 minoura return;
157 1.1.2.1 minoura }
158 1.1.2.1 minoura
159 1.1.2.1 minoura printf (" mapped at 0x%08p\n", intiobase);
160 1.1.2.1 minoura
161 1.1.2.1 minoura sc->sc_map = extent_create("intiomap",
162 1.1.2.1 minoura PHYS_INTIODEV,
163 1.1.2.1 minoura PHYS_INTIODEV + 0x400000,
164 1.1.2.1 minoura M_DEVBUF, NULL, NULL, EX_NOWAIT);
165 1.1.2.1 minoura intio_alloc_system_ports (sc);
166 1.1.2.1 minoura
167 1.1.2.1 minoura sc->sc_bst = &intio_bus;
168 1.1.2.1 minoura sc->sc_bst->x68k_bus_device = self;
169 1.1.2.1 minoura #if 0
170 1.1.2.1 minoura sc->sc_dmat = &intio_dma;
171 1.1.2.1 minoura #endif
172 1.1.2.1 minoura bzero(iiv, sizeof (struct intio_interrupt_vector) * 256);
173 1.1.2.1 minoura
174 1.1.2.1 minoura ia.ia_bst = sc->sc_bst;
175 1.1.2.1 minoura ia.ia_dmat = sc->sc_dmat;
176 1.1.2.1 minoura
177 1.1.2.1 minoura config_search (intio_search, self, &ia);
178 1.1.2.1 minoura }
179 1.1.2.1 minoura
180 1.1.2.1 minoura static int
181 1.1.2.1 minoura intio_search(parent, cf, aux)
182 1.1.2.1 minoura struct device *parent;
183 1.1.2.1 minoura struct cfdata *cf;
184 1.1.2.1 minoura void *aux;
185 1.1.2.1 minoura {
186 1.1.2.1 minoura struct intio_attach_args *ia = aux;
187 1.1.2.1 minoura struct intio_softc *sc = (struct intio_softc *)parent;
188 1.1.2.1 minoura
189 1.1.2.1 minoura ia->ia_bst = sc->sc_bst;
190 1.1.2.1 minoura ia->ia_dmat = sc->sc_dmat;
191 1.1.2.2 minoura ia->ia_name = cf->cf_driver->cd_name;
192 1.1.2.1 minoura ia->ia_addr = cf->cf_addr;
193 1.1.2.1 minoura ia->ia_intr = cf->cf_intr;
194 1.1.2.1 minoura ia->ia_errintr = cf->cf_errintr;
195 1.1.2.1 minoura ia->ia_dma = cf->cf_dma;
196 1.1.2.1 minoura
197 1.1.2.1 minoura if ((*cf->cf_attach->ca_match)(parent, cf, ia) > 0)
198 1.1.2.1 minoura config_attach(parent, cf, ia, intio_print);
199 1.1.2.1 minoura
200 1.1.2.1 minoura return (0);
201 1.1.2.1 minoura }
202 1.1.2.1 minoura
203 1.1.2.1 minoura static int
204 1.1.2.1 minoura intio_print(aux, name)
205 1.1.2.1 minoura void *aux;
206 1.1.2.1 minoura const char *name;
207 1.1.2.1 minoura {
208 1.1.2.1 minoura struct intio_attach_args *ia = aux;
209 1.1.2.1 minoura
210 1.1.2.1 minoura /* if (ia->ia_addr > 0) */
211 1.1.2.1 minoura printf (" addr 0x%06x", ia->ia_addr);
212 1.1.2.1 minoura if (ia->ia_intr > 0) {
213 1.1.2.1 minoura printf (" interrupting at 0x%02x", ia->ia_intr);
214 1.1.2.1 minoura if (ia->ia_errintr > 0)
215 1.1.2.1 minoura printf (" and 0x%02x", ia->ia_errintr);
216 1.1.2.1 minoura }
217 1.1.2.1 minoura if (ia->ia_dma >= 0)
218 1.1.2.1 minoura printf (" using DMA ch%d", ia->ia_dma);
219 1.1.2.1 minoura
220 1.1.2.1 minoura return (QUIET);
221 1.1.2.1 minoura }
222 1.1.2.1 minoura
223 1.1.2.1 minoura /*
224 1.1.2.1 minoura * intio memory map manager
225 1.1.2.1 minoura */
226 1.1.2.1 minoura
227 1.1.2.1 minoura int
228 1.1.2.1 minoura intio_map_allocate_region(parent, ia, flag)
229 1.1.2.1 minoura struct device *parent;
230 1.1.2.1 minoura struct intio_attach_args *ia;
231 1.1.2.1 minoura enum intio_map_flag flag; /* INTIO_MAP_TESTONLY or INTIO_MAP_ALLOCATE */
232 1.1.2.1 minoura {
233 1.1.2.1 minoura struct intio_softc *sc = (struct intio_softc*) parent;
234 1.1.2.1 minoura struct extent *map = sc->sc_map;
235 1.1.2.1 minoura int r;
236 1.1.2.1 minoura
237 1.1.2.1 minoura r = extent_alloc_region (map, ia->ia_addr, ia->ia_size, 0);
238 1.1.2.1 minoura #ifdef DEBUG
239 1.1.2.1 minoura extent_print (map);
240 1.1.2.1 minoura #endif
241 1.1.2.1 minoura if (r == 0) {
242 1.1.2.1 minoura if (flag != INTIO_MAP_ALLOCATE)
243 1.1.2.1 minoura extent_free (map, ia->ia_addr, ia->ia_size, 0);
244 1.1.2.1 minoura return 0;
245 1.1.2.1 minoura }
246 1.1.2.1 minoura
247 1.1.2.1 minoura return -1;
248 1.1.2.1 minoura }
249 1.1.2.1 minoura
250 1.1.2.1 minoura int
251 1.1.2.1 minoura intio_map_free_region(parent, ia)
252 1.1.2.1 minoura struct device *parent;
253 1.1.2.1 minoura struct intio_attach_args *ia;
254 1.1.2.1 minoura {
255 1.1.2.1 minoura struct intio_softc *sc = (struct intio_softc*) parent;
256 1.1.2.1 minoura struct extent *map = sc->sc_map;
257 1.1.2.1 minoura
258 1.1.2.1 minoura extent_free (map, ia->ia_addr, ia->ia_size, 0);
259 1.1.2.1 minoura #ifdef DEBUG
260 1.1.2.1 minoura extent_print (map);
261 1.1.2.1 minoura #endif
262 1.1.2.1 minoura return 0;
263 1.1.2.1 minoura }
264 1.1.2.1 minoura
265 1.1.2.1 minoura void
266 1.1.2.1 minoura intio_alloc_system_ports(sc)
267 1.1.2.1 minoura struct intio_softc *sc;
268 1.1.2.1 minoura {
269 1.1.2.1 minoura extent_alloc_region (sc->sc_map, INTIO_SYSPORT, 16, 0);
270 1.1.2.1 minoura }
271 1.1.2.1 minoura
272 1.1.2.1 minoura
273 1.1.2.1 minoura /*
274 1.1.2.1 minoura * intio bus space stuff.
275 1.1.2.1 minoura */
276 1.1.2.1 minoura static int
277 1.1.2.1 minoura intio_bus_space_map(t, bpa, size, flags, bshp)
278 1.1.2.1 minoura bus_space_tag_t t;
279 1.1.2.1 minoura bus_addr_t bpa;
280 1.1.2.1 minoura bus_size_t size;
281 1.1.2.1 minoura int flags;
282 1.1.2.1 minoura bus_space_handle_t *bshp;
283 1.1.2.1 minoura {
284 1.1.2.1 minoura /*
285 1.1.2.1 minoura * Intio bus is mapped permanently.
286 1.1.2.1 minoura */
287 1.1.2.1 minoura *bshp = (bus_space_handle_t)
288 1.1.2.1 minoura ((u_int) bpa - PHYS_INTIODEV + intiobase);
289 1.1.2.1 minoura
290 1.1.2.1 minoura return (0);
291 1.1.2.1 minoura }
292 1.1.2.1 minoura
293 1.1.2.1 minoura static void
294 1.1.2.1 minoura intio_bus_space_unmap(t, bsh, size)
295 1.1.2.1 minoura bus_space_tag_t t;
296 1.1.2.1 minoura bus_space_handle_t bsh;
297 1.1.2.1 minoura bus_size_t size;
298 1.1.2.1 minoura {
299 1.1.2.1 minoura return;
300 1.1.2.1 minoura }
301 1.1.2.1 minoura
302 1.1.2.1 minoura static int
303 1.1.2.1 minoura intio_bus_space_subregion(t, bsh, offset, size, nbshp)
304 1.1.2.1 minoura bus_space_tag_t t;
305 1.1.2.1 minoura bus_space_handle_t bsh;
306 1.1.2.1 minoura bus_size_t offset, size;
307 1.1.2.1 minoura bus_space_handle_t *nbshp;
308 1.1.2.1 minoura {
309 1.1.2.1 minoura
310 1.1.2.1 minoura *nbshp = bsh + offset;
311 1.1.2.1 minoura return (0);
312 1.1.2.1 minoura }
313 1.1.2.1 minoura
314 1.1.2.1 minoura
315 1.1.2.1 minoura /*
316 1.1.2.1 minoura * interrupt handler
317 1.1.2.1 minoura */
318 1.1.2.1 minoura int
319 1.1.2.1 minoura intio_intr_establish (vector, name, handler, arg)
320 1.1.2.1 minoura int vector;
321 1.1.2.1 minoura const char *name; /* XXX */
322 1.1.2.1 minoura intio_intr_handler_t handler;
323 1.1.2.1 minoura void *arg;
324 1.1.2.1 minoura {
325 1.1.2.1 minoura if (vector < 16)
326 1.1.2.1 minoura panic ("Invalid interrupt vector");
327 1.1.2.1 minoura if (iiv[vector].iiv_handler)
328 1.1.2.1 minoura return EBUSY;
329 1.1.2.1 minoura iiv[vector].iiv_handler = handler;
330 1.1.2.1 minoura iiv[vector].iiv_arg = arg;
331 1.1.2.1 minoura
332 1.1.2.1 minoura return 0;
333 1.1.2.1 minoura }
334 1.1.2.1 minoura
335 1.1.2.1 minoura int
336 1.1.2.1 minoura intio_intr_disestablish (vector, arg)
337 1.1.2.1 minoura int vector;
338 1.1.2.1 minoura void *arg;
339 1.1.2.1 minoura {
340 1.1.2.1 minoura if (iiv[vector].iiv_handler == 0 || iiv[vector].iiv_arg != arg)
341 1.1.2.1 minoura return EINVAL;
342 1.1.2.1 minoura iiv[vector].iiv_handler = 0;
343 1.1.2.1 minoura iiv[vector].iiv_arg = 0;
344 1.1.2.1 minoura
345 1.1.2.1 minoura return 0;
346 1.1.2.1 minoura }
347 1.1.2.1 minoura
348 1.1.2.1 minoura int
349 1.1.2.1 minoura intio_intr (frame)
350 1.1.2.1 minoura struct frame *frame;
351 1.1.2.1 minoura {
352 1.1.2.1 minoura int vector = frame->f_vector / 4;
353 1.1.2.1 minoura
354 1.1.2.1 minoura /* CAUTION: HERE WE ARE IN SPLHIGH() */
355 1.1.2.1 minoura /* LOWER TO APPROPRIATE IPL AT VERY FIRST IN THE HANDLER!! */
356 1.1.2.1 minoura
357 1.1.2.1 minoura if (iiv[vector].iiv_handler == 0) {
358 1.1.2.1 minoura printf ("Stray interrupt: %d type %x\n", vector, frame->f_format);
359 1.1.2.1 minoura return 0;
360 1.1.2.1 minoura }
361 1.1.2.1 minoura
362 1.1.2.1 minoura return (*(iiv[vector].iiv_handler)) (iiv[vector].iiv_arg);
363 1.1.2.1 minoura }
364