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