summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-07-01 21:56:39 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-07-01 21:56:39 +0000
commit120e4235c1e0f40a9d9a2b0db84f1dbc97912bc3 (patch)
tree502c4209de3d0aba95950eeb456805f7630a5771 /sys
parent0d94a2f192e73199851c56fe6342bcdb84e8fb9a (diff)
The widget mapping code has been written back when I was only working on
Octane support. The Octane being a single-node system, address space is ludicrous enough to allow the whole address space of every widget to be directly accessible in whole, using the address bits reserved to nasid. However, on IP27 and IP35, things do not work this way - while we still have the low 16MB address space of each widget available (the so-called ``short window''), access to other parts of the wiget address space is done through translation slots (IOTTE) at the Hub I/O space level, on a per-node basis. Given the imminent release lock, give up completely on ``large'' mappings of widgets, and restrict ourselves to short window operation, all the time (thus reinforcing the use of devio registers to map pci resources on xbridge). A proper interface to request mappings of specific widget areas, either directly on Octane, or through IOTTE if available on Origin, will appear post-release. No functional change (except from silently repairing Octane support which the previous xbridge commit silently broke).
Diffstat (limited to 'sys')
-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;