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 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 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 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 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 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 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 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 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 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