summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/sgi/pci/ioc.c9
-rw-r--r--sys/arch/sgi/sgi/ip27_machdep.c11
-rw-r--r--sys/arch/sgi/sgi/ip30_machdep.c9
-rw-r--r--sys/arch/sgi/xbow/xbow.c121
-rw-r--r--sys/arch/sgi/xbow/xbow.h17
-rw-r--r--sys/arch/sgi/xbow/xbridge.c187
6 files changed, 129 insertions, 225 deletions
diff --git a/sys/arch/sgi/pci/ioc.c b/sys/arch/sgi/pci/ioc.c
index 01a21ea1e39..a19240806f4 100644
--- a/sys/arch/sgi/pci/ioc.c
+++ b/sys/arch/sgi/pci/ioc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ioc.c,v 1.17 2009/06/21 18:03:15 miod Exp $ */
+/* $OpenBSD: ioc.c,v 1.18 2009/07/01 21:56:37 miod Exp $ */
/*
* Copyright (c) 2008 Joel Sing.
@@ -182,12 +182,13 @@ ioc_attach(struct device *parent, struct device *self, void *aux)
sc->sc_mem_bus_space->bus_base = memh;
sc->sc_mem_bus_space->_space_read_1 = xbow_read_1;
sc->sc_mem_bus_space->_space_read_2 = xbow_read_2;
+ sc->sc_mem_bus_space->_space_read_raw_2 = xbow_read_raw_2;
sc->sc_mem_bus_space->_space_write_1 = xbow_write_1;
sc->sc_mem_bus_space->_space_write_2 = xbow_write_2;
+ sc->sc_mem_bus_space->_space_write_raw_2 = xbow_write_raw_2;
- /* XXX undo IP27 xbridge weird mapping */
- if (sys_config.system_type != SGI_OCTANE)
- sc->sc_mem_bus_space->_space_map = xbow_space_map_short;
+ /* XXX undo xbridge mapping games */
+ sc->sc_mem_bus_space->_space_map = xbow_space_map;
sc->sc_memt = sc->sc_mem_bus_space;
sc->sc_memh = memh;
diff --git a/sys/arch/sgi/sgi/ip27_machdep.c b/sys/arch/sgi/sgi/ip27_machdep.c
index a5b30009f12..b4a3164d567 100644
--- a/sys/arch/sgi/sgi/ip27_machdep.c
+++ b/sys/arch/sgi/sgi/ip27_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip27_machdep.c,v 1.14 2009/06/13 21:48:03 miod Exp $ */
+/* $OpenBSD: ip27_machdep.c,v 1.15 2009/07/01 21:56:38 miod Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -55,6 +55,8 @@ int ip27_widget_id(int16_t, u_int, uint32_t *);
void ip27_halt(int);
+unsigned int xbow_long_shift = 29;
+
static paddr_t io_base;
static gda_t *gda;
static int ip35 = 0;
@@ -84,8 +86,7 @@ ip27_setup()
ip35 = sys_config.system_type == SGI_O300;
- xbow_widget_short = ip27_widget_short;
- xbow_widget_long = ip27_widget_long;
+ xbow_widget_base = ip27_widget_short;
xbow_widget_id = ip27_widget_id;
md_halt = ip27_halt;
@@ -139,8 +140,8 @@ ip27_setup()
* This assumes IOC3 is accessible through a widget small window.
*/
- xbow_build_bus_space(&sys_config.console_io, 0, 8 /* whatever */, 0);
- /* Constrain to a short window */
+ xbow_build_bus_space(&sys_config.console_io, 0, 8 /* whatever */);
+ /* Constrain to the correct window */
sys_config.console_io.bus_base =
kl_get_console_base() & 0xffffffffff000000UL;
diff --git a/sys/arch/sgi/sgi/ip30_machdep.c b/sys/arch/sgi/sgi/ip30_machdep.c
index 2d021396b44..ef53cf1c1ac 100644
--- a/sys/arch/sgi/sgi/ip30_machdep.c
+++ b/sys/arch/sgi/sgi/ip30_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip30_machdep.c,v 1.6 2009/04/18 14:48:08 miod Exp $ */
+/* $OpenBSD: ip30_machdep.c,v 1.7 2009/07/01 21:56:38 miod Exp $ */
/*
* Copyright (c) 2008 Miodrag Vallat.
@@ -93,8 +93,7 @@ ip30_setup()
}
#endif
- xbow_widget_short = ip30_widget_short;
- xbow_widget_long = ip30_widget_long;
+ xbow_widget_base = ip30_widget_short;
xbow_widget_id = ip30_widget_id;
/*
@@ -111,8 +110,8 @@ ip30_setup()
* exactly what we need, since the IOC3 doesn't need any. Some
* may consider this an evil abuse of bus_space knowledge, though.
*/
- xbow_build_bus_space(&sys_config.console_io, 0, 15, 1);
- sys_config.console_io.bus_base += BRIDGE_PCI_MEM_SPACE_BASE;
+ xbow_build_bus_space(&sys_config.console_io, 0, 15);
+ sys_config.console_io.bus_base = ip30_widget_short(0, 15);
comconsaddr = 0x500000 + IOC3_UARTA_BASE;
comconsfreq = 22000000 / 3;
diff --git a/sys/arch/sgi/xbow/xbow.c b/sys/arch/sgi/xbow/xbow.c
index 743c4283e38..f7e19526de9 100644
--- a/sys/arch/sgi/xbow/xbow.c
+++ b/sys/arch/sgi/xbow/xbow.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xbow.c,v 1.12 2009/06/27 22:21:31 miod Exp $ */
+/* $OpenBSD: xbow.c,v 1.13 2009/07/01 21:56:38 miod Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -87,10 +87,6 @@ uint32_t xbow_read_4(bus_space_tag_t, bus_space_handle_t, bus_size_t);
uint64_t xbow_read_8(bus_space_tag_t, bus_space_handle_t, bus_size_t);
void xbow_write_4(bus_space_tag_t, bus_space_handle_t, bus_size_t, uint32_t);
void xbow_write_8(bus_space_tag_t, bus_space_handle_t, bus_size_t, uint64_t);
-void xbow_read_raw_2(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
- uint8_t *, bus_size_t);
-void xbow_write_raw_2(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
- const uint8_t *, bus_size_t);
void xbow_read_raw_4(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
uint8_t *, bus_size_t);
void xbow_write_raw_4(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
@@ -100,12 +96,8 @@ void xbow_read_raw_8(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
void xbow_write_raw_8(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
const uint8_t *, bus_size_t);
-int xbow_space_map_long(bus_space_tag_t, bus_addr_t, bus_size_t, int,
- bus_space_handle_t *);
void xbow_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t);
-int xbow_space_region_short(bus_space_tag_t, bus_space_handle_t, bus_size_t,
- bus_size_t, bus_space_handle_t *);
-int xbow_space_region_long(bus_space_tag_t, bus_space_handle_t, bus_size_t,
+int xbow_space_region(bus_space_tag_t, bus_space_handle_t, bus_size_t,
bus_size_t, bus_space_handle_t *);
void *xbow_space_vaddr(bus_space_tag_t, bus_space_handle_t);
@@ -119,7 +111,7 @@ struct cfdriver xbow_cd = {
NULL, "xbow", DV_DULL
};
-static const bus_space_t xbowbus_short_tag = {
+static const bus_space_t xbowbus_tag = {
NULL,
(bus_addr_t)0, /* will be modified in widgets bus_space_t */
NULL,
@@ -138,34 +130,9 @@ static const bus_space_t xbowbus_short_tag = {
xbow_write_raw_4,
xbow_read_raw_8,
xbow_write_raw_8,
- xbow_space_map_short,
+ xbow_space_map,
xbow_space_unmap,
- xbow_space_region_short
-
-};
-
-static const bus_space_t xbowbus_long_tag = {
- NULL,
- (bus_addr_t)0, /* will be modified in widgets bus_space_t */
- NULL,
- 0,
- xbow_read_1,
- xbow_write_1,
- xbow_read_2,
- xbow_write_2,
- xbow_read_4,
- xbow_write_4,
- xbow_read_8,
- xbow_write_8,
- xbow_read_raw_2,
- xbow_write_raw_2,
- xbow_read_raw_4,
- xbow_write_raw_4,
- xbow_read_raw_8,
- xbow_write_raw_8,
- xbow_space_map_long,
- xbow_space_unmap,
- xbow_space_region_long
+ xbow_space_region
};
@@ -173,9 +140,7 @@ static const bus_space_t xbowbus_long_tag = {
* Function pointers to hide widget window mapping differences accross
* systems.
*/
-paddr_t (*xbow_widget_short)(int16_t, u_int);
-paddr_t (*xbow_widget_long)(int16_t, u_int);
-unsigned int xbow_long_shift = 29;
+paddr_t (*xbow_widget_base)(int16_t, u_int);
int (*xbow_widget_id)(int16_t, u_int, uint32_t *);
@@ -390,26 +355,16 @@ xbow_attach_widget(struct device *self, int16_t nasid, int widget,
{
struct xbow_attach_args xaa;
uint32_t wid;
- struct mips_bus_space *bs, *bl;
+ struct mips_bus_space bs;
int rc;
if ((rc = xbow_widget_id(nasid, widget, &wid)) != 0)
return rc;
/*
- * Build a pair of bus_space_t suitable for this widget.
+ * Build a bus_space_t suitable for this widget.
*/
- bs = malloc(sizeof (*bs), M_DEVBUF, M_NOWAIT);
- if (bs == NULL)
- return ENOMEM;
- bl = malloc(sizeof (*bl), M_DEVBUF, M_NOWAIT);
- if (bl == NULL) {
- free(bs, M_DEVBUF);
- return ENOMEM;
- }
-
- xbow_build_bus_space(bs, nasid, widget, 0);
- xbow_build_bus_space(bl, nasid, widget, 1);
+ xbow_build_bus_space(&bs, nasid, widget);
xaa.xaa_nasid = nasid;
xaa.xaa_widget = widget;
@@ -418,16 +373,10 @@ xbow_attach_widget(struct device *self, int16_t nasid, int widget,
xaa.xaa_product = (wid & WIDGET_ID_PRODUCT_MASK) >>
WIDGET_ID_PRODUCT_SHIFT;
xaa.xaa_revision = (wid & WIDGET_ID_REV_MASK) >> WIDGET_ID_REV_SHIFT;
- xaa.xaa_short_tag = bs;
- xaa.xaa_long_tag = bl;
-
- if (config_found_sm(self, &xaa, print, sm) == NULL) {
- /* nothing attached, no need to keep the bus_space */
- free(bs, M_DEVBUF);
- free(bl, M_DEVBUF);
+ xaa.xaa_iot = &bs;
+ if (config_found_sm(self, &xaa, print, sm) == NULL)
return ENOENT;
- }
return 0;
}
@@ -513,15 +462,10 @@ xbow_kl_search_mplane(klinfo_t *c, void *arg)
*/
void
-xbow_build_bus_space(struct mips_bus_space *bs, int nasid, int widget, int lwin)
+xbow_build_bus_space(struct mips_bus_space *bs, int nasid, int widget)
{
- if (lwin) {
- bcopy(&xbowbus_long_tag, bs, sizeof (*bs));
- bs->bus_base = (*xbow_widget_long)(nasid, widget);
- } else {
- bcopy(&xbowbus_short_tag, bs, sizeof (*bs));
- bs->bus_base = (*xbow_widget_short)(nasid, widget);
- }
+ bcopy(&xbowbus_tag, bs, sizeof (*bs));
+ bs->bus_base = (*xbow_widget_base)(nasid, widget);
}
uint8_t
@@ -645,7 +589,7 @@ xbow_write_raw_8(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
}
int
-xbow_space_map_short(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
+xbow_space_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
int cacheable, bus_space_handle_t *bshp)
{
bus_addr_t bpa;
@@ -660,48 +604,15 @@ xbow_space_map_short(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
return 0;
}
-int
-xbow_space_map_long(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
- int cacheable, bus_space_handle_t *bshp)
-{
- bus_addr_t bpa;
-
- bpa = t->bus_base + offs;
-
- /* check that this does not overflow the window */
- if (((bpa + size - 1) >> xbow_long_shift) !=
- (t->bus_base >> xbow_long_shift))
- return (EINVAL);
-
- *bshp = bpa;
- return 0;
-}
-
void
xbow_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
{
}
int
-xbow_space_region_short(bus_space_tag_t t, bus_space_handle_t bsh,
- bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
-{
- /* check that this does not overflow the window */
- if (((bsh + offset) >> 24) != (bsh >> 24))
- return (EINVAL);
-
- *nbshp = bsh + offset;
- return 0;
-}
-
-int
-xbow_space_region_long(bus_space_tag_t t, bus_space_handle_t bsh,
+xbow_space_region(bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
{
- /* check that this does not overflow the window */
- if (((bsh + offset) >> xbow_long_shift) != (bsh >> xbow_long_shift))
- return (EINVAL);
-
*nbshp = bsh + offset;
return 0;
}
diff --git a/sys/arch/sgi/xbow/xbow.h b/sys/arch/sgi/xbow/xbow.h
index d7f0e5337b6..545c355a688 100644
--- a/sys/arch/sgi/xbow/xbow.h
+++ b/sys/arch/sgi/xbow/xbow.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: xbow.h,v 1.4 2009/06/13 21:48:03 miod Exp $ */
+/* $OpenBSD: xbow.h,v 1.5 2009/07/01 21:56:38 miod Exp $ */
/*
* Copyright (c) 2008 Miodrag Vallat.
@@ -39,9 +39,7 @@
* two parameters needed to map a widget.
*/
-extern paddr_t (*xbow_widget_short)(int16_t, u_int);
-extern paddr_t (*xbow_widget_long)(int16_t, u_int);
-extern unsigned int xbow_long_shift;
+extern paddr_t (*xbow_widget_base)(int16_t, u_int);
extern int (*xbow_widget_id)(int16_t, u_int, uint32_t *);
extern int xbow_intr_widget;
@@ -115,21 +113,24 @@ struct xbow_attach_args {
uint32_t xaa_product;
uint32_t xaa_revision;
- bus_space_tag_t xaa_short_tag;
- bus_space_tag_t xaa_long_tag;
+ bus_space_tag_t xaa_iot;
};
-void xbow_build_bus_space(struct mips_bus_space *, int, int, int);
+void xbow_build_bus_space(struct mips_bus_space *, int, int);
int xbow_intr_register(int, int, int *);
int xbow_intr_establish(int (*)(void *), void *, int, int, const char *);
void xbow_intr_disestablish(int);
-int xbow_space_map_short(bus_space_tag_t, bus_addr_t, bus_size_t, int,
+int xbow_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
bus_space_handle_t *);
uint8_t xbow_read_1(bus_space_tag_t, bus_space_handle_t, bus_size_t);
uint16_t xbow_read_2(bus_space_tag_t, bus_space_handle_t, bus_size_t);
+void xbow_read_raw_2(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
+ uint8_t *, bus_size_t);
void xbow_write_1(bus_space_tag_t, bus_space_handle_t, bus_size_t, uint8_t);
void xbow_write_2(bus_space_tag_t, bus_space_handle_t, bus_size_t,
uint16_t);
+void xbow_write_raw_2(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
+ const uint8_t *, bus_size_t);
#endif /* _XBOW_H_ */
diff --git a/sys/arch/sgi/xbow/xbridge.c b/sys/arch/sgi/xbow/xbridge.c
index 7d76266c87d..a5abd41cf2c 100644
--- a/sys/arch/sgi/xbow/xbridge.c
+++ b/sys/arch/sgi/xbow/xbridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xbridge.c,v 1.30 2009/06/28 21:52:54 miod Exp $ */
+/* $OpenBSD: xbridge.c,v 1.31 2009/07/01 21:56:38 miod Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -66,16 +66,15 @@ struct xbridge_softc {
#define XBRIDGE_FLAGS_XBRIDGE 0x01 /* is XBridge vs Bridge */
int16_t sc_nasid;
int sc_widget;
+ uint sc_devio_skew;
struct mips_pci_chipset sc_pc;
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_regh;
+
struct mips_bus_space *sc_mem_bus_space;
struct mips_bus_space *sc_io_bus_space;
struct machine_bus_dma_tag *sc_dmat;
- struct extent *sc_mem_ex;
- struct extent *sc_io_ex;
-
- bus_space_tag_t sc_iot;
- bus_space_handle_t sc_regh;
int sc_intrbit[BRIDGE_NINTRS];
struct xbridge_intr *sc_intr[BRIDGE_NINTRS];
@@ -154,7 +153,7 @@ void xbridge_setup(struct xbridge_softc *);
void xbridge_ate_setup(struct xbridge_softc *);
void xbridge_resource_explore(struct xbridge_softc *, pcitag_t,
- int *, int *);
+ uint *, uint *);
void xbridge_resource_manage(struct xbridge_softc *, pcitag_t,
struct extent *, int);
void xbridge_resource_setup(struct xbridge_softc *);
@@ -206,7 +205,6 @@ xbridge_attach(struct device *parent, struct device *self, void *aux)
struct xbridge_softc *sc = (struct xbridge_softc *)self;
struct pcibus_attach_args pba;
struct xbow_attach_args *xaa = aux;
- int direct_io_avail = 0;
sc->sc_nasid = xaa->xaa_nasid;
sc->sc_widget = xaa->xaa_widget;
@@ -220,10 +218,14 @@ xbridge_attach(struct device *parent, struct device *self, void *aux)
* Map Bridge registers.
*/
- sc->sc_iot = xaa->xaa_short_tag;
+ sc->sc_iot = malloc(sizeof (*sc->sc_iot), M_DEVBUF, M_NOWAIT);
+ if (sc->sc_iot == NULL)
+ goto fail0;
+ bcopy(xaa->xaa_iot, sc->sc_iot, sizeof (*sc->sc_iot));
if (bus_space_map(sc->sc_iot, 0, BRIDGE_REGISTERS_SIZE, 0,
&sc->sc_regh)) {
printf("%s: unable to map control registers\n", self->dv_xname);
+ free(sc->sc_iot, M_DEVBUF);
return;
}
@@ -243,57 +245,53 @@ xbridge_attach(struct device *parent, struct device *self, void *aux)
goto fail2;
#ifdef notyet
- /* Unrestricted memory mappings in the large window */
- bcopy(xaa->xaa_long_tag, sc->sc_mem_bus_space,
+ /*
+ * Memory mappings are available in the widget at
+ * offset BRIDGE_PCI_MEM_SPACE_BASE onwards.
+ */
+ bcopy(xaa->xaa_iot, sc->sc_mem_bus_space,
sizeof(*sc->sc_mem_bus_space));
+ sc->sc_mem_bus_space->bus_base = ...
sc->sc_mem_ex = extent_create("pcimem",
0, BRIDGE_PCI_MEM_SPACE_LENGTH - 1,
M_DEVBUF, NULL, 0, EX_NOWAIT);
sc->sc_mem_bus_space->_space_map = xbridge_space_map_mem;
#else
/* Programmable memory mappings in the small window */
- bcopy(xaa->xaa_short_tag, sc->sc_mem_bus_space,
+ bcopy(xaa->xaa_iot, sc->sc_mem_bus_space,
sizeof(*sc->sc_mem_bus_space));
sc->sc_mem_bus_space->_space_map = xbridge_space_map_devio;
#endif
+ sc->sc_mem_bus_space->bus_private = sc;
+ sc->sc_mem_bus_space->_space_read_1 = xbridge_read_1;
+ sc->sc_mem_bus_space->_space_write_1 = xbridge_write_1;
+ sc->sc_mem_bus_space->_space_read_2 = xbridge_read_2;
+ sc->sc_mem_bus_space->_space_write_2 = xbridge_write_2;
+ sc->sc_mem_bus_space->_space_read_raw_2 = xbridge_read_raw_2;
+ sc->sc_mem_bus_space->_space_write_raw_2 = xbridge_write_raw_2;
+
+#ifdef notyet
+ /*
+ * I/O mappings are available in the widget at
+ * offset BRIDGE_PCI_IO_SPACE_BASE onwards, but
+ * weren't working correctly until Bridge revision 4.
+ */
if (ISSET(sc->sc_flags, XBRIDGE_FLAGS_XBRIDGE) ||
xaa->xaa_revision >= 4) {
- switch (sys_config.system_type) {
- default:
-#if defined(TGT_ORIGIN200) || defined(TGT_ORIGIN2000)
- case SGI_O200:
- case SGI_O300:
- /*
- * In N mode, the large window is truncated and the
- * direct I/O area is not accessible.
- */
- if (kl_n_mode == 0)
- direct_io_avail = 1;
- break;
-#endif
-#if defined(TGT_OCTANE)
- case SGI_OCTANE:
- direct_io_avail = 1;
- break;
-#endif
- }
- }
-#ifdef notyet
- if (direct_io_avail) {
-#else
- if (0) {
-#endif
/* Unrestricted I/O mappings in the large window */
- bcopy(xaa->xaa_long_tag, sc->sc_io_bus_space,
+ bcopy(xaa->xaa_iot, sc->sc_io_bus_space,
sizeof(*sc->sc_io_bus_space));
+ sc->sc_io_bus_space->bus_base = ...
sc->sc_io_ex = extent_create("pciio",
0, BRIDGE_PCI_IO_SPACE_LENGTH - 1,
M_DEVBUF, NULL, 0, EX_NOWAIT);
sc->sc_io_bus_space->_space_map = xbridge_space_map_io;
- } else {
+ } else
+#endif
+ {
/* Programmable I/O mappings in the small window */
- bcopy(xaa->xaa_short_tag, sc->sc_io_bus_space,
+ bcopy(xaa->xaa_iot, sc->sc_io_bus_space,
sizeof(*sc->sc_io_bus_space));
sc->sc_io_bus_space->_space_map = xbridge_space_map_devio;
}
@@ -306,14 +304,6 @@ xbridge_attach(struct device *parent, struct device *self, void *aux)
sc->sc_io_bus_space->_space_read_raw_2 = xbridge_read_raw_2;
sc->sc_io_bus_space->_space_write_raw_2 = xbridge_write_raw_2;
- sc->sc_mem_bus_space->bus_private = sc;
- sc->sc_mem_bus_space->_space_read_1 = xbridge_read_1;
- sc->sc_mem_bus_space->_space_write_1 = xbridge_write_1;
- sc->sc_mem_bus_space->_space_read_2 = xbridge_read_2;
- sc->sc_mem_bus_space->_space_write_2 = xbridge_write_2;
- sc->sc_mem_bus_space->_space_read_raw_2 = xbridge_read_raw_2;
- sc->sc_mem_bus_space->_space_write_raw_2 = xbridge_write_raw_2;
-
sc->sc_dmat = malloc(sizeof (*sc->sc_dmat), M_DEVBUF, M_NOWAIT);
if (sc->sc_dmat == NULL)
goto fail3;
@@ -353,8 +343,8 @@ xbridge_attach(struct device *parent, struct device *self, void *aux)
pba.pba_iot = sc->sc_io_bus_space;
pba.pba_memt = sc->sc_mem_bus_space;
pba.pba_dmat = sc->sc_dmat;
- pba.pba_ioex = sc->sc_io_ex;
- pba.pba_memex = sc->sc_mem_ex;
+ pba.pba_ioex = NULL;
+ pba.pba_memex = NULL;
pba.pba_pc = &sc->sc_pc;
pba.pba_domain = pci_ndomains++;
pba.pba_bus = 0;
@@ -367,6 +357,8 @@ fail3:
fail2:
free(sc->sc_mem_bus_space, M_DEVBUF);
fail1:
+ free(sc->sc_iot, M_DEVBUF);
+fail0:
printf("%s: not enough memory to build access structures\n",
self->dv_xname);
return;
@@ -882,7 +874,7 @@ xbridge_space_map_devio(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
bus_addr_t bpa, start, end;
uint d;
- if ((offs >> 24) != sc->sc_widget)
+ if ((offs >> 24) != sc->sc_devio_skew)
return EINVAL; /* not a devio mapping */
/*
@@ -912,6 +904,7 @@ xbridge_space_map_devio(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
return 0;
}
+#ifdef notyet
int
xbridge_space_map_io(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
int cacheable, bus_space_handle_t *bshp)
@@ -923,7 +916,7 @@ xbridge_space_map_io(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
* window.
*/
- if ((offs >> 24) == sc->sc_widget)
+ if ((offs >> 24) == sc->sc_devio_skew)
return xbridge_space_map_devio(t, offs, size, cacheable, bshp);
/* check that this doesn't overflow the window */
@@ -945,7 +938,7 @@ xbridge_space_map_mem(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
* window.
*/
- if ((offs >> 24) == sc->sc_widget)
+ if ((offs >> 24) == sc->sc_devio_skew)
return xbridge_space_map_devio(t, offs, size, cacheable, bshp);
/* check that this doesn't overflow the window */
@@ -955,6 +948,7 @@ xbridge_space_map_mem(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
*bshp = t->bus_base + BRIDGE_PCI_MEM_SPACE_BASE + offs;
return 0;
}
+#endif
/*
********************* bus_dma helpers
@@ -1794,10 +1788,30 @@ xbridge_resource_setup(struct xbridge_softc *sc)
pcireg_t id, bhlcr;
const struct pci_quirkdata *qd;
uint32_t devio, basewin;
- int io, mem;
+ uint io, mem;
int need_setup;
struct extent *ex;
+ /*
+ * Figure out where the devio mappings will lie in the widget.
+ * On Octane (at least for the on-board devices widget), they are
+ * relative to the beginning of the widget.
+ * On other systems, they are offset an address multiple of the
+ * widget number.
+ *
+ * We could remap everything to the beginning of the widget, but
+ * since we need serial console mappings early, we can not afford
+ * changing how ARCS maps the IOC device.
+ */
+
+ sc->sc_devio_skew = sc->sc_widget;
+ if (sys_config.system_type == SGI_OCTANE) {
+#if 0 /* no reason not to expect all octane xbridge to behave the same way */
+ if (sc->sc_widget == WIDGET_MAX)
+#endif
+ sc->sc_devio_skew = 0;
+ }
+
for (dev = 0; dev < BRIDGE_NSLOTS; dev++) {
id = sc->sc_devices[dev];
@@ -1812,8 +1826,9 @@ xbridge_resource_setup(struct xbridge_softc *sc)
*/
devio = bus_space_read_4(sc->sc_iot, sc->sc_regh,
BRIDGE_DEVICE(dev));
+ basewin = (sc->sc_widget << 24) | BRIDGE_DEVIO_OFFS(dev);
need_setup = ((devio & BRIDGE_DEVICE_BASE_MASK) >>
- (24 - BRIDGE_DEVICE_BASE_SHIFT)) != sc->sc_widget;
+ (24 - BRIDGE_DEVICE_BASE_SHIFT)) != sc->sc_devio_skew;
/*
* On Octane, the firmware will setup the I/O registers
@@ -1825,17 +1840,12 @@ xbridge_resource_setup(struct xbridge_softc *sc)
need_setup = 0;
if (need_setup) {
- basewin =
- (sc->sc_widget << 24) | BRIDGE_DEVIO_OFFS(dev);
-
devio &= ~BRIDGE_DEVICE_BASE_MASK;
/*
- * XXX This defaults to I/O resources only.
- * XXX However some devices may carry only
- * XXX memory mappings.
- * XXX This code should assign devio in a more
- * XXX flexible way...
+ * Default to I/O resources only for now.
+ * If we setup memory resources, this bit
+ * will be flipped later on.
*/
devio &= ~BRIDGE_DEVICE_IO_MEM;
@@ -1855,25 +1865,14 @@ xbridge_resource_setup(struct xbridge_softc *sc)
devio);
(void)bus_space_read_4(sc->sc_iot, sc->sc_regh, WIDGET_TFLUSH);
- /*
- * If we can manage I/O and memory resource allocation in
- * the MI code, we do not need to do anything more at this
- * stage...
- */
-
- if (sc->sc_io_ex != NULL && sc->sc_mem_ex != NULL)
+ if (need_setup == 0)
continue;
/*
- * ...otherwise, we need to perform the resource allocation
- * ourselves, within the devio window we have configured
- * above, for the devices which have not been setup by the
- * firmware already.
+ * We now need to perform the resource allocation for this
+ * device, which has not been setup by ARCS.
*/
- if (need_setup == 0)
- continue;
-
ex = extent_create("pcires",
basewin, basewin + BRIDGE_DEVIO_SIZE(dev) - 1,
M_DEVBUF, NULL, 0, EX_NOWAIT);
@@ -1895,7 +1894,6 @@ xbridge_resource_setup(struct xbridge_softc *sc)
*/
io = mem = 0;
-
for (function = 0; function < nfuncs; function++) {
tag = pci_make_tag(pc, 0, dev, function);
id = pci_conf_read(pc, tag, PCI_ID_REG);
@@ -1908,10 +1906,6 @@ xbridge_resource_setup(struct xbridge_softc *sc)
}
/*
- * As long as the memory area in the large window
- * isn't working as well as we'd like it to,
- * we can only use devio mappings in the short window.
- *
* For devices having both I/O and memory resources, we
* favour the I/O resources so far. Eventually this code
* should attempt to steal a devio from an unpopulated
@@ -1945,7 +1939,7 @@ xbridge_resource_setup(struct xbridge_softc *sc)
void
xbridge_resource_explore(struct xbridge_softc *sc, pcitag_t tag,
- int *nio, int *nmem)
+ uint *nio, uint *nmem)
{
pci_chipset_tag_t pc = &sc->sc_pc;
pcireg_t bhlc, type;
@@ -2026,10 +2020,17 @@ xbridge_resource_manage(struct xbridge_softc *sc, pcitag_t tag,
if (pci_mapreg_info(pc, tag, reg, type, &base, &size, NULL))
continue;
+ /*
+ * Note that we do not care about the existing BAR values,
+ * since these devices either have not been setup by ARCS
+ * or do not matter for early system setup (such as
+ * optional IOC3 PCI boards, which will get setup by
+ * ARCS but can be reinitialized as we see fit).
+ */
switch (type) {
case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
- if (sc->sc_mem_ex == NULL && prefer_mem != 0) {
+ if (prefer_mem != 0) {
if (extent_alloc(ex, size, size, 0, 0, 0,
&base) != 0)
base = 0;
@@ -2037,20 +2038,10 @@ xbridge_resource_manage(struct xbridge_softc *sc, pcitag_t tag,
base = 0;
break;
case PCI_MAPREG_TYPE_IO:
- if (sc->sc_io_ex == NULL && prefer_mem == 0) {
- if (base != 0 && base >= ex->ex_start &&
- base + size - 1 <= ex->ex_end) {
- if (extent_alloc_region(ex, base, size,
- EX_NOWAIT)) {
- printf("io address conflict"
- " 0x%x/0x%x\n", base, size);
- base = 0;
- }
- } else {
- if (extent_alloc(ex, size, size, 0, 0,
- 0, &base) != 0)
- base = 0;
- }
+ if (prefer_mem == 0) {
+ if (extent_alloc(ex, size, size, 0, 0, 0,
+ &base) != 0)
+ base = 0;
} else
base = 0;
break;