xref: /netbsd/sys/arch/vax/uba/uba_sbi.c (revision 2d5d8524)
1 /*	$NetBSD: uba_sbi.c,v 1.30 2017/05/22 17:15:45 ragge Exp $	   */
2 /*
3  * Copyright (c) 1982, 1986 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the University nor the names of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  *	@(#)uba.c	7.10 (Berkeley) 12/16/90
31  *	@(#)autoconf.c	7.20 (Berkeley) 5/9/91
32  */
33 
34 /*
35  * Copyright (c) 1996 Jonathan Stone.
36  * Copyright (c) 1994, 1996 Ludd, University of Lule}, Sweden.
37  *
38  * Redistribution and use in source and binary forms, with or without
39  * modification, are permitted provided that the following conditions
40  * are met:
41  * 1. Redistributions of source code must retain the above copyright
42  *    notice, this list of conditions and the following disclaimer.
43  * 2. Redistributions in binary form must reproduce the above copyright
44  *    notice, this list of conditions and the following disclaimer in the
45  *    documentation and/or other materials provided with the distribution.
46  *
47  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
48  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57  * SUCH DAMAGE.
58  *
59  *	@(#)uba.c	7.10 (Berkeley) 12/16/90
60  *	@(#)autoconf.c	7.20 (Berkeley) 5/9/91
61  */
62 
63 /*
64  * Abus support added by Johnny Billquist 2010
65  * Changed UBA code to need to know less of the innards of the
66  * actual machine at the same time. Information passed down from
67  * the SBI bus instead.
68  */
69 
70 #include <sys/cdefs.h>
71 __KERNEL_RCSID(0, "$NetBSD: uba_sbi.c,v 1.30 2017/05/22 17:15:45 ragge Exp $");
72 
73 #define _VAX_BUS_DMA_PRIVATE
74 
75 #include <sys/param.h>
76 #include <sys/systm.h>
77 #include <sys/bus.h>
78 #include <sys/cpu.h>
79 #include <sys/device.h>
80 #include <sys/kernel.h>
81 
82 #include <machine/nexus.h>
83 #include <machine/sgmap.h>
84 #include <machine/scb.h>
85 
86 #include <dev/qbus/ubavar.h>
87 
88 #include <vax/uba/uba_common.h>
89 
90 #include "locators.h"
91 #include "ioconf.h"
92 
93 /* Some SBI-specific defines */
94 #define UBASIZE		(UBAPAGES * VAX_NBPG)
95 #define UMEM(sa,i) ((sa->sa_base)+0x100000+(i)*0x40000)
96 
97 /*
98  * Some status registers.
99  */
100 #define UBACNFGR_UBIC  0x00010000      /* unibus init complete */
101 #define UBACNFGR_BITS \
102 "\40\40PARFLT\37WSQFLT\36URDFLT\35ISQFLT\34MXTFLT\33XMTFLT\30ADPDN\27ADPUP\23UBINIT\22UBPDN\21UBIC"
103 
104 #define UBACR_IFS      0x00000040      /* interrupt field switch */
105 #define UBACR_BRIE     0x00000020      /* BR interrupt enable */
106 #define UBACR_USEFIE   0x00000010      /* UNIBUS to SBI error field IE */
107 #define UBACR_SUEFIE   0x00000008      /* SBI to UNIBUS error field IE */
108 #define UBACR_ADINIT   0x00000001      /* adapter init */
109 
110 #define UBADPR_BNE     0x80000000      /* buffer not empty - purge */
111 
112 #define UBABRRVR_DIV    0x0000ffff      /* device interrupt vector field */
113 
114 #define UBASR_BITS \
115 "\20\13RDTO\12RDS\11CRD\10CXTER\7CXTMO\6DPPE\5IVMR\4MRPF\3LEB\2UBSTO\1UBSSYNTO"
116 
117 const char ubasr_bits[] = UBASR_BITS;
118 
119 /*
120  * The DW780 are directly connected to the SBI on 11/780 and 8600.
121  */
122 static	int	dw780_match(device_t, cfdata_t, void *);
123 static	void	dw780_attach(device_t, device_t, void *);
124 static	void	dw780_init(struct uba_softc*);
125 static	void    dw780_beforescan(struct uba_softc *);
126 static	void    dw780_afterscan(struct uba_softc *);
127 static	int     dw780_errchk(struct uba_softc *);
128 static	inline	void uba_dw780int_common(void *, int);
129 static	void    uba_dw780int_0x14(void *);
130 static	void    uba_dw780int_0x15(void *);
131 static	void    uba_dw780int_0x16(void *);
132 static	void    uba_dw780int_0x17(void *);
133 static  void	ubaerror(struct uba_softc *, int *, int *);
134 #ifdef notyet
135 static	void	dw780_purge(struct uba_softc *, int);
136 #endif
137 
138 CFATTACH_DECL_NEW(uba_sbi, sizeof(struct uba_vsoftc),
139     dw780_match, dw780_attach, NULL, NULL);
140 
141 static struct evcnt strayint = EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "uba","stray intr");
142 static int strayinit = 0;
143 
144 extern	struct vax_bus_space vax_mem_bus_space;
145 
146 int
dw780_match(device_t parent,cfdata_t cf,void * aux)147 dw780_match(device_t parent, cfdata_t cf, void *aux)
148 {
149 	struct sbi_attach_args * const sa = aux;
150 
151 	if (cf->cf_loc[SBICF_TR] != sa->sa_nexnum &&
152 	    cf->cf_loc[SBICF_TR] != SBICF_TR_DEFAULT)
153 		return 0;
154 	/*
155 	 * The uba type is actually only telling where the uba
156 	 * space is in nexus space.
157 	 */
158 	if ((sa->sa_type & ~3) != NEX_UBA0)
159 		return 0;
160 
161 	return 1;
162 }
163 
164 void
dw780_attach(device_t parent,device_t self,void * aux)165 dw780_attach(device_t parent, device_t self, void *aux)
166 {
167 	struct uba_vsoftc * const sc = device_private(self);
168 	struct sbi_attach_args * const sa = aux;
169 	int ubaddr = sa->sa_type & 3;
170 
171 	aprint_naive(": DW780\n");
172 	aprint_normal(": DW780\n");
173 
174 	/*
175 	 * Fill in bus specific data.
176 	 */
177 	sc->uv_sc.uh_dev = self;
178 	sc->uv_sc.uh_ubainit = dw780_init;
179 #ifdef notyet
180 	sc->uv_sc.uh_ubapurge = dw780_purge;
181 #endif
182 	sc->uv_sc.uh_beforescan = dw780_beforescan;
183 	sc->uv_sc.uh_afterscan = dw780_afterscan;
184 	sc->uv_sc.uh_errchk = dw780_errchk;
185 	sc->uv_sc.uh_iot = sa->sa_iot;
186 	sc->uv_sc.uh_dmat = &sc->uv_dmat;
187 	sc->uv_sc.uh_nr = ubaddr;
188 	sc->uv_uba = (void *)sa->sa_ioh;
189 	sc->uh_ibase = VAX_NBPG + ubaddr * VAX_NBPG;
190 	sc->uv_sc.uh_type = UBA_UBA;
191 
192 	if (strayinit++ == 0) evcnt_attach_static(&strayint); /* Setup stray
193 							         interrupt
194 							         counter. */
195 
196 	/*
197 	 * Set up dispatch vectors for DW780.
198 	 */
199 #define SCB_VECALLOC_DW780(br)						\
200 	scb_vecalloc(vecnum(0, br, sa->sa_nexnum), uba_dw780int_ ## br,	\
201 		     sc, SCB_ISTACK, &sc->uv_sc.uh_intrcnt)		\
202 
203 	SCB_VECALLOC_DW780(0x14);
204 	SCB_VECALLOC_DW780(0x15);
205 	SCB_VECALLOC_DW780(0x16);
206 	SCB_VECALLOC_DW780(0x17);
207 
208 	evcnt_attach_dynamic(&sc->uv_sc.uh_intrcnt, EVCNT_TYPE_INTR, NULL,
209 		device_xname(sc->uv_sc.uh_dev), "intr");
210 
211 	/*
212 	 * Fill in variables used by the sgmap system.
213 	 */
214 	sc->uv_size = UBASIZE;		/* Size in bytes of Unibus space */
215 
216 	uba_dma_init(sc);
217 	uba_attach(&sc->uv_sc, UMEM(sa,ubaddr) + (UBAPAGES * VAX_NBPG));
218 }
219 
220 void
dw780_beforescan(struct uba_softc * sc)221 dw780_beforescan(struct uba_softc *sc)
222 {
223 	struct uba_vsoftc * const vc = (void *)sc;
224 	volatile int *hej = &vc->uv_uba->uba_sr;
225 
226 	*hej = *hej;
227 	vc->uv_uba->uba_cr = UBACR_IFS|UBACR_BRIE;
228 }
229 
230 void
dw780_afterscan(struct uba_softc * sc)231 dw780_afterscan(struct uba_softc *sc)
232 {
233 	struct uba_vsoftc * const vc = (void *)sc;
234 
235 	vc->uv_uba->uba_cr = UBACR_IFS | UBACR_BRIE |
236 	    UBACR_USEFIE | UBACR_SUEFIE |
237 	    (vc->uv_uba->uba_cr & 0x7c000000);
238 }
239 
240 
241 int
dw780_errchk(struct uba_softc * sc)242 dw780_errchk(struct uba_softc *sc)
243 {
244 	struct uba_vsoftc * const vc = (void *)sc;
245 	volatile int *hej = &vc->uv_uba->uba_sr;
246 
247 	if (*hej) {
248 		*hej = *hej;
249 		return 1;
250 	}
251 	return 0;
252 }
253 
254 static inline void
uba_dw780int_common(void * arg,int br)255 uba_dw780int_common(void *arg, int br)
256 {
257 	extern	void scb_stray(void *);
258 	struct	uba_vsoftc *vc = arg;
259 	struct	uba_regs *ur = vc->uv_uba;
260 	struct	ivec_dsp *ivec;
261 	struct  evcnt *uvec;
262 	int	vec;
263 
264 	uvec = &vc->uv_sc.uh_intrcnt;
265 	vec = ur->uba_brrvr[br - 0x14];
266 	if (vec <= 0) {
267 		ubaerror(&vc->uv_sc, &br, &vec);
268 		if (vec == 0)
269 			return;
270 	}
271 
272 	uvec->ev_count--;	/* This interrupt should not be counted against
273 				   the uba. */
274 	ivec = &scb_vec[(vc->uh_ibase + vec)/4];
275 	if (cold && *ivec->hoppaddr == scb_stray) {
276 		scb_fake(vec + vc->uh_ibase, br);
277 	} else {
278 		if (*ivec->hoppaddr == scb_stray)
279 			strayint.ev_count++; /* Count against stray int */
280 		else
281 			ivec->ev->ev_count++; /* Count against device */
282 		(*ivec->hoppaddr)(ivec->pushlarg);
283 	}
284 }
285 
286 #define UBA_DW780INT(br)		\
287 void					\
288 uba_dw780int_ ## br(void *arg)		\
289 {					\
290 	uba_dw780int_common(arg, br);	\
291 }					\
292 
293 UBA_DW780INT(0x14);
294 UBA_DW780INT(0x15);
295 UBA_DW780INT(0x16);
296 UBA_DW780INT(0x17);
297 
298 void
dw780_init(struct uba_softc * sc)299 dw780_init(struct uba_softc *sc)
300 {
301 	struct uba_vsoftc *vc = (void *)sc;
302 
303 	vc->uv_uba->uba_cr = UBACR_ADINIT;
304 	vc->uv_uba->uba_cr = UBACR_IFS|UBACR_BRIE|UBACR_USEFIE|UBACR_SUEFIE;
305 	while ((vc->uv_uba->uba_cnfgr & UBACNFGR_UBIC) == 0)
306 		;
307 }
308 
309 #ifdef notyet
310 void
dw780_purge(struct uba_softc * sc,int bdp)311 dw780_purge(struct uba_softc *sc, int bdp)
312 {
313 	struct uba_vsoftc *vc = (void *)sc;
314 
315 	vc->uv_uba->uba_dpr[bdp] |= UBADPR_BNE;
316 }
317 #endif
318 
319 int	ubawedgecnt = 10;
320 int	ubacrazy = 500;
321 int	zvcnt_max = 5000;	/* in 8 sec */
322 int	ubaerrcnt;
323 /*
324  * This routine is called by the locore code to process a UBA
325  * error on an 11/780 or 8600.	The arguments are passed
326  * on the stack, and value-result (through some trickery).
327  * In particular, the uvec argument is used for further
328  * uba processing so the result aspect of it is very important.
329  */
330 /*ARGSUSED*/
331 void
ubaerror(struct uba_softc * uh,int * ipl,int * uvec)332 ubaerror(struct uba_softc *uh, int *ipl, int *uvec)
333 {
334 	struct uba_vsoftc *vc = (void *)uh;
335 	struct	uba_regs *uba = vc->uv_uba;
336 	int sr, s;
337 	char sbuf[256], sbuf2[256];
338 
339 	if (*uvec == 0) {
340 		/*
341 		 * Declare dt as unsigned so that negative values
342 		 * are handled as >8 below, in case time was set back.
343 		 */
344 		u_long	dt = time_second - vc->uh_zvtime;
345 
346 		vc->uh_zvtotal++;
347 		if (dt > 8) {
348 			vc->uh_zvtime = time_second;
349 			vc->uh_zvcnt = 0;
350 		}
351 		if (++vc->uh_zvcnt > zvcnt_max) {
352 			aprint_error_dev(vc->uv_sc.uh_dev,
353 			    "too many zero vectors (%d in <%d sec)\n",
354 			    vc->uh_zvcnt, (int)dt + 1);
355 
356 			snprintb(sbuf, sizeof(sbuf), UBACNFGR_BITS,
357 			    uba->uba_cnfgr & ~0xff);
358 			aprint_error(
359 			    "\tIPL 0x%x\n"
360 			    "\tcnfgr: %s\tAdapter Code: 0x%x\n",
361 			    *ipl, sbuf, uba->uba_cnfgr&0xff);
362 
363 			snprintb(sbuf, sizeof(sbuf), ubasr_bits, uba->uba_sr);
364 			aprint_error(
365 			    "\tsr: %s\n"
366 			    "\tdcr: %x (MIC %sOK)\n",
367 			    sbuf, uba->uba_dcr,
368 			    (uba->uba_dcr&0x8000000)?"":"NOT ");
369 
370 			ubareset(&vc->uv_sc);
371 		}
372 		return;
373 	}
374 	if (uba->uba_cnfgr & NEX_CFGFLT) {
375 		snprintb(sbuf, sizeof(sbuf), ubasr_bits, uba->uba_sr);
376 		snprintb(sbuf2, sizeof(sbuf2), NEXFLT_BITS, uba->uba_cnfgr);
377 		aprint_error_dev(vc->uv_sc.uh_dev,
378 		    "sbi fault sr=%s cnfgr=%s\n", sbuf, sbuf2);
379 		ubareset(&vc->uv_sc);
380 		*uvec = 0;
381 		return;
382 	}
383 	sr = uba->uba_sr;
384 	s = spluba();
385 	snprintb(sbuf, sizeof(sbuf), ubasr_bits, uba->uba_sr);
386 	aprint_error_dev(vc->uv_sc.uh_dev,
387 	    "uba error sr=%s fmer=%x fubar=%o\n",
388 	    sbuf, uba->uba_fmer, 4*uba->uba_fubar);
389 	splx(s);
390 	uba->uba_sr = sr;
391 	*uvec &= UBABRRVR_DIV;
392 	if (++ubaerrcnt % ubawedgecnt == 0) {
393 		if (ubaerrcnt > ubacrazy)
394 			panic("uba crazy");
395 		printf("ERROR LIMIT ");
396 		ubareset(&vc->uv_sc);
397 		*uvec = 0;
398 	}
399 }
400