vsbus.c revision 1.6 1 1.6 ragge /* $NetBSD: vsbus.c,v 1.6 1997/03/22 23:05:31 ragge Exp $ */
2 1.1 ragge /*
3 1.1 ragge * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
4 1.1 ragge * All rights reserved.
5 1.1 ragge *
6 1.1 ragge * This code is derived from software contributed to Ludd by Bertram Barth.
7 1.1 ragge *
8 1.1 ragge * Redistribution and use in source and binary forms, with or without
9 1.1 ragge * modification, are permitted provided that the following conditions
10 1.1 ragge * are met:
11 1.1 ragge * 1. Redistributions of source code must retain the above copyright
12 1.1 ragge * notice, this list of conditions and the following disclaimer.
13 1.1 ragge * 2. Redistributions in binary form must reproduce the above copyright
14 1.1 ragge * notice, this list of conditions and the following disclaimer in the
15 1.1 ragge * documentation and/or other materials provided with the distribution.
16 1.1 ragge * 3. All advertising materials mentioning features or use of this software
17 1.1 ragge * must display the following acknowledgement:
18 1.1 ragge * This product includes software developed at Ludd, University of
19 1.1 ragge * Lule}, Sweden and its contributors.
20 1.1 ragge * 4. The name of the author may not be used to endorse or promote products
21 1.1 ragge * derived from this software without specific prior written permission
22 1.1 ragge *
23 1.1 ragge * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 1.1 ragge * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 1.1 ragge * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 1.1 ragge * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 1.1 ragge * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 1.1 ragge * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 1.1 ragge * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 1.1 ragge * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 1.1 ragge * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 1.1 ragge * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 1.1 ragge */
34 1.1 ragge
35 1.1 ragge #include <sys/param.h>
36 1.1 ragge #include <sys/systm.h>
37 1.1 ragge #include <sys/buf.h>
38 1.1 ragge #include <sys/conf.h>
39 1.1 ragge #include <sys/file.h>
40 1.1 ragge #include <sys/ioctl.h>
41 1.1 ragge #include <sys/proc.h>
42 1.1 ragge #include <sys/user.h>
43 1.1 ragge #include <sys/map.h>
44 1.1 ragge #include <sys/device.h>
45 1.1 ragge #include <sys/dkstat.h>
46 1.1 ragge #include <sys/disklabel.h>
47 1.1 ragge #include <sys/syslog.h>
48 1.1 ragge #include <sys/stat.h>
49 1.1 ragge
50 1.1 ragge #include <machine/pte.h>
51 1.1 ragge #include <machine/sid.h>
52 1.1 ragge #include <machine/scb.h>
53 1.1 ragge #include <machine/cpu.h>
54 1.1 ragge #include <machine/trap.h>
55 1.1 ragge #include <machine/nexus.h>
56 1.1 ragge
57 1.1 ragge #include <machine/uvax.h>
58 1.1 ragge #include <machine/ka410.h>
59 1.1 ragge #include <machine/ka43.h>
60 1.1 ragge
61 1.1 ragge #include <machine/vsbus.h>
62 1.1 ragge
63 1.1 ragge #define trace(x)
64 1.1 ragge #define debug(x)
65 1.1 ragge
66 1.1 ragge int vsbus_match __P((struct device *, void *, void *));
67 1.1 ragge void vsbus_attach __P((struct device *, struct device *, void *));
68 1.2 cgd int vsbus_print __P((void *, const char *));
69 1.1 ragge
70 1.1 ragge void ka410_attach __P((struct device *, struct device *, void *));
71 1.1 ragge void ka43_attach __P((struct device *, struct device *, void *));
72 1.1 ragge
73 1.1 ragge struct cfdriver vsbus_cd = {
74 1.1 ragge NULL, "vsbus", DV_DULL
75 1.1 ragge };
76 1.1 ragge struct cfattach vsbus_ca = {
77 1.1 ragge sizeof(struct device), vsbus_match, vsbus_attach
78 1.1 ragge };
79 1.1 ragge
80 1.1 ragge /*
81 1.1 ragge void vsbus_intr_register __P((struct confargs *ca, int (*)(void*), void*));
82 1.1 ragge void vsbus_intr_unregister __P((struct confargs *));
83 1.1 ragge */
84 1.1 ragge
85 1.1 ragge void vsbus_intr_dispatch __P((int i));
86 1.1 ragge
87 1.1 ragge #define VSBUS_MAXDEVS 8
88 1.1 ragge #define VSBUS_MAXINTR 8
89 1.1 ragge
90 1.1 ragge struct confargs *vsbus_devs = NULL;
91 1.1 ragge
92 1.6 ragge #ifdef VAX410
93 1.1 ragge struct confargs ka410_devs[] = {
94 1.1 ragge /* name intslot intpri intvec intbit ioaddr */
95 1.1 ragge { "dc", 7, 7, 0x2C0, (1<<7), KA410_SER_BASE,
96 1.1 ragge 6, 6, 0x2C4, (1<<6), 0x01, },
97 1.1 ragge { "dc (xmit)", 6, 6, 0x2C4, (1<<6), KA410_SER_BASE, },
98 1.1 ragge { "le", 5, 5, 0x250, (1<<5), KA410_LAN_BASE,
99 1.1 ragge KA410_NWA_BASE, 0x00, },
100 1.1 ragge { "ncr", 1, 1, 0x3F8, (1<<1), KA410_SCS_BASE,
101 1.1 ragge KA410_SCS_DADR, KA410_SCS_DCNT, KA410_SCS_DDIR,
102 1.1 ragge KA410_DMA_BASE, KA410_DMA_SIZE, 0x00, 0x07, },
103 1.1 ragge { "hdc", 0, 0, 0x3FC, (1<<0), KA410_DKC_BASE,
104 1.1 ragge 0, 0, 0,
105 1.1 ragge KA410_DMA_BASE, KA410_DMA_SIZE, 0x00, },
106 1.1 ragge #if 0
107 1.1 ragge { "dc (recv)", 7, 7, 0x2C0, (1<<7), KA410_SER_BASE, },
108 1.1 ragge { "dc (xmit)", 6, 6, 0x2C4, (1<<6), KA410_SER_BASE, },
109 1.1 ragge { "hdc9224", 0, 0, 0x3FC, (1<<0), KA410_DKC_BASE, },
110 1.1 ragge { "ncr5380", 1, 1, 0x3F8, (1<<1), KA410_SCS_BASE, },
111 1.1 ragge { "am7990", 5, 5, 0x250, (1<<5), KA410_LAN_BASE, },
112 1.1 ragge { "NETOPT", 4, 4, 0x254, (1<<4), KA410_LAN_BASE, },
113 1.1 ragge #endif
114 1.1 ragge { "" },
115 1.1 ragge };
116 1.6 ragge
117 1.6 ragge /*
118 1.6 ragge * It would be better if we could use the (provided) system config
119 1.6 ragge * information for each CPU instead of this.
120 1.6 ragge */
121 1.6 ragge struct confargs ka420_devs[] = {
122 1.6 ragge { "le", 5, 5, 0x250, (1<<5), KA410_LAN_BASE,
123 1.6 ragge KA410_NWA_BASE, 0x00, },
124 1.6 ragge { "ncr", 1, 1, 0x3F8, (1<<1), KA410_SCS_BASE,
125 1.6 ragge KA410_SCS_DADR, KA410_SCS_DCNT, KA410_SCS_DDIR,
126 1.6 ragge KA410_DMA_BASE, KA410_DMA_SIZE, 0x00, 0x07, },
127 1.6 ragge { "ncr", 0, 0, 0x3FC, (1<<0), 0x200C0180,
128 1.6 ragge 0x200C01A0, 0x200C01C0, 0x200C01C4,
129 1.6 ragge KA410_DMA_BASE, KA410_DMA_SIZE, 0x00, 0x07, },
130 1.6 ragge { "" },
131 1.6 ragge };
132 1.1 ragge #endif
133 1.1 ragge
134 1.1 ragge #ifdef VAX43
135 1.1 ragge struct confargs ka43_devs[] = {
136 1.1 ragge /* name intslot intpri intvec intbit ioaddr */
137 1.1 ragge { "dc", 7, 7, 0x2C0, (1<<7), KA43_SER_BASE,
138 1.1 ragge 6, 6, 0x2C4, (1<<6), 0x01, },
139 1.1 ragge { "dc (xmit)", 6, 6, 0x2C4, (1<<6), KA43_SER_BASE, },
140 1.1 ragge { "le", 5, 5, 0x250, (1<<5), KA43_LAN_BASE,
141 1.1 ragge KA43_NWA_BASE, 0x00, },
142 1.1 ragge { "ncr", 1, 1, 0x3F8, (1<<1), KA43_SC1_BASE,
143 1.1 ragge KA43_SC1_DADR, KA43_SC1_DCNT, KA43_SC1_DDIR,
144 1.1 ragge KA43_DMA_BASE, KA43_DMA_SIZE, 0x01, 0x06, },
145 1.1 ragge { "ncr", 0, 0, 0x3FC, (1<<0), KA43_SC2_BASE,
146 1.1 ragge KA43_SC2_DADR, KA43_SC2_DCNT, KA43_SC2_DDIR,
147 1.1 ragge KA43_DMA_BASE, KA43_DMA_SIZE, 0x01, 0x06, },
148 1.1 ragge #if 0
149 1.1 ragge { "le (2nd)", 4, 4, 0x254, (1<<4), 0x???, },
150 1.1 ragge { "NETOPT", 4, 4, 0x254, (1<<4), 0x???, },
151 1.1 ragge #endif
152 1.1 ragge { "" },
153 1.1 ragge };
154 1.1 ragge #endif
155 1.1 ragge
156 1.1 ragge int
157 1.1 ragge vsbus_print(aux, name)
158 1.1 ragge void *aux;
159 1.2 cgd const char *name;
160 1.1 ragge {
161 1.1 ragge struct confargs *ca = aux;
162 1.1 ragge
163 1.1 ragge trace(("vsbus_print(%x, %s)\n", ca->ca_name, name));
164 1.1 ragge
165 1.1 ragge if (name) {
166 1.4 christos printf ("device %s at %s", ca->ca_name, name);
167 1.1 ragge return (UNSUPP);
168 1.1 ragge }
169 1.1 ragge return (UNCONF);
170 1.1 ragge }
171 1.1 ragge
172 1.1 ragge int
173 1.1 ragge vsbus_match(parent, cf, aux)
174 1.1 ragge struct device *parent;
175 1.1 ragge void *cf;
176 1.1 ragge void *aux;
177 1.1 ragge {
178 1.1 ragge struct bp_conf *bp = aux;
179 1.1 ragge
180 1.1 ragge trace(("vsbus_match: bp->type = \"%s\"\n", bp->type));
181 1.1 ragge
182 1.1 ragge if (strcmp(bp->type, "vsbus"))
183 1.1 ragge return 0;
184 1.1 ragge /*
185 1.1 ragge * on machines which can have it, the vsbus is always there
186 1.1 ragge */
187 1.1 ragge if ((vax_bustype & VAX_VSBUS) == 0)
188 1.1 ragge return (0);
189 1.1 ragge
190 1.1 ragge return (1);
191 1.1 ragge }
192 1.1 ragge
193 1.1 ragge #if 1 /*------------------------------------------------------------*/
194 1.1 ragge #if 1
195 1.1 ragge #define REG(name) short name; short X##name##X;
196 1.1 ragge #else
197 1.1 ragge #define REG(name) int name;
198 1.1 ragge #endif
199 1.1 ragge static volatile struct {/* base address of DZ-controller: 0x200A0000 */
200 1.1 ragge REG(csr); /* 00 Csr: control/status register */
201 1.1 ragge REG(rbuf); /* 04 Rbuf/Lpr: receive buffer/line param reg. */
202 1.1 ragge REG(tcr); /* 08 Tcr: transmit console register */
203 1.1 ragge REG(tdr); /* 0C Msr/Tdr: modem status reg/transmit data reg */
204 1.1 ragge REG(lpr0); /* 10 Lpr0: */
205 1.1 ragge REG(lpr1); /* 14 Lpr0: */
206 1.1 ragge REG(lpr2); /* 18 Lpr0: */
207 1.1 ragge REG(lpr3); /* 1C Lpr0: */
208 1.1 ragge } *dz = (void*)0x200A0000;
209 1.1 ragge extern int dzcnrint();
210 1.1 ragge extern int dzcntint();
211 1.1 ragge int hardclock_count = 0;
212 1.1 ragge int
213 1.1 ragge ka410_consintr_enable()
214 1.1 ragge {
215 1.1 ragge vsbus_intr_enable(&ka410_devs[0]);
216 1.1 ragge vsbus_intr_enable(&ka410_devs[1]);
217 1.1 ragge }
218 1.1 ragge
219 1.1 ragge int
220 1.1 ragge ka410_consRecv_intr(p)
221 1.1 ragge void *p;
222 1.1 ragge {
223 1.4 christos /* printf("ka410_consRecv_intr: hc-count=%d\n", hardclock_count); */
224 1.1 ragge dzcnrint();
225 1.4 christos /* printf("gencnrint() returned.\n"); */
226 1.1 ragge return(0);
227 1.1 ragge }
228 1.1 ragge
229 1.1 ragge int
230 1.1 ragge ka410_consXmit_intr(p)
231 1.1 ragge void *p;
232 1.1 ragge {
233 1.4 christos /* printf("ka410_consXmit_intr: hc-count=%d\n", hardclock_count); */
234 1.1 ragge dzcntint();
235 1.4 christos /* printf("gencntint() returned.\n"); */
236 1.1 ragge return(0);
237 1.1 ragge }
238 1.1 ragge #endif /*------------------------------------------------------------*/
239 1.1 ragge
240 1.1 ragge void
241 1.1 ragge vsbus_attach(parent, self, aux)
242 1.1 ragge struct device *parent, *self;
243 1.1 ragge void *aux;
244 1.1 ragge {
245 1.1 ragge struct confargs *ca;
246 1.1 ragge int i;
247 1.1 ragge
248 1.4 christos printf("\n");
249 1.1 ragge trace (("vsbus_attach()\n"));
250 1.1 ragge
251 1.1 ragge switch (vax_boardtype) {
252 1.6 ragge case VAX_BTYP_420:
253 1.6 ragge vsbus_devs = ka420_devs;
254 1.6 ragge break;
255 1.6 ragge
256 1.1 ragge case VAX_BTYP_410:
257 1.1 ragge vsbus_devs = ka410_devs;
258 1.1 ragge break;
259 1.1 ragge
260 1.1 ragge case VAX_BTYP_43:
261 1.1 ragge case VAX_BTYP_46:
262 1.1 ragge case VAX_BTYP_49:
263 1.5 ragge #ifdef VAX43
264 1.1 ragge vsbus_devs = ka43_devs;
265 1.5 ragge #endif
266 1.1 ragge break;
267 1.1 ragge
268 1.1 ragge default:
269 1.4 christos printf ("unsupported boardtype 0x%x in vsbus_attach()\n",
270 1.1 ragge vax_boardtype);
271 1.1 ragge return;
272 1.1 ragge }
273 1.1 ragge
274 1.1 ragge /*
275 1.1 ragge * first setup interrupt-table, so that devices can register
276 1.1 ragge * their interrupt-routines...
277 1.1 ragge */
278 1.1 ragge vsbus_intr_setup();
279 1.1 ragge
280 1.1 ragge /*
281 1.1 ragge * now check for all possible devices on this "bus"
282 1.1 ragge */
283 1.1 ragge for (i=0; i<VSBUS_MAXDEVS; i++) {
284 1.1 ragge ca = &vsbus_devs[i];
285 1.1 ragge if (*ca->ca_name == '\0')
286 1.1 ragge break;
287 1.1 ragge config_found(self, (void*)ca, vsbus_print);
288 1.1 ragge }
289 1.1 ragge
290 1.1 ragge /*
291 1.1 ragge * as long as there's no working DZ-driver, we use this dummy
292 1.1 ragge */
293 1.1 ragge vsbus_intr_register(&ka410_devs[0], ka410_consRecv_intr, NULL);
294 1.1 ragge vsbus_intr_register(&ka410_devs[1], ka410_consXmit_intr, NULL);
295 1.1 ragge }
296 1.1 ragge
297 1.1 ragge #define VSBUS_MAX_INTR 8 /* 64? */
298 1.1 ragge /*
299 1.1 ragge * interrupt service routines are given an int as argument, which is
300 1.1 ragge * pushed onto stack as LITERAL. Thus the value is between 0-63.
301 1.1 ragge * This array of 64 might be oversized for now, but it's all which
302 1.1 ragge * ever will be possible.
303 1.1 ragge */
304 1.1 ragge struct vsbus_ivec {
305 1.1 ragge struct ivec_dsp intr_vec; /* this is referenced in SCB */
306 1.1 ragge int intr_count; /* keep track of interrupts */
307 1.1 ragge int intr_flags; /* valid, etc. */
308 1.1 ragge void (*enab)(int); /* enable interrupt */
309 1.1 ragge void (*disab)(int); /* disable interrupt */
310 1.1 ragge void (*prep)(int); /* need pre-processing? */
311 1.1 ragge int (*handler)(void*); /* isr-routine to call */
312 1.1 ragge void *hndlarg; /* args to this routine */
313 1.1 ragge void (*postp)(int); /* need post-processing? */
314 1.1 ragge } vsbus_ivtab[VSBUS_MAX_INTR];
315 1.1 ragge
316 1.1 ragge /*
317 1.1 ragge *
318 1.1 ragge */
319 1.1 ragge int
320 1.1 ragge vsbus_intr_setup()
321 1.1 ragge {
322 1.1 ragge int i;
323 1.1 ragge struct vsbus_ivec *ip;
324 1.1 ragge extern struct ivec_dsp idsptch; /* subr.s */
325 1.1 ragge
326 1.1 ragge for (i=0; i<VSBUS_MAX_INTR; i++) {
327 1.1 ragge ip = &vsbus_ivtab[i];
328 1.1 ragge bcopy(&idsptch, &ip->intr_vec, sizeof(struct ivec_dsp));
329 1.1 ragge ip->intr_vec.pushlarg = i;
330 1.1 ragge ip->intr_vec.hoppaddr = vsbus_intr_dispatch;
331 1.1 ragge ip->intr_count = 0;
332 1.1 ragge ip->intr_flags = 0;
333 1.1 ragge ip->enab = NULL;
334 1.1 ragge ip->disab = NULL;
335 1.1 ragge ip->postp = NULL;
336 1.1 ragge }
337 1.1 ragge switch (vax_boardtype) {
338 1.1 ragge case VAX_BTYP_410:
339 1.1 ragge case VAX_BTYP_420:
340 1.1 ragge case VAX_BTYP_43:
341 1.1 ragge case VAX_BTYP_46:
342 1.1 ragge case VAX_BTYP_49:
343 1.1 ragge ka410_intr_setup();
344 1.1 ragge return(0);
345 1.1 ragge default:
346 1.4 christos printf("unsupported board-type 0x%x in vsbus_intr_setup()\n",
347 1.1 ragge vax_boardtype);
348 1.1 ragge return(1);
349 1.1 ragge }
350 1.1 ragge }
351 1.1 ragge
352 1.1 ragge int
353 1.1 ragge vsbus_intr_register(ca, handler, arg)
354 1.1 ragge struct confargs *ca;
355 1.1 ragge int (*handler)(void*);
356 1.1 ragge void *arg;
357 1.1 ragge {
358 1.1 ragge /* struct device *dev = arg; */
359 1.1 ragge int i = ca->ca_intslot;
360 1.1 ragge struct vsbus_ivec *ip = &vsbus_ivtab[i];
361 1.1 ragge
362 1.1 ragge trace (("vsbus_intr_register(%s/%d)\n", ca->ca_name, ca->ca_intslot));
363 1.1 ragge
364 1.1 ragge ip->handler = handler;
365 1.1 ragge ip->hndlarg = arg;
366 1.1 ragge }
367 1.1 ragge
368 1.1 ragge int
369 1.1 ragge vsbus_intr_enable(ca)
370 1.1 ragge struct confargs *ca;
371 1.1 ragge {
372 1.1 ragge int i = ca->ca_intslot;
373 1.1 ragge struct vsbus_ivec *ip = &vsbus_ivtab[i];
374 1.1 ragge
375 1.1 ragge trace (("vsbus_intr_enable(%s/%d)\n", ca->ca_name, ca->ca_intslot));
376 1.1 ragge
377 1.1 ragge /* XXX check for valid handler etc. !!! */
378 1.1 ragge if (ip->handler == NULL) {
379 1.4 christos printf("interrupts for \"%s\"(%d) not enabled: null-handler\n",
380 1.1 ragge ca->ca_name, ca->ca_intslot);
381 1.1 ragge return;
382 1.1 ragge }
383 1.1 ragge
384 1.1 ragge ip->enab(i);
385 1.1 ragge }
386 1.1 ragge
387 1.1 ragge int
388 1.1 ragge vsbus_intr_disable(ca)
389 1.1 ragge struct confargs *ca;
390 1.1 ragge {
391 1.1 ragge int i = ca->ca_intslot;
392 1.1 ragge struct vsbus_ivec *ip = &vsbus_ivtab[i];
393 1.1 ragge
394 1.1 ragge trace (("vsbus_intr_disable(%s/%d)\n", ca->ca_name, i));
395 1.1 ragge
396 1.1 ragge ip->disab(i);
397 1.1 ragge }
398 1.1 ragge
399 1.1 ragge int
400 1.1 ragge vsbus_intr_unregister(ca)
401 1.1 ragge struct confargs *ca;
402 1.1 ragge {
403 1.1 ragge int i = ca->ca_intslot;
404 1.1 ragge struct vsbus_ivec *ip = &vsbus_ivtab[i];
405 1.1 ragge
406 1.1 ragge trace (("vsbus_intr_unregister(%s/%d)\n", ca->ca_name, i));
407 1.1 ragge
408 1.1 ragge ip->handler = NULL;
409 1.1 ragge ip->hndlarg = NULL;
410 1.1 ragge }
411 1.1 ragge
412 1.1 ragge void
413 1.1 ragge vsbus_intr_dispatch(i)
414 1.1 ragge register int i;
415 1.1 ragge {
416 1.1 ragge register struct vsbus_ivec *ip = &vsbus_ivtab[i];
417 1.1 ragge
418 1.1 ragge trace (("vsbus_intr_dispatch(%d)", i));
419 1.1 ragge
420 1.1 ragge if (i < VSBUS_MAX_INTR && ip->handler != NULL) {
421 1.1 ragge ip->intr_count++;
422 1.1 ragge debug (("intr-count[%d] = %d\n", i, ip->intr_count));
423 1.1 ragge (ip->handler)(ip->hndlarg);
424 1.1 ragge if (ip->postp)
425 1.1 ragge (ip->postp)(i);
426 1.1 ragge return;
427 1.1 ragge }
428 1.1 ragge
429 1.1 ragge if (i < 0 || i >= VSBUS_MAX_INTR) {
430 1.4 christos printf ("stray interrupt %d on vsbus.\n", i);
431 1.1 ragge return;
432 1.1 ragge }
433 1.1 ragge
434 1.1 ragge if (!ip->handler) {
435 1.4 christos printf ("unhandled interrupt %d on vsbus.\n", i);
436 1.1 ragge return;
437 1.1 ragge }
438 1.1 ragge }
439 1.1 ragge
440 1.1 ragge /*
441 1.1 ragge * These addresses are invalid and will be updated/corrected by
442 1.1 ragge * ka410_intr_setup(), but having them this way helps debugging
443 1.1 ragge */
444 1.1 ragge static volatile u_char *ka410_intmsk = (void*)KA410_INTMSK;
445 1.1 ragge static volatile u_char *ka410_intreq = (void*)KA410_INTREQ;
446 1.1 ragge static volatile u_char *ka410_intclr = (void*)KA410_INTCLR;
447 1.1 ragge
448 1.1 ragge static void
449 1.1 ragge ka410_intr_enable(i)
450 1.1 ragge int i;
451 1.1 ragge {
452 1.1 ragge trace (("ka410_intr_enable(%d)\n", i));
453 1.1 ragge *ka410_intmsk |= (1<<i);
454 1.1 ragge }
455 1.1 ragge
456 1.1 ragge static void
457 1.1 ragge ka410_intr_disable(i)
458 1.1 ragge int i;
459 1.1 ragge {
460 1.1 ragge trace (("ka410_intr_disable(%d)\n", i));
461 1.1 ragge *ka410_intmsk &= ~(1<<i);
462 1.1 ragge }
463 1.1 ragge
464 1.1 ragge static void
465 1.1 ragge ka410_intr_clear(i)
466 1.1 ragge int i;
467 1.1 ragge {
468 1.1 ragge trace (("ka410_intr_clear(%d)\n", i));
469 1.1 ragge *ka410_intclr = (1<<i);
470 1.1 ragge }
471 1.1 ragge
472 1.1 ragge ka410_intr_setup()
473 1.1 ragge {
474 1.1 ragge int i;
475 1.1 ragge struct vsbus_ivec *ip;
476 1.1 ragge void **scbP = (void*)scb;
477 1.1 ragge
478 1.1 ragge trace (("ka410_intr_setup()\n"));
479 1.1 ragge
480 1.1 ragge ka410_intmsk = (void*)uvax_phys2virt(KA410_INTMSK);
481 1.1 ragge ka410_intreq = (void*)uvax_phys2virt(KA410_INTREQ);
482 1.1 ragge ka410_intclr = (void*)uvax_phys2virt(KA410_INTCLR);
483 1.1 ragge
484 1.1 ragge *ka410_intmsk = 0; /* disable all interrupts */
485 1.1 ragge *ka410_intclr = 0xFF; /* clear all old interrupts */
486 1.1 ragge
487 1.1 ragge /*
488 1.1 ragge * insert the VS2000-specific routines into ivec-table...
489 1.1 ragge */
490 1.1 ragge for (i=0; i<8; i++) {
491 1.1 ragge ip = &vsbus_ivtab[i];
492 1.1 ragge ip->enab = ka410_intr_enable;
493 1.1 ragge ip->disab = ka410_intr_disable;
494 1.1 ragge /* ip->postp = ka410_intr_clear; bertram XXX */
495 1.1 ragge }
496 1.1 ragge /*
497 1.1 ragge * ...and register the interrupt-vectors in SCB
498 1.1 ragge */
499 1.1 ragge scbP[IVEC_DC/4] = &vsbus_ivtab[0].intr_vec;
500 1.1 ragge scbP[IVEC_SC/4] = &vsbus_ivtab[1].intr_vec;
501 1.1 ragge scbP[IVEC_VS/4] = &vsbus_ivtab[2].intr_vec;
502 1.1 ragge scbP[IVEC_VF/4] = &vsbus_ivtab[3].intr_vec;
503 1.1 ragge scbP[IVEC_NS/4] = &vsbus_ivtab[4].intr_vec;
504 1.1 ragge scbP[IVEC_NP/4] = &vsbus_ivtab[5].intr_vec;
505 1.1 ragge scbP[IVEC_ST/4] = &vsbus_ivtab[6].intr_vec;
506 1.1 ragge scbP[IVEC_SR/4] = &vsbus_ivtab[7].intr_vec;
507 1.1 ragge }
508 1.1 ragge
509 1.1 ragge /*
510 1.1 ragge *
511 1.1 ragge *
512 1.1 ragge */
513 1.1 ragge
514 1.1 ragge static volatile struct dma_lock {
515 1.1 ragge int dl_locked;
516 1.1 ragge int dl_wanted;
517 1.1 ragge void *dl_owner;
518 1.1 ragge int dl_count;
519 1.1 ragge } dmalock = { 0, 0, NULL, 0 };
520 1.1 ragge
521 1.1 ragge int
522 1.1 ragge vsbus_lockDMA(ca)
523 1.1 ragge struct confargs *ca;
524 1.1 ragge {
525 1.1 ragge while (dmalock.dl_locked) {
526 1.1 ragge dmalock.dl_wanted++;
527 1.1 ragge sleep((caddr_t)&dmalock, PRIBIO); /* PLOCK or PRIBIO ? */
528 1.1 ragge dmalock.dl_wanted--;
529 1.1 ragge }
530 1.1 ragge dmalock.dl_locked++;
531 1.1 ragge dmalock.dl_owner = ca;
532 1.1 ragge
533 1.1 ragge /*
534 1.1 ragge * no checks yet, no timeouts, nothing...
535 1.1 ragge */
536 1.1 ragge
537 1.1 ragge #ifdef DEBUG
538 1.1 ragge if ((++dmalock.dl_count % 1000) == 0)
539 1.4 christos printf("%d locks, owner: %s\n", dmalock.dl_count, ca->ca_name);
540 1.1 ragge #endif
541 1.1 ragge return (0);
542 1.1 ragge }
543 1.1 ragge
544 1.1 ragge int
545 1.1 ragge vsbus_unlockDMA(ca)
546 1.1 ragge struct confargs *ca;
547 1.1 ragge {
548 1.1 ragge if (dmalock.dl_locked != 1 || dmalock.dl_owner != ca) {
549 1.4 christos printf("locking-problem: %d, %s\n", dmalock.dl_locked,
550 1.1 ragge (dmalock.dl_owner ? dmalock.dl_owner : "null"));
551 1.1 ragge dmalock.dl_locked = 0;
552 1.1 ragge return (-1);
553 1.1 ragge }
554 1.1 ragge dmalock.dl_owner = NULL;
555 1.1 ragge dmalock.dl_locked = 0;
556 1.1 ragge if (dmalock.dl_wanted) {
557 1.1 ragge wakeup((caddr_t)&dmalock);
558 1.1 ragge }
559 1.1 ragge return (0);
560 1.1 ragge }
561 1.1 ragge
562 1.1 ragge /*----------------------------------------------------------------------*/
563 1.1 ragge #if 0
564 1.1 ragge /*
565 1.1 ragge * small set of routines needed for mapping when doing pseudo-DMA,
566 1.1 ragge * quasi-DMA or virtual-DMA (choose whatever name you like).
567 1.1 ragge *
568 1.1 ragge * Once I know how VS3100 is doing real DMA (I hope it does), this
569 1.1 ragge * should be rewritten to present a general interface...
570 1.1 ragge *
571 1.1 ragge */
572 1.1 ragge
573 1.1 ragge extern u_long uVAX_physmap;
574 1.1 ragge
575 1.1 ragge u_long
576 1.1 ragge vsdma_mapin(bp, len)
577 1.1 ragge struct buf *bp;
578 1.1 ragge int len;
579 1.1 ragge {
580 1.1 ragge pt_entry_t *pte; /* pointer to Page-Table-Entry */
581 1.1 ragge struct pcb *pcb; /* pointer to Process-Controll-Block */
582 1.1 ragge pt_entry_t *xpte;
583 1.1 ragge caddr_t addr;
584 1.1 ragge int pgoff; /* offset into 1st page */
585 1.1 ragge int pgcnt; /* number of pages needed */
586 1.1 ragge int pfnum;
587 1.1 ragge int i;
588 1.1 ragge
589 1.1 ragge trace(("mapin(bp=%x, bp->data=%x)\n", bp, bp->b_data));
590 1.1 ragge
591 1.1 ragge addr = bp->b_data;
592 1.1 ragge pgoff = (int)bp->b_data & PGOFSET; /* get starting offset */
593 1.1 ragge pgcnt = btoc(bp->b_bcount + pgoff) + 1; /* one more than needed */
594 1.1 ragge
595 1.1 ragge /*
596 1.1 ragge * Get a pointer to the pte pointing out the first virtual address.
597 1.1 ragge * Use different ways in kernel and user space.
598 1.1 ragge */
599 1.1 ragge if ((bp->b_flags & B_PHYS) == 0) {
600 1.1 ragge pte = kvtopte(addr);
601 1.1 ragge } else {
602 1.1 ragge pcb = bp->b_proc->p_vmspace->vm_pmap.pm_pcb;
603 1.1 ragge pte = uvtopte(addr, pcb);
604 1.1 ragge }
605 1.1 ragge
606 1.1 ragge /*
607 1.1 ragge * When we are doing DMA to user space, be sure that all pages
608 1.1 ragge * we want to transfer to are mapped. WHY DO WE NEED THIS???
609 1.1 ragge * SHOULDN'T THEY ALWAYS BE MAPPED WHEN DOING THIS???
610 1.1 ragge */
611 1.1 ragge for (i=0; i<(pgcnt-1); i++) {
612 1.1 ragge if ((pte + i)->pg_pfn == 0) {
613 1.1 ragge int rv;
614 1.1 ragge rv = vm_fault(&bp->b_proc->p_vmspace->vm_map,
615 1.1 ragge (unsigned)addr + i * NBPG,
616 1.1 ragge VM_PROT_READ|VM_PROT_WRITE, FALSE);
617 1.1 ragge if (rv)
618 1.1 ragge panic("vs-DMA to nonexistent page, %d", rv);
619 1.1 ragge }
620 1.1 ragge }
621 1.1 ragge
622 1.1 ragge /*
623 1.1 ragge * now insert new mappings for this memory area into kernel's
624 1.1 ragge * mapping-table
625 1.1 ragge */
626 1.1 ragge xpte = kvtopte(uVAX_physmap);
627 1.1 ragge while (--pgcnt > 0) {
628 1.1 ragge pfnum = pte->pg_pfn;
629 1.1 ragge if (pfnum == 0)
630 1.1 ragge panic("vsbus: zero entry");
631 1.1 ragge *(int *)xpte++ = *(int *)pte++;
632 1.1 ragge }
633 1.1 ragge *(int *)xpte = 0; /* mark last mapped page as invalid! */
634 1.1 ragge
635 1.1 ragge debug(("uVAX: 0x%x\n", uVAX_physmap + pgoff));
636 1.1 ragge
637 1.1 ragge return (uVAX_physmap + pgoff); /* ??? */
638 1.1 ragge }
639 1.1 ragge #endif
640 1.1 ragge /*----------------------------------------------------------------------*/
641 1.1 ragge /*
642 1.1 ragge * Here follows some currently(?) unused stuff. Someday this should be removed
643 1.1 ragge */
644 1.1 ragge
645 1.1 ragge #if 0
646 1.1 ragge /*
647 1.1 ragge * Configure devices on VS2000/KA410 directly attached to vsbus
648 1.1 ragge */
649 1.1 ragge void
650 1.1 ragge ka410_attach(parent, self, aux)
651 1.1 ragge struct device *parent;
652 1.1 ragge struct device *self;
653 1.1 ragge void *aux;
654 1.1 ragge {
655 1.1 ragge struct confargs *ca;
656 1.1 ragge int i;
657 1.1 ragge
658 1.1 ragge for (i=0; i<KA410_MAXDEVS; i++) {
659 1.1 ragge ca = &ka410_devs[i];
660 1.1 ragge if (*ca->ca_name == '\0')
661 1.1 ragge break;
662 1.1 ragge config_found(self, (void*)ca, vsbus_print);
663 1.1 ragge }
664 1.1 ragge /*
665 1.1 ragge * as long as there's no real DZ-driver, we used this dummy
666 1.1 ragge */
667 1.1 ragge vsbus_intr_register(&ka410_devs[0], ka410_consRecv_intr, NULL);
668 1.1 ragge vsbus_intr_register(&ka410_devs[1], ka410_consXmit_intr, NULL);
669 1.1 ragge }
670 1.1 ragge
671 1.1 ragge #endif
672