diff options
| author | ragge <ragge@NetBSD.org> | 1999-05-24 20:12:57 +0000 |
|---|---|---|
| committer | ragge <ragge@NetBSD.org> | 1999-05-24 20:12:57 +0000 |
| commit | 7fb0d17b388e43870e709e560191ea77dcae4fec (patch) | |
| tree | 6e901e33a38cc9db06ae991c13a07394454ddf75 /sys/dev/dec | |
| parent | 770a66b9a82de25974aa859d8ab1e5f8d9a67766 (diff) | |
First step towards MI Unibus/Q22 bus code.
Diffstat (limited to 'sys/dev/dec')
| -rw-r--r-- | sys/dev/dec/qbus/files.uba | 8 | ||||
| -rw-r--r-- | sys/dev/dec/qbus/uba.c | 480 | ||||
| -rw-r--r-- | sys/dev/dec/qbus/ubareg.h | 3 | ||||
| -rw-r--r-- | sys/dev/dec/qbus/ubavar.h | 20 |
4 files changed, 38 insertions, 473 deletions
diff --git a/sys/dev/dec/qbus/files.uba b/sys/dev/dec/qbus/files.uba new file mode 100644 index 00000000000..4ca58dbd755 --- /dev/null +++ b/sys/dev/dec/qbus/files.uba @@ -0,0 +1,8 @@ +# $NetBSD: files.uba,v 1.1 1999/05/24 20:12:57 ragge Exp $ +# +# Config file and device description for machine-independent +# code for devices Digital Equipment Corp. Unibus and Q22 bus. +# Included by ports that need it. +device uba { csr } + +file dev/dec/uba/uba.c uba & new_uba diff --git a/sys/dev/dec/qbus/uba.c b/sys/dev/dec/qbus/uba.c index f53f4ff806b..f4cb595dabd 100644 --- a/sys/dev/dec/qbus/uba.c +++ b/sys/dev/dec/qbus/uba.c @@ -1,4 +1,4 @@ -/* $NetBSD: uba.c,v 1.42 1999/02/02 18:37:20 ragge Exp $ */ +/* $NetBSD: uba.c,v 1.43 1999/05/24 20:12:58 ragge Exp $ */ /* * Copyright (c) 1996 Jonathan Stone. * Copyright (c) 1994, 1996 Ludd, University of Lule}, Sweden. @@ -54,439 +54,25 @@ #include <vm/vm.h> #include <vm/vm_kern.h> -#include <machine/pte.h> -#include <machine/cpu.h> -#include <machine/mtpr.h> -#include <machine/nexus.h> -#include <machine/sid.h> +#include <machine/bus.h> #include <machine/scb.h> -#include <machine/trap.h> -#include <machine/frame.h> +#include <machine/cpu.h> -#include <vax/uba/ubareg.h> -#include <vax/uba/ubavar.h> +#ifdef __vax__ +#include <machine/pte.h> +#endif -volatile int /* rbr, rcvec,*/ svec; +#include <dev/dec/uba/ubareg.h> +#include <dev/dec/uba/ubavar.h> static int ubasearch __P((struct device *, struct cfdata *, void *)); static int ubaprint __P((void *, const char *)); -#if 0 -static void ubastray __P((int)); -#endif static void ubainitmaps __P((struct uba_softc *)); extern struct cfdriver uba_cd; #define spluba spl7 -#if defined(DW780) || defined(DW750) - -int dw_match __P((struct device *, struct cfdata *, void *)); - -int -dw_match(parent, cf, aux) - struct device *parent; - struct cfdata *cf; - void *aux; -{ - struct sbi_attach_args *sa = (struct sbi_attach_args *)aux; - - if ((cf->cf_loc[0] != sa->nexnum) && (cf->cf_loc[0] > -1 )) - return 0; - - /* - * The uba type is actually only telling where the uba - * space is in nexus space. - */ - if ((sa->type & ~3) != NEX_UBA0) - return 0; - - return 1; -} -#endif - -#ifdef DW780 -/* - * The DW780 are directly connected to the SBI on 11/780 and 8600. - */ -void dw780_attach __P((struct device *, struct device *, void *)); -void dw780_beforescan __P((struct uba_softc *)); -void dw780_afterscan __P((struct uba_softc *)); -int dw780_errchk __P((struct uba_softc *)); -void dw780_init __P((struct uba_softc *)); -void dw780_purge __P((struct uba_softc *, int)); -void uba_dw780int __P((int)); -static void ubaerror __P((struct uba_softc *, int *, int *)); - -struct cfattach uba_sbi_ca = { - sizeof(struct uba_softc), dw_match, dw780_attach -}; - -char ubasr_bits[] = UBASR_BITS; - -void -dw780_attach(parent, self, aux) - struct device *parent, *self; - void *aux; -{ - struct uba_softc *sc = (void *)self; - struct sbi_attach_args *sa = aux; - int ubaddr = sa->type & 3; - int i; - - printf(": DW780\n"); - - /* - * Fill in bus specific data. - */ - sc->uh_uba = (void *)sa->nexaddr; - sc->uh_nbdp = NBDP780; - sc->uh_nr = sa->nexnum * (parent->dv_unit + 1); - sc->uh_beforescan = dw780_beforescan; - sc->uh_afterscan = dw780_afterscan; - sc->uh_errchk = dw780_errchk; - sc->uh_ubapurge = dw780_purge; - sc->uh_ubainit = dw780_init; - sc->uh_type = DW780; - sc->uh_memsize = UBAPAGES; - sc->uh_ibase = VAX_NBPG + ubaddr * VAX_NBPG; - sc->uh_mr = sc->uh_uba->uba_map; - - for (i = 0; i < 4; i++) - scb_vecalloc(256 + i * 64 + sa->nexnum * 4, uba_dw780int, - sc->uh_dev.dv_unit, SCB_ISTACK); - - uba_attach(sc, (parent->dv_unit ? UMEMB8600(ubaddr) : - UMEMA8600(ubaddr)) + (UBAPAGES * VAX_NBPG)); -} - -void -dw780_beforescan(sc) - struct uba_softc *sc; -{ - volatile int *hej = &sc->uh_uba->uba_sr; - - *hej = *hej; - sc->uh_uba->uba_cr = UBACR_IFS|UBACR_BRIE; -} - -void -dw780_afterscan(sc) - struct uba_softc *sc; -{ - sc->uh_uba->uba_cr = UBACR_IFS | UBACR_BRIE | - UBACR_USEFIE | UBACR_SUEFIE | - (sc->uh_uba->uba_cr & 0x7c000000); -} - -/* - * On DW780 badaddr() in uba space sets a bit in uba_sr instead of - * doing a machine check. - */ -int -dw780_errchk(sc) - struct uba_softc *sc; -{ - volatile int *hej = &sc->uh_uba->uba_sr; - - if (*hej) { - *hej = *hej; - return 1; - } - return 0; -} - -void -uba_dw780int(uba) - int uba; -{ - int br, vec, arg; - struct uba_softc *sc = uba_cd.cd_devs[uba]; - struct uba_regs *ur = sc->uh_uba; - void (*func) __P((int)); - - br = mfpr(PR_IPL); - vec = ur->uba_brrvr[br - 0x14]; - if (vec <= 0) { - ubaerror(sc, &br, (int *)&vec); - if (svec == 0) - return; - } - if (cold) - scb_fake(vec + sc->uh_ibase, br); - else { - struct ivec_dsp *scb_vec = (struct ivec_dsp *)((int)scb + 512); - func = scb_vec[vec/4].hoppaddr; - arg = scb_vec[vec/4].pushlarg; - (*func)(arg); - } -} - -void -dw780_init(sc) - struct uba_softc *sc; -{ - sc->uh_uba->uba_cr = UBACR_ADINIT; - sc->uh_uba->uba_cr = UBACR_IFS|UBACR_BRIE|UBACR_USEFIE|UBACR_SUEFIE; - while ((sc->uh_uba->uba_cnfgr & UBACNFGR_UBIC) == 0) - ; -} - -void -dw780_purge(sc, bdp) - struct uba_softc *sc; - int bdp; -{ - sc->uh_uba->uba_dpr[bdp] |= UBADPR_BNE; -} - -int ubawedgecnt = 10; -int ubacrazy = 500; -int zvcnt_max = 5000; /* in 8 sec */ -int ubaerrcnt; -/* - * This routine is called by the locore code to process a UBA - * error on an 11/780 or 8600. The arguments are passed - * on the stack, and value-result (through some trickery). - * In particular, the uvec argument is used for further - * uba processing so the result aspect of it is very important. - * It must not be declared register. - */ -/*ARGSUSED*/ -void -ubaerror(uh, ipl, uvec) - register struct uba_softc *uh; - int *ipl, *uvec; -{ - struct uba_regs *uba = uh->uh_uba; - register int sr, s; - - if (*uvec == 0) { - /* - * Declare dt as unsigned so that negative values - * are handled as >8 below, in case time was set back. - */ - u_long dt = time.tv_sec - uh->uh_zvtime; - - uh->uh_zvtotal++; - if (dt > 8) { - uh->uh_zvtime = time.tv_sec; - uh->uh_zvcnt = 0; - } - if (++uh->uh_zvcnt > zvcnt_max) { - printf("%s: too many zero vectors (%d in <%d sec)\n", - uh->uh_dev.dv_xname, uh->uh_zvcnt, (int)dt + 1); - printf("\tIPL 0x%x\n\tcnfgr: %b Adapter Code: 0x%x\n", - *ipl, uba->uba_cnfgr&(~0xff), UBACNFGR_BITS, - uba->uba_cnfgr&0xff); - printf("\tsr: %b\n\tdcr: %x (MIC %sOK)\n", - uba->uba_sr, ubasr_bits, uba->uba_dcr, - (uba->uba_dcr&0x8000000)?"":"NOT "); - ubareset(uh->uh_dev.dv_unit); - } - return; - } - if (uba->uba_cnfgr & NEX_CFGFLT) { - printf("%s: sbi fault sr=%b cnfgr=%b\n", - uh->uh_dev.dv_xname, uba->uba_sr, ubasr_bits, - uba->uba_cnfgr, NEXFLT_BITS); - ubareset(uh->uh_dev.dv_unit); - *uvec = 0; - return; - } - sr = uba->uba_sr; - s = spluba(); - printf("%s: uba error sr=%b fmer=%x fubar=%o\n", uh->uh_dev.dv_xname, - uba->uba_sr, ubasr_bits, uba->uba_fmer, 4*uba->uba_fubar); - splx(s); - uba->uba_sr = sr; - *uvec &= UBABRRVR_DIV; - if (++ubaerrcnt % ubawedgecnt == 0) { - if (ubaerrcnt > ubacrazy) - panic("uba crazy"); - printf("ERROR LIMIT "); - ubareset(uh->uh_dev.dv_unit); - *uvec = 0; - return; - } - return; -} -#endif - -#ifdef DW750 -/* - * The DW780 and DW750 are quite similar to their function from - * a programmers point of view. Differencies are number of BDP's - * and bus status/command registers, the latter are (partly) IPR's - * on 750. - */ -void dw750_attach __P((struct device *, struct device *, void *)); -void dw750_init __P((struct uba_softc *)); -void dw750_purge __P((struct uba_softc *, int)); - -struct cfattach uba_cmi_ca = { - sizeof(struct uba_softc), dw_match, dw750_attach -}; - -void -dw750_attach(parent, self, aux) - struct device *parent, *self; - void *aux; -{ - struct uba_softc *sc = (void *)self; - struct sbi_attach_args *sa = aux; - int ubaddr = sa->nexinfo & 1; - - printf(": DW750\n"); - - /* - * Fill in bus specific data. - */ - sc->uh_uba = (void *)sa->nexaddr; - sc->uh_nbdp = NBDP750; - sc->uh_nr = sa->nexnum; - sc->uh_ubapurge = dw750_purge; - sc->uh_ubainit = dw750_init; - sc->uh_type = DW750; - sc->uh_memsize = UBAPAGES; - sc->uh_mr = sc->uh_uba->uba_map; - - uba_attach(sc, UMEM750(ubaddr) + (UBAPAGES * VAX_NBPG)); -} - -void -dw750_init(sc) - struct uba_softc *sc; -{ - mtpr(0, PR_IUR); - DELAY(500000); -} - -void -dw750_purge(sc, bdp) - struct uba_softc *sc; - int bdp; -{ - sc->uh_uba->uba_dpr[bdp] |= UBADPR_PURGE | UBADPR_NXM | UBADPR_UCE; -} -#endif - -#ifdef QBA -/* - * The Q22 bus is the main IO bus on MicroVAX II/MicroVAX III systems. - * It has an address space of 4MB (22 address bits), therefore the name, - * and is hardware compatible with all 16 and 18 bits Q-bus devices. - * This driver can only handle map registers up to 1MB due to map info - * storage, but that should be enough for normal purposes. - */ -int qba_match __P((struct device *, struct cfdata *, void *)); -void qba_attach __P((struct device *, struct device *, void *)); -void qba_beforescan __P((struct uba_softc*)); -void qba_init __P((struct uba_softc*)); - -struct cfattach uba_mainbus_ca = { - sizeof(struct uba_softc), qba_match, qba_attach -}; - -int -qba_match(parent, vcf, aux) - struct device *parent; - struct cfdata *vcf; - void *aux; -{ - struct bp_conf *bp = aux; - - if (strcmp(bp->type, "uba")) - return 0; - - return 1; -} - -void -qba_attach(parent, self, aux) - struct device *parent, *self; - void *aux; -{ - struct uba_softc *sc = (void *)self; - - printf(": Q22\n"); - /* - * Fill in bus specific data. - */ -/* sc->uh_uba not used; no regs */ -/* sc->uh_nbdp is 0; Qbus has no BDP's */ -/* sc->uh_nr is 0; there can be only one! */ -/* sc->uh_afterscan; not used */ -/* sc->uh_errchk; not used */ - sc->uh_beforescan = qba_beforescan; - sc->uh_ubainit = qba_init; - sc->uh_type = QBA; - sc->uh_memsize = QBAPAGES; - /* - * Map in the UBA page map into kernel space. On other UBAs, - * the map registers are in the bus IO space. - */ - sc->uh_mr = (void *)vax_map_physmem(QBAMAP, - (QBAPAGES * sizeof(struct pte)) / VAX_NBPG); - - uba_attach(sc, QIOPAGE); -} - -/* - * Called when the QBA is set up; to enable DMA access from - * QBA devices to main memory. - */ -void -qba_beforescan(sc) - struct uba_softc *sc; -{ - *((u_short *)(sc->uh_iopage + QIPCR)) = Q_LMEAE; -} - -void -qba_init(sc) - struct uba_softc *sc; -{ - mtpr(0, PR_IUR); - DELAY(500000); - qba_beforescan(sc); -} -#endif -#ifdef DW730 -struct cfattach uba_dw730_ca = { - sizeof(struct uba_softc), dw730_match, dw730_attach -}; -#endif -#if 0 -/* - * Stray interrupt vector handler, used when nowhere else to go to. - */ -void -ubastray(arg) - int arg; -{ - struct callsframe *cf = FRAMEOFFSET(arg); - struct uba_softc *sc = uba_cd.cd_devs[arg]; - int vektor; - - rbr = mfpr(PR_IPL); -#ifdef DW780 - if (sc->uh_type == DW780) - vektor = svec >> 2; - else -#endif - vektor = (cf->ca_pc - (unsigned)&sc->uh_idsp[0]) >> 4; - - if (cold) { -#ifdef DW780 - if (sc->uh_type != DW780) -#endif - rcvec = vektor; - } else - printf("uba%d: unexpected interrupt, vector 0x%x, br 0x%x\n", - arg, svec, rbr); -} -#endif /* * Do transfer on device argument. The controller * and uba involved are implied by the device. @@ -760,30 +346,6 @@ ubareset(uban) splx(s); } -#ifdef notyet -/* - * Determine the interrupt priority of a Q-bus - * peripheral. The device probe routine must spl6(), - * attempt to make the device request an interrupt, - * delaying as necessary, then call this routine - * before resetting the device. - */ -int -qbgetpri() -{ - int pri; - - for (pri = 0x17; pri > 0x14; ) { - if (rcvec && rcvec != 0x200) /* interrupted at pri */ - break; - pri--; - splx(pri - 1); - } - spl0(); - return (pri); -} -#endif - /* * The common attach routines: * Allocates interrupt vectors. @@ -805,11 +367,10 @@ uba_attach(sc, iopagephys) SIMPLEQ_INIT(&sc->uh_resq); /* - * Allocate place for unibus memory in virtual space. + * Allocate place for unibus I/O space in virtual space. */ - sc->uh_iopage = (caddr_t)vax_map_physmem(iopagephys, UBAIOPAGES); - if (sc->uh_iopage == 0) - return; /* vax_map_physmem() will complain for us */ + if (bus_space_map(sc->uh_tag, iopagephys, UBAIOSIZE, 0, &sc->uh_ioh)) + return; /* * Initialize the UNIBUS, by freeing the map * registers and the buffered data path registers @@ -819,12 +380,6 @@ uba_attach(sc, iopagephys) bzero((caddr_t)sc->uh_map, (unsigned)(UAMSIZ * sizeof (struct map))); ubainitmaps(sc); - /* - * Map the first page of UNIBUS i/o space to the first page of memory - * for devices which will need to dma to produce an interrupt. - */ - *(int *)(&sc->uh_mr[0]) = UBAMR_MRV; - if (sc->uh_beforescan) (*sc->uh_beforescan)(sc); /* @@ -846,10 +401,11 @@ ubasearch(parent, cf, aux) struct uba_attach_args ua; int i, vec, br; - ua.ua_addr = (caddr_t)((int)sc->uh_iopage + ubdevreg(cf->cf_loc[0])); + ua.ua_addr = ubdevreg(cf->cf_loc[0]); ua.ua_reset = NULL; - if (badaddr(ua.ua_addr, 2) || (sc->uh_errchk ? (*sc->uh_errchk)(sc):0)) + if (badaddr((caddr_t)(sc->uh_ioh + ua.ua_addr), 2) || + (sc->uh_errchk ? (*sc->uh_errchk)(sc):0)) goto forgetit; scb_vecref(0, 0); /* Clear vector ref */ @@ -870,17 +426,15 @@ ubasearch(parent, cf, aux) scb_vecalloc(vec, ua.ua_ivec, cf->cf_unit, SCB_ISTACK); if (ua.ua_reset) { /* device wants ubareset */ if (sc->uh_resno == 0) { - sc->uh_reset = malloc(1024, M_DEVBUF, M_NOWAIT); + sc->uh_reset = malloc(sizeof(ua.ua_reset), + M_DEVBUF, M_NOWAIT); sc->uh_resarg = (int *)sc->uh_reset + 128; } -#ifdef DIAGNOSTIC if (sc->uh_resno > 127) { printf("%s: Expand reset table, skipping reset %s%d\n", sc->uh_dev.dv_xname, cf->cf_driver->cd_name, cf->cf_unit); - } else -#endif - { + } else { sc->uh_resarg[sc->uh_resno] = cf->cf_unit; sc->uh_reset[sc->uh_resno++] = ua.ua_reset; } diff --git a/sys/dev/dec/qbus/ubareg.h b/sys/dev/dec/qbus/ubareg.h index 003a7645934..d29d4cc31e1 100644 --- a/sys/dev/dec/qbus/ubareg.h +++ b/sys/dev/dec/qbus/ubareg.h @@ -1,4 +1,4 @@ -/* $NetBSD: ubareg.h,v 1.10 1998/10/18 18:51:30 ragge Exp $ */ +/* $NetBSD: ubareg.h,v 1.11 1999/05/24 20:12:58 ragge Exp $ */ /*- * Copyright (c) 1982, 1986 The Regents of the University of California. @@ -86,6 +86,7 @@ #define QBAPAGES 1024 #define UBAIOADDR 0760000 /* start of I/O page */ #define UBAIOPAGES 16 +#define UBAIOSIZE 8192 /* 8K I/O space */ #ifndef _LOCORE /* diff --git a/sys/dev/dec/qbus/ubavar.h b/sys/dev/dec/qbus/ubavar.h index f16396f882f..9576714f058 100644 --- a/sys/dev/dec/qbus/ubavar.h +++ b/sys/dev/dec/qbus/ubavar.h @@ -1,4 +1,4 @@ -/* $NetBSD: ubavar.h,v 1.21 1999/01/19 21:04:48 ragge Exp $ */ +/* $NetBSD: ubavar.h,v 1.22 1999/05/24 20:12:58 ragge Exp $ */ /* * Copyright (c) 1982, 1986 Regents of the University of California. @@ -99,6 +99,8 @@ struct uba_softc { short uh_nr; /* Unibus sequential number */ short uh_nbdp; /* # of BDP's */ int uh_ibase; /* Base address for vectors */ + bus_space_tag_t uh_tag; /* Tag for this Unibus */ + bus_space_handle_t uh_ioh; /* Handle for I/O space */ }; #define UAMSIZ 100 @@ -124,14 +126,14 @@ struct uba_unit { * from ubascan() to each (possible) device. */ struct uba_attach_args { - caddr_t ua_addr; - /* Pointer to int routine, filled in by probe*/ - void (*ua_ivec) __P((int)); - /* UBA reset routine, filled in by probe */ - void (*ua_reset) __P((int)); - int ua_iaddr; - int ua_br; - int ua_cvec; + bus_addr_t ua_addr; /* I/O regs addr */ + /* Pointer to int routine, filled in by probe*/ + void (*ua_ivec) __P((int)); + /* UBA reset routine, filled in by probe */ + void (*ua_reset) __P((int)); + int ua_iaddr; + int ua_br; + int ua_cvec; }; /* |
