Add sbus_translate() to deal with slot address translations, including
new v3 PROM style "range" properties. This routine is also called from obio.c (which can be viewed upon as just a another Sbus slot).
This commit is contained in:
parent
345295ff08
commit
96f175d477
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sbus.c,v 1.8 1996/03/17 02:01:14 thorpej Exp $ */
|
||||
/* $NetBSD: sbus.c,v 1.9 1996/03/31 22:27:15 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
@ -100,8 +100,9 @@ sbus_match(parent, vcf, aux)
|
||||
register struct confargs *ca = aux;
|
||||
register struct romaux *ra = &ca->ca_ra;
|
||||
|
||||
if (cputyp==CPU_SUN4)
|
||||
if (CPU_ISSUN4)
|
||||
return (0);
|
||||
|
||||
return (strcmp(cf->cf_driver->cd_name, ra->ra_name) == 0);
|
||||
}
|
||||
|
||||
@ -117,8 +118,7 @@ sbus_attach(parent, self, aux)
|
||||
register struct sbus_softc *sc = (struct sbus_softc *)self;
|
||||
struct confargs *ca = aux;
|
||||
register struct romaux *ra = &ca->ca_ra;
|
||||
register int base, node, slot;
|
||||
register int i;
|
||||
register int node;
|
||||
register char *name;
|
||||
struct confargs oca;
|
||||
|
||||
@ -144,6 +144,9 @@ sbus_attach(parent, self, aux)
|
||||
else
|
||||
oca.ca_ra.ra_bp = NULL;
|
||||
|
||||
sc->sc_range = ra->ra_range;
|
||||
sc->sc_nrange = ra->ra_nrange;
|
||||
|
||||
/*
|
||||
* Loop through ROM children, fixing any relative addresses
|
||||
* and then configuring each device.
|
||||
@ -152,23 +155,60 @@ sbus_attach(parent, self, aux)
|
||||
name = getpropstring(node, "name");
|
||||
if (!romprop(&oca.ca_ra, name, node))
|
||||
continue;
|
||||
base = (int)oca.ca_ra.ra_paddr;
|
||||
|
||||
sbus_translate(self, &oca);
|
||||
oca.ca_bustype = BUS_SBUS;
|
||||
(void) config_found(&sc->sc_dev, (void *)&oca, sbus_print);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sbus_translate(dev, ca)
|
||||
struct device *dev;
|
||||
struct confargs *ca;
|
||||
{
|
||||
struct sbus_softc *sc = (struct sbus_softc *)dev;
|
||||
register int base, slot;
|
||||
register int i;
|
||||
|
||||
if (sc->sc_nrange == 0) {
|
||||
/* Old-style Sbus configuration */
|
||||
base = (int)ca->ca_ra.ra_paddr;
|
||||
if (SBUS_ABS(base)) {
|
||||
oca.ca_slot = SBUS_ABS_TO_SLOT(base);
|
||||
oca.ca_offset = SBUS_ABS_TO_OFFSET(base);
|
||||
ca->ca_slot = SBUS_ABS_TO_SLOT(base);
|
||||
ca->ca_offset = SBUS_ABS_TO_OFFSET(base);
|
||||
} else {
|
||||
oca.ca_slot = slot = oca.ca_ra.ra_iospace;
|
||||
oca.ca_offset = base;
|
||||
oca.ca_ra.ra_paddr = (void *)SBUS_ADDR(slot, base);
|
||||
ca->ca_slot = slot = ca->ca_ra.ra_iospace;
|
||||
ca->ca_offset = base;
|
||||
ca->ca_ra.ra_paddr =
|
||||
(void *)SBUS_ADDR(slot, base);
|
||||
/* Fix any remaining register banks */
|
||||
for (i = 1; i < oca.ca_ra.ra_nreg; i++) {
|
||||
base = (int)oca.ca_ra.ra_reg[i].rr_paddr;
|
||||
oca.ca_ra.ra_reg[i].rr_paddr =
|
||||
for (i = 1; i < ca->ca_ra.ra_nreg; i++) {
|
||||
base = (int)ca->ca_ra.ra_reg[i].rr_paddr;
|
||||
ca->ca_ra.ra_reg[i].rr_paddr =
|
||||
(void *)SBUS_ADDR(slot, base);
|
||||
}
|
||||
}
|
||||
oca.ca_bustype = BUS_SBUS;
|
||||
(void) config_found(&sc->sc_dev, (void *)&oca, sbus_print);
|
||||
|
||||
} else {
|
||||
|
||||
ca->ca_slot = ca->ca_ra.ra_iospace;
|
||||
ca->ca_offset = (int)ca->ca_ra.ra_paddr;
|
||||
|
||||
/* Translate into parent address spaces */
|
||||
for (i = 0; i < ca->ca_ra.ra_nreg; i++) {
|
||||
int j, cspace = ca->ca_ra.ra_reg[i].rr_iospace;
|
||||
|
||||
for (j = 0; j < sc->sc_nrange; j++) {
|
||||
if (sc->sc_range[j].cspace == cspace) {
|
||||
(int)ca->ca_ra.ra_reg[i].rr_paddr +=
|
||||
sc->sc_range[j].poffset;
|
||||
(int)ca->ca_ra.ra_reg[i].rr_iospace =
|
||||
sc->sc_range[j].pspace;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,7 +221,25 @@ sbus_establish(sd, dev)
|
||||
register struct sbusdev *sd;
|
||||
register struct device *dev;
|
||||
{
|
||||
register struct sbus_softc *sc = (struct sbus_softc *)dev->dv_parent;
|
||||
register struct sbus_softc *sc;
|
||||
register struct device *curdev;
|
||||
|
||||
/*
|
||||
* We have to look for the sbus by name, since it is not necessarily
|
||||
* our immediate parent (i.e. sun4m /iommu/sbus/espdma/esp)
|
||||
* We don't just use the device structure of the above-attached
|
||||
* sbus, since we might (in the future) support multiple sbus's.
|
||||
*/
|
||||
for (curdev = dev->dv_parent; ; curdev = curdev->dv_parent) {
|
||||
if (!curdev || !curdev->dv_xname)
|
||||
panic("sbus_establish: can't find sbus parent for %s",
|
||||
(sd->sd_dev->dv_xname ? sd->sd_dev->dv_xname :
|
||||
"<unknown>"));
|
||||
|
||||
if (strncmp(curdev->dv_xname, "sbus", 4) == 0)
|
||||
break;
|
||||
}
|
||||
sc = (struct sbus_softc *) curdev;
|
||||
|
||||
sd->sd_dev = dev;
|
||||
sd->sd_bchain = sc->sc_sbdev;
|
||||
|
Loading…
Reference in New Issue
Block a user