summaryrefslogtreecommitdiff
path: root/sys/arch/vax/uba/uba.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/vax/uba/uba.c')
-rw-r--r--sys/arch/vax/uba/uba.c231
1 files changed, 77 insertions, 154 deletions
diff --git a/sys/arch/vax/uba/uba.c b/sys/arch/vax/uba/uba.c
index 98b8f4b5a1c..5d06ea578aa 100644
--- a/sys/arch/vax/uba/uba.c
+++ b/sys/arch/vax/uba/uba.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uba.c,v 1.8 1997/05/29 00:05:09 niklas Exp $ */
-/* $NetBSD: uba.c,v 1.29 1996/10/13 03:35:24 christos Exp $ */
+/* $OpenBSD: uba.c,v 1.9 2000/04/27 03:14:51 bjc Exp $ */
+/* $NetBSD: uba.c,v 1.42 1999/02/02 18:37:20 ragge Exp $ */
/*
* Copyright (c) 1996 Jonathan Stone.
* Copyright (c) 1994, 1996 Ludd, University of Lule}, Sweden.
@@ -67,33 +67,30 @@
#include <vax/uba/ubareg.h>
#include <vax/uba/ubavar.h>
-volatile int rbr, rcvec, svec;
+volatile int /* rbr, rcvec,*/ svec;
-static void ubascan __P((struct device *, void *));
+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 *));
-static void uba_attach __P((struct uba_softc *, unsigned long));
-static int ubasetup __P((struct uba_softc *, struct buf *, int));
-
-struct cfdriver uba_cd = {
- NULL, "uba", DV_DULL, 1
-};
+extern struct cfdriver uba_cd;
#define spluba spl7
#if defined(DW780) || defined(DW750)
-int dw_match __P((struct device *, void *, void *));
+int dw_match __P((struct device *, struct cfdata *, void *));
int
-dw_match(parent, vcf, aux)
+dw_match(parent, cf, aux)
struct device *parent;
- void *vcf, *aux;
+ struct cfdata *cf;
+ void *aux;
{
struct sbi_attach_args *sa = (struct sbi_attach_args *)aux;
- struct cfdata *cf = vcf;
if ((cf->cf_loc[0] != sa->nexnum) && (cf->cf_loc[0] > -1 ))
return 0;
@@ -136,6 +133,7 @@ dw780_attach(parent, self, aux)
struct uba_softc *sc = (void *)self;
struct sbi_attach_args *sa = aux;
int ubaddr = sa->type & 3;
+ int i;
printf(": DW780\n");
@@ -152,18 +150,15 @@ dw780_attach(parent, self, aux)
sc->uh_ubainit = dw780_init;
sc->uh_type = DW780;
sc->uh_memsize = UBAPAGES;
- sc->uh_iarea = (void *)scb + NBPG + ubaddr * NBPG;
+ sc->uh_ibase = VAX_NBPG + ubaddr * VAX_NBPG;
sc->uh_mr = sc->uh_uba->uba_map;
- bcopy(&idsptch, &sc->uh_dw780, sizeof(struct ivec_dsp));
- sc->uh_dw780.pushlarg = sc->uh_dev.dv_unit;
- sc->uh_dw780.hoppaddr = uba_dw780int;
- scb->scb_nexvec[0][sa->nexnum] = scb->scb_nexvec[1][sa->nexnum]
- = scb->scb_nexvec[2][sa->nexnum]
- = scb->scb_nexvec[3][sa->nexnum] = &sc->uh_dw780;
+ 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 * NBPG));
+ UMEMA8600(ubaddr)) + (UBAPAGES * VAX_NBPG));
}
void
@@ -172,20 +167,17 @@ dw780_beforescan(sc)
{
volatile int *hej = &sc->uh_uba->uba_sr;
- if (sc->uh_type == DW780) {
- *hej = *hej;
- sc->uh_uba->uba_cr = UBACR_IFS|UBACR_BRIE;
- }
+ *hej = *hej;
+ sc->uh_uba->uba_cr = UBACR_IFS|UBACR_BRIE;
}
void
dw780_afterscan(sc)
struct uba_softc *sc;
{
- if (sc->uh_type == DW780)
- sc->uh_uba->uba_cr = UBACR_IFS | UBACR_BRIE |
- UBACR_USEFIE | UBACR_SUEFIE |
- (sc->uh_uba->uba_cr & 0x7c000000);
+ sc->uh_uba->uba_cr = UBACR_IFS | UBACR_BRIE |
+ UBACR_USEFIE | UBACR_SUEFIE |
+ (sc->uh_uba->uba_cr & 0x7c000000);
}
/*
@@ -198,7 +190,7 @@ dw780_errchk(sc)
{
volatile int *hej = &sc->uh_uba->uba_sr;
- if (sc->uh_type == DW780 && *hej) {
+ if (*hej) {
*hej = *hej;
return 1;
}
@@ -215,18 +207,20 @@ uba_dw780int(uba)
void (*func) __P((int));
br = mfpr(PR_IPL);
- svec = ur->uba_brrvr[br - 0x14];
- if (svec <= 0) {
- ubaerror(sc, &br, (int *)&svec);
+ vec = ur->uba_brrvr[br - 0x14];
+ if (vec <= 0) {
+ ubaerror(sc, &br, (int *)&vec);
if (svec == 0)
return;
}
- vec = svec >> 2;
if (cold)
- rcvec = vec;
- func = sc->uh_idsp[vec].hoppaddr;
- arg = sc->uh_idsp[vec].pushlarg;
- (*func)(arg);
+ 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
@@ -266,7 +260,7 @@ ubaerror(uh, ipl, uvec)
int *ipl, *uvec;
{
struct uba_regs *uba = uh->uh_uba;
- register sr, s;
+ register int sr, s;
if (*uvec == 0) {
/*
@@ -356,10 +350,9 @@ dw750_attach(parent, self, aux)
sc->uh_ubainit = dw750_init;
sc->uh_type = DW750;
sc->uh_memsize = UBAPAGES;
- sc->uh_iarea = (void *)scb + NBPG + ubaddr * NBPG;
sc->uh_mr = sc->uh_uba->uba_map;
- uba_attach(sc, UMEM750(ubaddr) + (UBAPAGES * NBPG));
+ uba_attach(sc, UMEM750(ubaddr) + (UBAPAGES * VAX_NBPG));
}
void
@@ -387,19 +380,20 @@ dw750_purge(sc, bdp)
* 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 *, void *, void *));
+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_backplane_ca = {
+struct cfattach uba_mainbus_ca = {
sizeof(struct uba_softc), qba_match, qba_attach
};
int
qba_match(parent, vcf, aux)
struct device *parent;
- void *vcf, *aux;
+ struct cfdata *vcf;
+ void *aux;
{
struct bp_conf *bp = aux;
@@ -415,11 +409,8 @@ qba_attach(parent, self, aux)
void *aux;
{
struct uba_softc *sc = (void *)self;
- vm_offset_t mini, maxi;
printf(": Q22\n");
-
-
/*
* Fill in bus specific data.
*/
@@ -432,16 +423,12 @@ qba_attach(parent, self, aux)
sc->uh_ubainit = qba_init;
sc->uh_type = QBA;
sc->uh_memsize = QBAPAGES;
- sc->uh_iarea = (void *)scb + NBPG;
/*
* Map in the UBA page map into kernel space. On other UBAs,
* the map registers are in the bus IO space.
*/
- (void)kmem_suballoc(kernel_map, &mini, &maxi,
- QBAPAGES * sizeof(struct pte), FALSE);
- pmap_map(mini, QBAMAP, QBAMAP + QBAPAGES * sizeof(struct pte),
- VM_PROT_READ | VM_PROT_WRITE);
- sc->uh_mr = (void *)mini;
+ sc->uh_mr = (void *)vax_map_physmem(QBAMAP,
+ (QBAPAGES * sizeof(struct pte)) / VAX_NBPG);
uba_attach(sc, QIOPAGE);
}
@@ -466,36 +453,12 @@ qba_init(sc)
qba_beforescan(sc);
}
#endif
-#ifdef DWBUA
-int bua_match __P((struct device *, void *, void *));
-void bua_attach __P((struct device *, struct device *, void *));
-
-struct cfattach uba_bi_ca = {
- sizeof(struct uba_softc), bua_match, bua_attach
-};
-
-bua_beforescan(sc)
- struct uba_softc *sc;
-{
- if (sc->uh_type == DWBUA)
- BUA(ubar)->bua_offset = (int)sc->uh_vec - (int)&scb[0];
-}
-
-void
-bua_init(sc)
- struct uba_softc *sc;
-{
- BUA(uba)->bua_csr |= BUACSR_UPI;
- /* give devices time to recover from power fail */
- DELAY(500000);
- break;
-}
-#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.
*/
@@ -524,7 +487,7 @@ ubastray(arg)
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.
@@ -623,8 +586,8 @@ ubasetup(uh, bp, flags)
if (uh->uh_nbdp == 0)
flags &= ~UBA_NEEDBDP;
- o = (int)bp->b_un.b_addr & PGOFSET;
- npf = btoc(bp->b_bcount + o) + 1;
+ o = (int)bp->b_un.b_addr & VAX_PGOFSET;
+ npf = vax_btoc(bp->b_bcount + o) + 1;
if (npf > UBA_MAXNMR)
panic("uba xfer too big");
a = spluba();
@@ -831,10 +794,8 @@ qbgetpri()
void
uba_attach(sc, iopagephys)
struct uba_softc *sc;
- unsigned long iopagephys;
+ paddr_t iopagephys;
{
- vm_offset_t mini, maxi;
- extern struct ivec_dsp idsptch;
/*
* Set last free interrupt vector for devices with
@@ -845,34 +806,11 @@ uba_attach(sc, iopagephys)
SIMPLEQ_INIT(&sc->uh_resq);
/*
- * Create interrupt dispatchers for this uba.
- */
-#define NO_IVEC 128
- {
- vm_offset_t iarea;
- int i;
-
- iarea = kmem_alloc(kernel_map,
- NO_IVEC * sizeof(struct ivec_dsp));
- sc->uh_idsp = (struct ivec_dsp *)iarea;
-
- for (i = 0; i < NO_IVEC; i++) {
- bcopy(&idsptch, &sc->uh_idsp[i],
- sizeof(struct ivec_dsp));
- sc->uh_idsp[i].pushlarg = sc->uh_dev.dv_unit;
- sc->uh_idsp[i].hoppaddr = ubastray;
- sc->uh_iarea[i] = (unsigned int)&sc->uh_idsp[i];
- }
- }
- /*
* Allocate place for unibus memory in virtual space.
- * This is done with kmem_suballoc() but after that
- * never used in the vm system. Is it OK to do so?
*/
- (void)kmem_suballoc(kernel_map, &mini, &maxi, UBAIOPAGES * NBPG, FALSE);
- pmap_map(mini, iopagephys, iopagephys + UBAIOPAGES * NBPG,
- VM_PROT_READ|VM_PROT_WRITE);
- sc->uh_iopage = (void *)mini;
+ sc->uh_iopage = (caddr_t)vax_map_physmem(iopagephys, UBAIOPAGES);
+ if (sc->uh_iopage == 0)
+ return; /* vax_map_physmem() will complain for us */
/*
* Initialize the UNIBUS, by freeing the map
* registers and the buffered data path registers
@@ -893,22 +831,21 @@ uba_attach(sc, iopagephys)
/*
* Now start searching for devices.
*/
- config_scan(ubascan,(struct device *)sc);
+ config_search(ubasearch,(struct device *)sc, NULL);
if (sc->uh_afterscan)
(*sc->uh_afterscan)(sc);
}
-void
-ubascan(parent, match)
+int
+ubasearch(parent, cf, aux)
struct device *parent;
- void *match;
+ struct cfdata *cf;
+ void *aux;
{
- struct device *dev = match;
- struct cfdata *cf = dev->dv_cfdata;
struct uba_softc *sc = (struct uba_softc *)parent;
struct uba_attach_args ua;
- int i;
+ int i, vec, br;
ua.ua_addr = (caddr_t)((int)sc->uh_iopage + ubdevreg(cf->cf_loc[0]));
ua.ua_reset = NULL;
@@ -916,8 +853,8 @@ ubascan(parent, match)
if (badaddr(ua.ua_addr, 2) || (sc->uh_errchk ? (*sc->uh_errchk)(sc):0))
goto forgetit;
- rcvec = 0x200;
- i = (*cf->cf_attach->ca_match) (parent, dev, &ua);
+ scb_vecref(0, 0); /* Clear vector ref */
+ i = (*cf->cf_attach->ca_match) (parent, cf, &ua);
if (sc->uh_errchk)
if ((*sc->uh_errchk)(sc))
@@ -925,58 +862,44 @@ ubascan(parent, match)
if (i == 0)
goto forgetit;
- if (rcvec == 0 || rcvec == 0x200)
+ i = scb_vecref(&vec, &br);
+ if (i == 0)
+ goto fail;
+ if (vec == 0)
goto fail;
- sc->uh_idsp[rcvec].hoppaddr = ua.ua_ivec;
- sc->uh_idsp[rcvec].pushlarg = dev->dv_unit;
- if (ua.ua_reset) { /* device wants ubraeset */
+ 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_resarg = (int *)sc->uh_reset + 128;
}
#ifdef DIAGNOSTIC
if (sc->uh_resno > 127) {
- printf("%s: Expand reset table, skipping reset %s\n",
- sc->uh_dev.dv_xname, dev->dv_xname);
+ 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
{
- sc->uh_resarg[sc->uh_resno] = dev->dv_unit;
+ sc->uh_resarg[sc->uh_resno] = cf->cf_unit;
sc->uh_reset[sc->uh_resno++] = ua.ua_reset;
}
}
- ua.ua_br = rbr;
- ua.ua_cvec = rcvec;
- ua.ua_iaddr = dev->dv_cfdata->cf_loc[0];
+ ua.ua_br = br;
+ ua.ua_cvec = vec;
+ ua.ua_iaddr = cf->cf_loc[0];
- config_attach(parent, dev, &ua, ubaprint);
- return;
+ config_attach(parent, cf, &ua, ubaprint);
+ return 0;
fail:
- printf("%s at %s csr %o %s\n", dev->dv_cfdata->cf_driver->cd_name,
- parent->dv_xname, dev->dv_cfdata->cf_loc[0],
- rcvec ? "didn't interrupt\n" : "zero vector\n");
+ printf("%s%d at %s csr %o %s\n",
+ cf->cf_driver->cd_name, cf->cf_unit, parent->dv_xname,
+ cf->cf_loc[0], (i ? "zero vector" : "didn't interrupt"));
forgetit:
- free(dev, M_DEVBUF);
-}
-
-/*
- * Called when a device needs more than one interrupt vector.
- * (Like DHU11, DMF32). Argument is the device's softc, vector
- * number and a function pointer to the interrupt catcher.
- */
-void
-ubasetvec(dev, vec, func)
- struct device *dev;
- int vec;
- void (*func) __P((int));
-{
- struct uba_softc *sc = (void *)dev->dv_parent;
-
- sc->uh_idsp[vec].hoppaddr = func;
- sc->uh_idsp[vec].pushlarg = dev->dv_unit;
+ return 0;
}
/*
@@ -990,6 +913,6 @@ ubaprint(aux, uba)
struct uba_attach_args *ua = aux;
printf(" csr %o vec %o ipl %x", ua->ua_iaddr,
- ua->ua_cvec << 2, ua->ua_br);
+ ua->ua_cvec & 511, ua->ua_br);
return UNCONF;
}