From cb4e539861dbd56824e1bc742c6914bee17d1b2e Mon Sep 17 00:00:00 2001 From: Miod Vallat Date: Sat, 5 Mar 2005 01:44:53 +0000 Subject: Preliminary xbox support: attaches, memory mapping and interrupts work, but DMA transfers are not implemented yet, and are disabled (which causes drivers to SBus cards on the xbox to fail to attach). In practice, this allows frame buffers to work, maybe more devices; DMA support will be worked on in the near future. --- sys/arch/sparc64/conf/GENERIC | 6 +- sys/arch/sparc64/conf/RAMDISK | 6 +- sys/arch/sparc64/conf/RAMDISKU1 | 6 +- sys/arch/sparc64/conf/files.sparc64 | 5 +- sys/arch/sparc64/dev/sbus.c | 170 +++++++++++++++++++++++++----------- sys/arch/sparc64/dev/sbusvar.h | 3 +- 6 files changed, 139 insertions(+), 57 deletions(-) (limited to 'sys/arch') diff --git a/sys/arch/sparc64/conf/GENERIC b/sys/arch/sparc64/conf/GENERIC index a79896f2052..96ef6a23b6f 100644 --- a/sys/arch/sparc64/conf/GENERIC +++ b/sys/arch/sparc64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.117 2005/02/15 11:03:46 jsg Exp $ +# $OpenBSD: GENERIC,v 1.118 2005/03/05 01:44:52 miod Exp $ # $NetBSD: GENERIC32,v 1.18 2001/07/20 00:07:12 eeh Exp $ machine sparc64 @@ -315,6 +315,10 @@ pcmcia* at stp? wi* at pci? # WaveLAN IEEE 802.11DS wi* at pcmcia? # WaveLAN IEEE 802.11DS +# ``XBox'' SBus Expansion +xbox* at sbus? +sbus* at xbox? + #pseudo-device hotplug 1 # devices hot plugging # mouse & keyboard multiplexor pseudo-devices diff --git a/sys/arch/sparc64/conf/RAMDISK b/sys/arch/sparc64/conf/RAMDISK index 6b0ed05a48d..be612cd7bf8 100644 --- a/sys/arch/sparc64/conf/RAMDISK +++ b/sys/arch/sparc64/conf/RAMDISK @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK,v 1.38 2005/02/15 11:03:46 jsg Exp $ +# $OpenBSD: RAMDISK,v 1.39 2005/03/05 01:44:52 miod Exp $ # Machine architecture; required by config(8) machine sparc64 @@ -191,6 +191,10 @@ creator* at mainbus0 creator* at upa0 wsdisplay* at creator? +# ``XBox'' SBus Expansion +xbox* at sbus? +sbus* at xbox? + ## PROM console driver -- if all else fails pcons0 at mainbus0 # PROM console diff --git a/sys/arch/sparc64/conf/RAMDISKU1 b/sys/arch/sparc64/conf/RAMDISKU1 index 8af407452c0..ec0fdaed2cf 100644 --- a/sys/arch/sparc64/conf/RAMDISKU1 +++ b/sys/arch/sparc64/conf/RAMDISKU1 @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISKU1,v 1.12 2004/11/29 18:12:50 miod Exp $ +# $OpenBSD: RAMDISKU1,v 1.13 2005/03/05 01:44:52 miod Exp $ # Machine architecture; required by config(8) machine sparc64 @@ -103,6 +103,10 @@ wsdisplay* at vigra? creator* at mainbus0 wsdisplay* at creator? +# ``XBox'' SBus Expansion +xbox* at sbus? +sbus* at xbox? + ## PROM console driver -- if all else fails pcons0 at mainbus0 # PROM console diff --git a/sys/arch/sparc64/conf/files.sparc64 b/sys/arch/sparc64/conf/files.sparc64 index ebc7f74b786..fba2af7a805 100644 --- a/sys/arch/sparc64/conf/files.sparc64 +++ b/sys/arch/sparc64/conf/files.sparc64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.sparc64,v 1.55 2004/10/08 13:04:36 grange Exp $ +# $OpenBSD: files.sparc64,v 1.56 2005/03/05 01:44:52 miod Exp $ # $NetBSD: files.sparc64,v 1.50 2001/08/10 20:53:50 eeh Exp $ # maxpartitions must be first item in files.${ARCH} @@ -67,7 +67,8 @@ file arch/sparc64/sparc64/netbsd_machdep.c compat_netbsd # Sun specific files include "../../../dev/sun/files.sun" -attach sbus at mainbus +attach sbus at mainbus with sbus_mb +attach sbus at xbox with sbus_xbox file arch/sparc64/dev/sbus.c sbus device creator: wsemuldisplaydev, rasops8, rasops16, rasops24, rasops32, wsemul_sun diff --git a/sys/arch/sparc64/dev/sbus.c b/sys/arch/sparc64/dev/sbus.c index df871d30ff6..18c1932ca65 100644 --- a/sys/arch/sparc64/dev/sbus.c +++ b/sys/arch/sparc64/dev/sbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sbus.c,v 1.21 2005/01/27 21:17:50 miod Exp $ */ +/* $OpenBSD: sbus.c,v 1.22 2005/03/05 01:44:52 miod Exp $ */ /* $NetBSD: sbus.c,v 1.46 2001/10/07 20:30:41 eeh Exp $ */ /*- @@ -118,6 +118,7 @@ #include #include #include +#include #include @@ -136,32 +137,37 @@ int sbus_debug = 0; void sbusreset(int); -static bus_space_tag_t sbus_alloc_bustag(struct sbus_softc *); -static bus_dma_tag_t sbus_alloc_dmatag(struct sbus_softc *); -static int sbus_get_intr(struct sbus_softc *, int, +bus_space_tag_t sbus_alloc_bustag(struct sbus_softc *, int); +bus_dma_tag_t sbus_alloc_dmatag(struct sbus_softc *, bus_dma_tag_t); +int sbus_get_intr(struct sbus_softc *, int, struct sbus_intr **, int *, int); -static int sbus_overtemp(void *); -static int _sbus_bus_map(bus_space_tag_t, bus_space_tag_t, +int sbus_overtemp(void *); +int _sbus_bus_map(bus_space_tag_t, bus_space_tag_t, bus_addr_t, /*offset*/ bus_size_t, /*size*/ int, /*flags*/ bus_space_handle_t *); -static void *sbus_intr_establish(bus_space_tag_t, bus_space_tag_t, +void *sbus_intr_establish(bus_space_tag_t, bus_space_tag_t, int, /*Sbus interrupt level*/ int, /*`device class' priority*/ int, /*flags*/ int (*)(void *), /*handler*/ void *, /*handler arg*/ const char *); /*what*/ - +void sbus_attach_common(struct sbus_softc *, int, int); /* autoconfiguration driver */ -int sbus_match(struct device *, void *, void *); -void sbus_attach(struct device *, struct device *, void *); +void sbus_mb_attach(struct device *, struct device *, void *); +void sbus_xbox_attach(struct device *, struct device *, void *); +int sbus_mb_match(struct device *, void *, void *); +int sbus_xbox_match(struct device *, void *, void *); +struct cfattach sbus_mb_ca = { + sizeof(struct sbus_softc), sbus_mb_match, sbus_mb_attach +}; -struct cfattach sbus_ca = { - sizeof(struct sbus_softc), sbus_match, sbus_attach +struct cfattach sbus_xbox_ca = { + sizeof(struct sbus_softc), sbus_xbox_match, sbus_xbox_attach }; struct cfdriver sbus_cd = { @@ -232,7 +238,7 @@ sbus_print(void *args, const char *busname) } int -sbus_match(struct device *parent, void *vcf, void *aux) +sbus_mb_match(struct device *parent, void *vcf, void *aux) { struct cfdata *cf = vcf; struct mainbus_attach_args *ma = aux; @@ -240,35 +246,39 @@ sbus_match(struct device *parent, void *vcf, void *aux) return (strcmp(cf->cf_driver->cd_name, ma->ma_name) == 0); } -/* - * Attach an Sbus. - */ +int +sbus_xbox_match(struct device *parent, void *vcf, void *aux) +{ + struct xbox_softc *xsc = (struct xbox_softc *)parent; + + /* Prevent multiple attachments */ + if (xsc->sc_attached == 0) { + xsc->sc_attached = 1; + return (1); + } + + return (0); +} + void -sbus_attach(struct device *parent, struct device *self, void *aux) +sbus_xbox_attach(struct device *parent, struct device *self, void *aux) { struct sbus_softc *sc = (struct sbus_softc *)self; - struct mainbus_attach_args *ma = aux; - struct intrhand *ih; - struct sysioreg *sysio; - int ipl; - char *name; - int node = ma->ma_node; - int node0, error; - bus_space_tag_t sbt; - struct sbus_attach_args sa; + struct xbox_softc *xsc = (struct xbox_softc *)parent; + struct sbus_softc *sbus = (struct sbus_softc *)parent->dv_parent; + struct xbox_attach_args *xa = aux; + int node = xa->xa_node; - sc->sc_bustag = ma->ma_bustag; - sc->sc_dmatag = ma->ma_dmatag; - /* Find interrupt group no */ - sc->sc_ign = ma->ma_interrupts[0] & INTMAP_IGN; + sc->sc_master = sbus->sc_master; - bus_space_map(sc->sc_bustag, - ma->ma_address[0], sizeof(struct sysioreg), - BUS_SPACE_MAP_PROMADDRESS, &sc->sc_bh); - sysio = bus_space_vaddr(sc->sc_bustag, sc->sc_bh); + sc->sc_bustag = xa->xa_bustag; + sc->sc_dmatag = sbus_alloc_dmatag(sc, xa->xa_dmatag); - /* Setup interrupt translation tables */ - sc->sc_intr2ipl = intr_sbus2ipl_4u; + /* + * Parent has already done the address translation computations. + */ + sc->sc_nrange = xsc->sc_nrange; + sc->sc_range = xsc->sc_range; /* * Record clock frequency for synchronous SCSI. @@ -277,13 +287,26 @@ sbus_attach(struct device *parent, struct device *self, void *aux) sc->sc_clockfreq = getpropint(node, "clock-frequency", 25*1000*1000); printf(": clock = %s MHz\n", clockfreq(sc->sc_clockfreq)); - sbt = sbus_alloc_bustag(sc); - sc->sc_dmatag = sbus_alloc_dmatag(sc); + sbus_attach_common(sc, node, 1); +} - /* - * Get the SBus burst transfer size if burst transfers are supported - */ - sc->sc_burst = getpropint(node, "burst-sizes", 0); +void +sbus_mb_attach(struct device *parent, struct device *self, void *aux) +{ + struct sbus_softc *sc = (struct sbus_softc *)self; + struct mainbus_attach_args *ma = aux; + int node = ma->ma_node; + struct intrhand *ih; + int ipl, error; + struct sysioreg *sysio; + char *name; + + sc->sc_master = sc; + + sc->sc_bustag = ma->ma_bustag; + + /* Find interrupt group no */ + sc->sc_ign = ma->ma_interrupts[0] & INTMAP_IGN; /* * Collect address translations from the OBP. @@ -293,6 +316,18 @@ sbus_attach(struct device *parent, struct device *self, void *aux) if (error) panic("%s: error getting ranges property", sc->sc_dev.dv_xname); + /* + * Record clock frequency for synchronous SCSI. + * IS THIS THE CORRECT DEFAULT?? + */ + sc->sc_clockfreq = getpropint(node, "clock-frequency", 25*1000*1000); + printf(": clock = %s MHz\n", clockfreq(sc->sc_clockfreq)); + + bus_space_map(sc->sc_bustag, + ma->ma_address[0], sizeof(struct sysioreg), + BUS_SPACE_MAP_PROMADDRESS, &sc->sc_bh); + sysio = bus_space_vaddr(sc->sc_bustag, sc->sc_bh); + /* initialize the IOMMU */ /* punch in our copies */ @@ -351,6 +386,31 @@ sbus_attach(struct device *parent, struct device *self, void *aux) panic("sbus iommu: can't toss first dvma page"); } + sc->sc_dmatag = sbus_alloc_dmatag(sc, ma->ma_dmatag); + + sbus_attach_common(sc, node, 0); +} + +/* + * Attach an Sbus (main part). + */ +void +sbus_attach_common(struct sbus_softc *sc, int node, int indirect) +{ + bus_space_tag_t sbt; + struct sbus_attach_args sa; + int node0; + + /* Setup interrupt translation tables */ + sc->sc_intr2ipl = intr_sbus2ipl_4u; + + sbt = sbus_alloc_bustag(sc, indirect); + + /* + * Get the SBus burst transfer size if burst transfers are supported + */ + sc->sc_burst = getpropint(node, "burst-sizes", 0); + /* * Loop through ROM children, fixing any relative addresses * and then configuring each device. @@ -512,7 +572,7 @@ sbus_establish(struct sbusdev *sd, struct device *dev) * 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. + * sbus, since we support multiple sbus's. */ for (curdev = dev->dv_parent; ; curdev = curdev->dv_parent) { if (!curdev || !curdev->dv_xname) @@ -657,6 +717,9 @@ sbus_intr_establish(bus_space_tag_t t, bus_space_tag_t t0, int pri, int level, int ipl; long vec = pri; + /* Pick the master SBus as all do not have IOMMU registers */ + sc = sc->sc_master; + sysio = bus_space_vaddr(sc->sc_bustag, sc->sc_bh); if ((flags & BUS_INTR_ESTABLISH_SOFTINTR) != 0) @@ -760,8 +823,8 @@ sbus_intr_establish(bus_space_tag_t t, bus_space_tag_t t0, int pri, int level, return (ih); } -static bus_space_tag_t -sbus_alloc_bustag(struct sbus_softc *sc) +bus_space_tag_t +sbus_alloc_bustag(struct sbus_softc *sc, int indirect) { struct sparc_bus_space_tag *sbt; @@ -773,7 +836,10 @@ sbus_alloc_bustag(struct sbus_softc *sc) snprintf(sbt->name, sizeof(sbt->name), "%s", sc->sc_dev.dv_xname); sbt->cookie = sc; - sbt->parent = sc->sc_bustag; + if (indirect) + sbt->parent = sc->sc_bustag->parent; + else + sbt->parent = sc->sc_bustag; sbt->default_type = SBUS_BUS_SPACE; sbt->asi = ASI_PRIMARY; sbt->sasi = ASI_PRIMARY; @@ -784,10 +850,10 @@ sbus_alloc_bustag(struct sbus_softc *sc) } -static bus_dma_tag_t -sbus_alloc_dmatag(struct sbus_softc *sc) +bus_dma_tag_t +sbus_alloc_dmatag(struct sbus_softc *sc, bus_dma_tag_t psdt) { - bus_dma_tag_t sdt, psdt = sc->sc_dmatag; + bus_dma_tag_t sdt; sdt = (bus_dma_tag_t) malloc(sizeof(struct sparc_bus_dma_tag), M_DEVBUF, M_NOWAIT); @@ -807,7 +873,6 @@ sbus_alloc_dmatag(struct sbus_softc *sc) sdt->_dmamem_free = iommu_dvmamem_free; sdt->_dmamem_map = iommu_dvmamem_map; sdt->_dmamem_unmap = iommu_dvmamem_unmap; - sc->sc_dmatag = sdt; return (sdt); } @@ -818,7 +883,10 @@ sbus_dmamap_create(bus_dma_tag_t t, bus_dma_tag_t t0, bus_size_t size, { struct sbus_softc *sc = t->_cookie; + /* Disallow DMA on secondary SBuses for now */ + if (sc != sc->sc_master) + return (EINVAL); + return (iommu_dvmamap_create(t, t0, &sc->sc_sb, size, nsegments, maxsegsz, boundary, flags, dmamp)); } - diff --git a/sys/arch/sparc64/dev/sbusvar.h b/sys/arch/sparc64/dev/sbusvar.h index f05ea6d05eb..cb3715c76a6 100644 --- a/sys/arch/sparc64/dev/sbusvar.h +++ b/sys/arch/sparc64/dev/sbusvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sbusvar.h,v 1.6 2003/06/02 23:27:55 millert Exp $ */ +/* $OpenBSD: sbusvar.h,v 1.7 2005/03/05 01:44:52 miod Exp $ */ /* $NetBSD: sbusvar.h,v 1.7 1999/06/05 05:30:43 mrg Exp $ */ /*- @@ -111,6 +111,7 @@ struct sbus_softc { struct iommu_state sc_is; /* IOMMU state, see iommureg.h */ struct strbuf_ctl sc_sb; /* Streaming buffer control */ int64_t sc_flush; /* Streaming buffer flush */ + struct sbus_softc *sc_master; /* main SBus */ }; bus_addr_t sbus_bus_addr(bus_space_tag_t, u_int, u_int); -- cgit v1.2.3