vsbus.c revision 1.11 1 1.11 ragge /* $NetBSD: vsbus.c,v 1.11 1998/06/04 15:51:12 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.10 ragge #include "ioconf.h"
64 1.1 ragge
65 1.9 ragge int vsbus_match __P((struct device *, struct cfdata *, void *));
66 1.1 ragge void vsbus_attach __P((struct device *, struct device *, void *));
67 1.2 cgd int vsbus_print __P((void *, const char *));
68 1.1 ragge
69 1.1 ragge void ka410_attach __P((struct device *, struct device *, void *));
70 1.1 ragge void ka43_attach __P((struct device *, struct device *, void *));
71 1.1 ragge
72 1.1 ragge #define VSBUS_MAXINTR 8
73 1.1 ragge
74 1.10 ragge struct vsbus_softc {
75 1.10 ragge struct device sc_dev;
76 1.10 ragge struct ivec_dsp sc_dsp[VSBUS_MAXINTR];
77 1.10 ragge };
78 1.1 ragge
79 1.10 ragge struct cfattach vsbus_ca = {
80 1.10 ragge sizeof(struct vsbus_softc), vsbus_match, vsbus_attach
81 1.1 ragge };
82 1.6 ragge
83 1.10 ragge void vsbus_intr_setup __P((struct vsbus_softc *));
84 1.1 ragge
85 1.10 ragge #define VSBUS_MAXDEVS 8
86 1.1 ragge
87 1.1 ragge int
88 1.1 ragge vsbus_print(aux, name)
89 1.1 ragge void *aux;
90 1.2 cgd const char *name;
91 1.1 ragge {
92 1.10 ragge struct vsbus_attach_args *va = aux;
93 1.1 ragge
94 1.1 ragge if (name) {
95 1.10 ragge printf ("device %d at %s", va->va_type, name);
96 1.1 ragge return (UNSUPP);
97 1.1 ragge }
98 1.1 ragge return (UNCONF);
99 1.1 ragge }
100 1.1 ragge
101 1.1 ragge int
102 1.1 ragge vsbus_match(parent, cf, aux)
103 1.1 ragge struct device *parent;
104 1.9 ragge struct cfdata *cf;
105 1.1 ragge void *aux;
106 1.1 ragge {
107 1.1 ragge struct bp_conf *bp = aux;
108 1.1 ragge
109 1.1 ragge if (strcmp(bp->type, "vsbus"))
110 1.1 ragge return 0;
111 1.1 ragge /*
112 1.1 ragge * on machines which can have it, the vsbus is always there
113 1.1 ragge */
114 1.1 ragge if ((vax_bustype & VAX_VSBUS) == 0)
115 1.1 ragge return (0);
116 1.1 ragge
117 1.1 ragge return (1);
118 1.1 ragge }
119 1.1 ragge
120 1.1 ragge void
121 1.1 ragge vsbus_attach(parent, self, aux)
122 1.1 ragge struct device *parent, *self;
123 1.1 ragge void *aux;
124 1.1 ragge {
125 1.10 ragge struct vsbus_softc *sc = (void *)self;
126 1.10 ragge struct vsbus_attach_args va;
127 1.1 ragge
128 1.4 christos printf("\n");
129 1.1 ragge /*
130 1.1 ragge * first setup interrupt-table, so that devices can register
131 1.1 ragge * their interrupt-routines...
132 1.1 ragge */
133 1.10 ragge vsbus_intr_setup(sc);
134 1.1 ragge
135 1.1 ragge /*
136 1.1 ragge * now check for all possible devices on this "bus"
137 1.1 ragge */
138 1.10 ragge /* Always have network */
139 1.10 ragge va.va_type = INR_NP;
140 1.10 ragge config_found(self, &va, vsbus_print);
141 1.1 ragge
142 1.10 ragge /* Always have serial line */
143 1.10 ragge va.va_type = INR_SR;
144 1.10 ragge config_found(self, &va, vsbus_print);
145 1.11 ragge
146 1.11 ragge /* If sm_addr is set, a monochrome graphics adapter is found */
147 1.11 ragge if (sm_addr) {
148 1.11 ragge va.va_type = INR_VF;
149 1.11 ragge config_found(self, &va, vsbus_print);
150 1.11 ragge }
151 1.1 ragge }
152 1.1 ragge
153 1.10 ragge static void stray __P((int));
154 1.1 ragge
155 1.10 ragge static void
156 1.10 ragge stray(arg)
157 1.10 ragge int arg;
158 1.1 ragge {
159 1.10 ragge printf("stray interrupt nr %d.\n", arg);
160 1.1 ragge }
161 1.1 ragge
162 1.10 ragge static int inrs[] = {IVEC_DC, IVEC_SC, IVEC_VS, IVEC_VF,
163 1.10 ragge IVEC_NS, IVEC_NP, IVEC_ST, IVEC_SR};
164 1.1 ragge
165 1.10 ragge void
166 1.10 ragge vsbus_intr_setup(sc)
167 1.10 ragge struct vsbus_softc *sc;
168 1.1 ragge {
169 1.10 ragge extern struct ivec_dsp idsptch; /* subr.s */
170 1.10 ragge void **scbP = (void*)scb;
171 1.10 ragge int i;
172 1.1 ragge
173 1.10 ragge vs_cpu->vc_intmsk = 0; /* disable all interrupts */
174 1.10 ragge vs_cpu->vc_intclr = 0xFF; /* clear all old interrupts */
175 1.1 ragge
176 1.10 ragge for (i = 0; i < VSBUS_MAXINTR; i++) {
177 1.10 ragge bcopy(&idsptch, &sc->sc_dsp[i], sizeof(struct ivec_dsp));
178 1.10 ragge sc->sc_dsp[i].hoppaddr = stray;
179 1.10 ragge sc->sc_dsp[i].pushlarg = i;
180 1.10 ragge scbP[inrs[i]/4] = &sc->sc_dsp[i];
181 1.1 ragge }
182 1.1 ragge }
183 1.1 ragge
184 1.10 ragge void
185 1.10 ragge vsbus_intr_attach(nr, func, arg)
186 1.10 ragge int nr;
187 1.10 ragge void (*func)(int);
188 1.10 ragge int arg;
189 1.1 ragge {
190 1.10 ragge struct vsbus_softc *sc = vsbus_cd.cd_devs[0];
191 1.1 ragge
192 1.10 ragge sc->sc_dsp[nr].hoppaddr = func;
193 1.10 ragge sc->sc_dsp[nr].pushlarg = arg;
194 1.1 ragge }
195 1.1 ragge
196 1.10 ragge void
197 1.10 ragge vsbus_intr_enable(nr)
198 1.10 ragge int nr;
199 1.1 ragge {
200 1.10 ragge vs_cpu->vc_intclr = (1<<nr);
201 1.10 ragge vs_cpu->vc_intmsk |= (1<<nr);
202 1.1 ragge }
203 1.1 ragge
204 1.1 ragge void
205 1.10 ragge vsbus_intr_disable(nr)
206 1.10 ragge int nr;
207 1.1 ragge {
208 1.10 ragge vs_cpu->vc_intmsk = vs_cpu->vc_intmsk & ~(1<<nr);
209 1.1 ragge }
210 1.1 ragge
211 1.1 ragge /*
212 1.1 ragge *
213 1.1 ragge *
214 1.1 ragge */
215 1.1 ragge
216 1.1 ragge static volatile struct dma_lock {
217 1.1 ragge int dl_locked;
218 1.1 ragge int dl_wanted;
219 1.1 ragge void *dl_owner;
220 1.1 ragge int dl_count;
221 1.1 ragge } dmalock = { 0, 0, NULL, 0 };
222 1.1 ragge
223 1.1 ragge int
224 1.1 ragge vsbus_lockDMA(ca)
225 1.1 ragge struct confargs *ca;
226 1.1 ragge {
227 1.1 ragge while (dmalock.dl_locked) {
228 1.1 ragge dmalock.dl_wanted++;
229 1.1 ragge sleep((caddr_t)&dmalock, PRIBIO); /* PLOCK or PRIBIO ? */
230 1.1 ragge dmalock.dl_wanted--;
231 1.1 ragge }
232 1.1 ragge dmalock.dl_locked++;
233 1.1 ragge dmalock.dl_owner = ca;
234 1.1 ragge
235 1.1 ragge /*
236 1.1 ragge * no checks yet, no timeouts, nothing...
237 1.1 ragge */
238 1.1 ragge
239 1.1 ragge #ifdef DEBUG
240 1.1 ragge if ((++dmalock.dl_count % 1000) == 0)
241 1.4 christos printf("%d locks, owner: %s\n", dmalock.dl_count, ca->ca_name);
242 1.1 ragge #endif
243 1.1 ragge return (0);
244 1.1 ragge }
245 1.1 ragge
246 1.1 ragge int
247 1.1 ragge vsbus_unlockDMA(ca)
248 1.1 ragge struct confargs *ca;
249 1.1 ragge {
250 1.1 ragge if (dmalock.dl_locked != 1 || dmalock.dl_owner != ca) {
251 1.4 christos printf("locking-problem: %d, %s\n", dmalock.dl_locked,
252 1.10 ragge (char *)(dmalock.dl_owner ? dmalock.dl_owner : "null"));
253 1.1 ragge dmalock.dl_locked = 0;
254 1.1 ragge return (-1);
255 1.1 ragge }
256 1.1 ragge dmalock.dl_owner = NULL;
257 1.1 ragge dmalock.dl_locked = 0;
258 1.1 ragge if (dmalock.dl_wanted) {
259 1.1 ragge wakeup((caddr_t)&dmalock);
260 1.1 ragge }
261 1.1 ragge return (0);
262 1.1 ragge }
263