summaryrefslogtreecommitdiff
path: root/sys/arch/sgi/xbow/xbridge.c
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-08-18 19:32:00 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-08-18 19:32:00 +0000
commit1a7308cc4310273bbad33aeb36d1c5d0c6896a13 (patch)
treecc384d7f777d0b8d97004687bc2df85379e46815 /sys/arch/sgi/xbow/xbridge.c
parent631da8807b408a5ced5809908d37ed46ca97dfdb (diff)
Blind support for SGI PIC PCI-X controller found on Origin 350 and Tezro
systems. PIC was supposed to be mostly XBridge compatible, but a silicon bug prevents it from working correctly if 32 bit register writes are used, so the xbridge(4) code now needs to issue 64 bit writes. In order to make this a bit more transparent, rebase all widget registers to a 8 byte boundary, and provide a few inline accessors which will do the right thing if you want 32 bit writes. Tested to not cause regressions on Octane, Origin 200 and Fuel; covering Bridge < 4, Bridge >= 4 and XBridge flavours.
Diffstat (limited to 'sys/arch/sgi/xbow/xbridge.c')
-rw-r--r--sys/arch/sgi/xbow/xbridge.c1156
1 files changed, 648 insertions, 508 deletions
diff --git a/sys/arch/sgi/xbow/xbridge.c b/sys/arch/sgi/xbow/xbridge.c
index a209a18c5b7..3b307d57215 100644
--- a/sys/arch/sgi/xbow/xbridge.c
+++ b/sys/arch/sgi/xbow/xbridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xbridge.c,v 1.44 2009/07/27 17:49:55 miod Exp $ */
+/* $OpenBSD: xbridge.c,v 1.45 2009/08/18 19:31:59 miod Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -17,7 +17,7 @@
*/
/*
- * XBow Bridge (and XBridge) Widget driver.
+ * XBow Bridge (as well as XBridge and PIC) Widget driver.
*/
/*
@@ -68,27 +68,42 @@ int xbridge_match(struct device *, void *, void *);
void xbridge_attach(struct device *, struct device *, void *);
int xbridge_print(void *, const char *);
-struct xbridge_intr;
struct xbridge_ate;
+struct xbridge_intr;
+struct xbridge_softc;
-struct xbridge_softc {
- struct device sc_dev;
- int sc_flags;
-#define XBRIDGE_FLAGS_XBRIDGE 0x01 /* is XBridge vs Bridge */
-#define XBRIDGE_FLAGS_NO_DIRECT_IO 0x02 /* no direct I/O mapping */
- int16_t sc_nasid;
- int sc_widget;
- uint sc_devio_skew;
- struct mips_pci_chipset sc_pc;
+struct xbridge_bus {
+ struct xbridge_softc *xb_sc;
+
+ /*
+ * Bridge register accessors.
+ * Due to hardware bugs, PIC registers can only be accessed
+ * with 64 bit operations, although the hardware was supposed
+ * to be directly compatible with XBridge on that aspect.
+ */
+ uint32_t (*xb_read_reg)(bus_space_tag_t, bus_space_handle_t,
+ bus_addr_t);
+ void (*xb_write_reg)(bus_space_tag_t, bus_space_handle_t,
+ bus_addr_t, uint32_t);
+
+ uint xb_busno;
+ uint xb_nslots;
+
+ int xb_flags; /* copy of xbridge_softc value */
+ int16_t xb_nasid; /* copy of xbridge_softc value */
+ int xb_widget; /* copy of xbridge_softc value */
+ uint xb_devio_skew; /* copy of xbridge_softc value */
+
+ struct mips_pci_chipset xb_pc;
- bus_space_tag_t sc_iot;
- bus_space_handle_t sc_regh;
+ bus_space_tag_t xb_regt;
+ bus_space_handle_t xb_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 mips_bus_space *xb_mem_bus_space;
+ struct mips_bus_space *xb_io_bus_space;
+ struct machine_bus_dma_tag *xb_dmat;
- struct xbridge_intr *sc_intr[BRIDGE_NINTRS];
+ struct xbridge_intr *xb_intr[BRIDGE_NINTRS];
/*
* Device information.
@@ -96,33 +111,50 @@ struct xbridge_softc {
struct {
pcireg_t id;
uint32_t devio;
- } sc_devices[BRIDGE_NSLOTS];
+ } xb_devices[MAX_SLOTS];
/*
* ATE management.
*/
- struct mutex sc_atemtx;
- uint sc_atecnt;
- struct xbridge_ate *sc_ate;
- LIST_HEAD(, xbridge_ate) sc_free_ate;
- LIST_HEAD(, xbridge_ate) sc_used_ate;
+ struct mutex xb_atemtx;
+ uint xb_atecnt;
+ struct xbridge_ate *xb_ate;
+ LIST_HEAD(, xbridge_ate) xb_free_ate;
+ LIST_HEAD(, xbridge_ate) xb_used_ate;
/*
* Large resource view sizes
*/
- bus_addr_t sc_iostart, sc_ioend;
- bus_addr_t sc_memstart, sc_memend;
+ bus_addr_t xb_iostart, xb_ioend;
+ bus_addr_t xb_memstart, xb_memend;
/*
* Resource extents for the large resource views, used during
* resource setup, then cleaned up for the MI code.
*/
- char sc_ioexname[32];
- struct extent *sc_ioex;
- char sc_memexname[32];
- struct extent *sc_memex;
+ char xb_ioexname[32];
+ struct extent *xb_ioex;
+ char xb_memexname[32];
+ struct extent *xb_memex;
};
+struct xbridge_softc {
+ struct device sc_dev;
+ int sc_flags;
+#define XF_XBRIDGE 0x01 /* is either PIC or XBridge */
+#define XF_PIC 0x02 /* is PIC */
+#define XF_NO_DIRECT_IO 0x04 /* no direct I/O mapping */
+ int16_t sc_nasid;
+ int sc_widget;
+ uint sc_devio_skew;
+ uint sc_nbuses;
+
+ struct mips_bus_space sc_regt;
+ struct xbridge_bus sc_bus[MAX_BUSES];
+};
+
+#define DEVNAME(xb) ((xb)->xb_sc->sc_dev.dv_xname)
+
const struct cfattach xbridge_ca = {
sizeof(struct xbridge_softc), xbridge_match, xbridge_attach,
};
@@ -131,6 +163,8 @@ struct cfdriver xbridge_cd = {
NULL, "xbridge", DV_DULL,
};
+void xbridge_attach_bus(struct xbridge_softc *, uint, bus_space_tag_t);
+
void xbridge_attach_hook(struct device *, struct device *,
struct pcibus_attach_args *);
int xbridge_bus_maxdevs(void *, int);
@@ -196,32 +230,50 @@ int xbridge_rbus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t,
void xbridge_rbus_space_unmap(bus_space_tag_t, bus_space_handle_t,
bus_size_t, bus_addr_t *);
-int xbridge_address_map(struct xbridge_softc *, paddr_t, bus_addr_t *,
+int xbridge_address_map(struct xbridge_bus *, paddr_t, bus_addr_t *,
bus_addr_t *);
-void xbridge_address_unmap(struct xbridge_softc *, bus_addr_t, bus_size_t);
-uint xbridge_ate_add(struct xbridge_softc *, paddr_t);
-void xbridge_ate_dump(struct xbridge_softc *);
-uint xbridge_ate_find(struct xbridge_softc *, paddr_t);
-uint64_t xbridge_ate_read(struct xbridge_softc *, uint);
-void xbridge_ate_unref(struct xbridge_softc *, uint, uint);
-void xbridge_ate_write(struct xbridge_softc *, uint, uint64_t);
-
-int xbridge_allocate_devio(struct xbridge_softc *, int, int);
-void xbridge_set_devio(struct xbridge_softc *, int, uint32_t);
-
-int xbridge_resource_explore(struct xbridge_softc *, pcitag_t,
+void xbridge_address_unmap(struct xbridge_bus *, bus_addr_t, bus_size_t);
+uint xbridge_ate_add(struct xbridge_bus *, paddr_t);
+void xbridge_ate_dump(struct xbridge_bus *);
+uint xbridge_ate_find(struct xbridge_bus *, paddr_t);
+uint64_t xbridge_ate_read(struct xbridge_bus *, uint);
+void xbridge_ate_unref(struct xbridge_bus *, uint, uint);
+void xbridge_ate_write(struct xbridge_bus *, uint, uint64_t);
+
+int xbridge_allocate_devio(struct xbridge_bus *, int, int);
+void xbridge_set_devio(struct xbridge_bus *, int, uint32_t);
+
+int xbridge_resource_explore(struct xbridge_bus *, pcitag_t,
struct extent *, struct extent *);
-void xbridge_resource_manage(struct xbridge_softc *, pcitag_t,
+void xbridge_resource_manage(struct xbridge_bus *, pcitag_t,
struct extent *, struct extent *);
-void xbridge_ate_setup(struct xbridge_softc *);
-void xbridge_device_setup(struct xbridge_softc *, int, int, uint32_t);
-void xbridge_extent_setup(struct xbridge_softc *);
+void xbridge_ate_setup(struct xbridge_bus *);
+void xbridge_device_setup(struct xbridge_bus *, int, int, uint32_t);
+void xbridge_extent_setup(struct xbridge_bus *);
struct extent *
- xbridge_mapping_setup(struct xbridge_softc *, int);
-void xbridge_resource_setup(struct xbridge_softc *);
-void xbridge_rrb_setup(struct xbridge_softc *, int);
-void xbridge_setup(struct xbridge_softc *);
+ xbridge_mapping_setup(struct xbridge_bus *, int);
+void xbridge_resource_setup(struct xbridge_bus *);
+void xbridge_rrb_setup(struct xbridge_bus *, int);
+void xbridge_setup(struct xbridge_bus *);
+
+uint32_t bridge_read_reg(bus_space_tag_t, bus_space_handle_t, bus_addr_t);
+void bridge_write_reg(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
+ uint32_t);
+uint32_t pic_read_reg(bus_space_tag_t, bus_space_handle_t, bus_addr_t);
+void pic_write_reg(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
+ uint32_t);
+
+static __inline__ uint32_t
+xbridge_read_reg(struct xbridge_bus *xb, bus_addr_t a)
+{
+ return (*xb->xb_read_reg)(xb->xb_regt, xb->xb_regh, a);
+}
+static __inline__ void
+xbridge_write_reg(struct xbridge_bus *xb, bus_addr_t a, uint32_t v)
+{
+ (*xb->xb_write_reg)(xb->xb_regt, xb->xb_regh, a, v);
+}
const struct machine_bus_dma_tag xbridge_dma_tag = {
NULL, /* _cookie */
@@ -248,18 +300,31 @@ const struct machine_bus_dma_tag xbridge_dma_tag = {
********************* Autoconf glue.
*/
+static const struct {
+ uint32_t vendor;
+ uint32_t product;
+ int flags;
+} xbridge_devices[] = {
+ /* original Bridge */
+ { XBOW_VENDOR_SGI4, XBOW_PRODUCT_SGI4_BRIDGE, 0 },
+ /* XBridge */
+ { XBOW_VENDOR_SGI3, XBOW_PRODUCT_SGI3_XBRIDGE, XF_XBRIDGE },
+ /* PIC first half */
+ { XBOW_VENDOR_SGI3, XBOW_PRODUCT_SGI3_PIC0, XF_PIC },
+ /* PIC second half */
+ { XBOW_VENDOR_SGI3, XBOW_PRODUCT_SGI3_PIC1, XF_PIC }
+};
+
int
xbridge_match(struct device *parent, void *match, void *aux)
{
struct xbow_attach_args *xaa = aux;
+ uint i;
- if (xaa->xaa_vendor == XBOW_VENDOR_SGI4 &&
- xaa->xaa_product == XBOW_PRODUCT_SGI4_BRIDGE)
- return 1;
-
- if (xaa->xaa_vendor == XBOW_VENDOR_SGI3 &&
- xaa->xaa_product == XBOW_PRODUCT_SGI3_XBRIDGE)
- return 1;
+ for (i = 0; i < nitems(xbridge_devices); i++)
+ if (xaa->xaa_vendor == xbridge_devices[i].vendor &&
+ xaa->xaa_product == xbridge_devices[i].product)
+ return 1;
return 0;
}
@@ -268,31 +333,83 @@ void
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;
+ uint i;
sc->sc_nasid = xaa->xaa_nasid;
sc->sc_widget = xaa->xaa_widget;
printf(" revision %d\n", xaa->xaa_revision);
- if (xaa->xaa_vendor == XBOW_VENDOR_SGI3 &&
- xaa->xaa_product == XBOW_PRODUCT_SGI3_XBRIDGE)
- sc->sc_flags |= XBRIDGE_FLAGS_XBRIDGE;
- else if (xaa->xaa_revision < 4)
- sc->sc_flags |= XBRIDGE_FLAGS_NO_DIRECT_IO;
+
+ for (i = 0; i < nitems(xbridge_devices); i++)
+ if (xaa->xaa_vendor == xbridge_devices[i].vendor &&
+ xaa->xaa_product == xbridge_devices[i].product) {
+ sc->sc_flags = xbridge_devices[i].flags;
+ break;
+ }
+
+ /* PICs are XBridges without an I/O window */
+ if (ISSET(sc->sc_flags, XF_PIC))
+ SET(sc->sc_flags, XF_XBRIDGE | XF_NO_DIRECT_IO);
+ /* Bridge < D lacks an I/O window */
+ if (!ISSET(sc->sc_flags, XF_XBRIDGE) && xaa->xaa_revision < 4)
+ SET(sc->sc_flags, XF_NO_DIRECT_IO);
+
+ /*
+ * Figure out where the devio mappings will go.
+ * On Octane, they are relative to the start of the widget.
+ * On Origin, they are computed from the widget number.
+ */
+ if (sys_config.system_type == SGI_OCTANE)
+ sc->sc_devio_skew = 0;
+ else
+ sc->sc_devio_skew = sc->sc_widget;
+
+ sc->sc_nbuses =
+ ISSET(sc->sc_flags, XF_PIC) ? PIC_NBUSES : BRIDGE_NBUSES;
+
+ /* make a permanent copy of the on-stack bus_space_tag */
+ bcopy(xaa->xaa_iot, &sc->sc_regt, sizeof(struct mips_bus_space));
+
+ /* configure and attach PCI buses */
+ for (i = 0; i < sc->sc_nbuses; i++)
+ xbridge_attach_bus(sc, i, &sc->sc_regt);
+}
+
+void
+xbridge_attach_bus(struct xbridge_softc *sc, uint busno, bus_space_tag_t regt)
+{
+ struct xbridge_bus *xb = &sc->sc_bus[busno];
+ struct pcibus_attach_args pba;
+
+ xb->xb_sc = sc;
+ xb->xb_busno = busno;
+ xb->xb_flags = sc->sc_flags;
+ xb->xb_nasid = sc->sc_nasid;
+ xb->xb_widget = sc->sc_widget;
+ xb->xb_devio_skew = sc->sc_devio_skew;
+
+ if (ISSET(sc->sc_flags, XF_PIC)) {
+ xb->xb_nslots = PIC_NSLOTS;
+
+ xb->xb_read_reg = pic_read_reg;
+ xb->xb_write_reg = pic_write_reg;
+ } else {
+ xb->xb_nslots = BRIDGE_NSLOTS;
+
+ xb->xb_read_reg = bridge_read_reg;
+ xb->xb_write_reg = bridge_write_reg;
+ }
/*
* Map Bridge registers.
*/
- 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);
+ xb->xb_regt = regt;
+ if (bus_space_map(regt, busno != 0 ? BRIDGE_BUS_OFFSET : 0,
+ BRIDGE_REGISTERS_SIZE, 0, &xb->xb_regh)) {
+ printf("%s: unable to map control registers for bus %u\n",
+ DEVNAME(xb), busno);
return;
}
@@ -302,74 +419,72 @@ xbridge_attach(struct device *parent, struct device *self, void *aux)
* low-order address bits.
*/
- sc->sc_mem_bus_space = malloc(sizeof (*sc->sc_mem_bus_space),
+ xb->xb_mem_bus_space = malloc(sizeof (*xb->xb_mem_bus_space),
M_DEVBUF, M_NOWAIT);
- if (sc->sc_mem_bus_space == NULL)
+ if (xb->xb_mem_bus_space == NULL)
goto fail1;
- sc->sc_io_bus_space = malloc(sizeof (*sc->sc_io_bus_space),
+ xb->xb_io_bus_space = malloc(sizeof (*xb->xb_io_bus_space),
M_DEVBUF, M_NOWAIT);
- if (sc->sc_io_bus_space == NULL)
+ if (xb->xb_io_bus_space == NULL)
goto fail2;
- bcopy(xaa->xaa_iot, sc->sc_mem_bus_space,
- sizeof(*sc->sc_mem_bus_space));
- sc->sc_mem_bus_space->bus_private = sc;
- sc->sc_mem_bus_space->_space_map = xbridge_space_map_devio;
- sc->sc_mem_bus_space->_space_subregion = xbridge_space_region_devio;
- 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_mem_bus_space->_space_read_raw_4 = xbridge_read_raw_4;
- sc->sc_mem_bus_space->_space_write_raw_4 = xbridge_write_raw_4;
- sc->sc_mem_bus_space->_space_read_raw_8 = xbridge_read_raw_8;
- sc->sc_mem_bus_space->_space_write_raw_8 = xbridge_write_raw_8;
-
- bcopy(xaa->xaa_iot, sc->sc_io_bus_space,
- sizeof(*sc->sc_io_bus_space));
- sc->sc_io_bus_space->bus_private = sc;
- sc->sc_io_bus_space->_space_map = xbridge_space_map_devio;
- sc->sc_io_bus_space->_space_subregion = xbridge_space_region_devio;
- sc->sc_io_bus_space->_space_read_1 = xbridge_read_1;
- sc->sc_io_bus_space->_space_write_1 = xbridge_write_1;
- sc->sc_io_bus_space->_space_read_2 = xbridge_read_2;
- sc->sc_io_bus_space->_space_write_2 = xbridge_write_2;
- 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_io_bus_space->_space_read_raw_4 = xbridge_read_raw_4;
- sc->sc_io_bus_space->_space_write_raw_4 = xbridge_write_raw_4;
- sc->sc_io_bus_space->_space_read_raw_8 = xbridge_read_raw_8;
- sc->sc_io_bus_space->_space_write_raw_8 = xbridge_write_raw_8;
-
- sc->sc_dmat = malloc(sizeof (*sc->sc_dmat), M_DEVBUF, M_NOWAIT);
- if (sc->sc_dmat == NULL)
+ bcopy(regt, xb->xb_mem_bus_space, sizeof(*xb->xb_mem_bus_space));
+ xb->xb_mem_bus_space->bus_private = xb;
+ xb->xb_mem_bus_space->_space_map = xbridge_space_map_devio;
+ xb->xb_mem_bus_space->_space_subregion = xbridge_space_region_devio;
+ xb->xb_mem_bus_space->_space_read_1 = xbridge_read_1;
+ xb->xb_mem_bus_space->_space_write_1 = xbridge_write_1;
+ xb->xb_mem_bus_space->_space_read_2 = xbridge_read_2;
+ xb->xb_mem_bus_space->_space_write_2 = xbridge_write_2;
+ xb->xb_mem_bus_space->_space_read_raw_2 = xbridge_read_raw_2;
+ xb->xb_mem_bus_space->_space_write_raw_2 = xbridge_write_raw_2;
+ xb->xb_mem_bus_space->_space_read_raw_4 = xbridge_read_raw_4;
+ xb->xb_mem_bus_space->_space_write_raw_4 = xbridge_write_raw_4;
+ xb->xb_mem_bus_space->_space_read_raw_8 = xbridge_read_raw_8;
+ xb->xb_mem_bus_space->_space_write_raw_8 = xbridge_write_raw_8;
+
+ bcopy(regt, xb->xb_io_bus_space, sizeof(*xb->xb_io_bus_space));
+ xb->xb_io_bus_space->bus_private = xb;
+ xb->xb_io_bus_space->_space_map = xbridge_space_map_devio;
+ xb->xb_io_bus_space->_space_subregion = xbridge_space_region_devio;
+ xb->xb_io_bus_space->_space_read_1 = xbridge_read_1;
+ xb->xb_io_bus_space->_space_write_1 = xbridge_write_1;
+ xb->xb_io_bus_space->_space_read_2 = xbridge_read_2;
+ xb->xb_io_bus_space->_space_write_2 = xbridge_write_2;
+ xb->xb_io_bus_space->_space_read_raw_2 = xbridge_read_raw_2;
+ xb->xb_io_bus_space->_space_write_raw_2 = xbridge_write_raw_2;
+ xb->xb_io_bus_space->_space_read_raw_4 = xbridge_read_raw_4;
+ xb->xb_io_bus_space->_space_write_raw_4 = xbridge_write_raw_4;
+ xb->xb_io_bus_space->_space_read_raw_8 = xbridge_read_raw_8;
+ xb->xb_io_bus_space->_space_write_raw_8 = xbridge_write_raw_8;
+
+ xb->xb_dmat = malloc(sizeof (*xb->xb_dmat), M_DEVBUF, M_NOWAIT);
+ if (xb->xb_dmat == NULL)
goto fail3;
- memcpy(sc->sc_dmat, &xbridge_dma_tag, sizeof(*sc->sc_dmat));
- sc->sc_dmat->_cookie = sc;
+ memcpy(xb->xb_dmat, &xbridge_dma_tag, sizeof(*xb->xb_dmat));
+ xb->xb_dmat->_cookie = xb;
/*
* Initialize PCI methods.
*/
- sc->sc_pc.pc_conf_v = sc;
- sc->sc_pc.pc_attach_hook = xbridge_attach_hook;
- sc->sc_pc.pc_make_tag = xbridge_make_tag;
- sc->sc_pc.pc_decompose_tag = xbridge_decompose_tag;
- sc->sc_pc.pc_bus_maxdevs = xbridge_bus_maxdevs;
- sc->sc_pc.pc_conf_read = xbridge_conf_read;
- sc->sc_pc.pc_conf_write = xbridge_conf_write;
- sc->sc_pc.pc_intr_v = sc;
- sc->sc_pc.pc_intr_map = xbridge_intr_map;
- sc->sc_pc.pc_intr_string = xbridge_intr_string;
- sc->sc_pc.pc_intr_establish = xbridge_intr_establish;
- sc->sc_pc.pc_intr_disestablish = xbridge_intr_disestablish;
- sc->sc_pc.pc_intr_line = xbridge_intr_line;
- sc->sc_pc.pc_ppb_setup = xbridge_ppb_setup;
+ xb->xb_pc.pc_conf_v = xb;
+ xb->xb_pc.pc_attach_hook = xbridge_attach_hook;
+ xb->xb_pc.pc_make_tag = xbridge_make_tag;
+ xb->xb_pc.pc_decompose_tag = xbridge_decompose_tag;
+ xb->xb_pc.pc_bus_maxdevs = xbridge_bus_maxdevs;
+ xb->xb_pc.pc_conf_read = xbridge_conf_read;
+ xb->xb_pc.pc_conf_write = xbridge_conf_write;
+ xb->xb_pc.pc_intr_v = xb;
+ xb->xb_pc.pc_intr_map = xbridge_intr_map;
+ xb->xb_pc.pc_intr_string = xbridge_intr_string;
+ xb->xb_pc.pc_intr_establish = xbridge_intr_establish;
+ xb->xb_pc.pc_intr_disestablish = xbridge_intr_disestablish;
+ xb->xb_pc.pc_intr_line = xbridge_intr_line;
+ xb->xb_pc.pc_ppb_setup = xbridge_ppb_setup;
#if NCARDBUS > 0
- sc->sc_pc.pc_rbus_parent_io = xbridge_rbus_parent_io;
- sc->sc_pc.pc_rbus_parent_mem = xbridge_rbus_parent_mem;
+ xb->xb_pc.pc_rbus_parent_io = xbridge_rbus_parent_io;
+ xb->xb_pc.pc_rbus_parent_mem = xbridge_rbus_parent_mem;
#endif
/*
@@ -377,37 +492,35 @@ xbridge_attach(struct device *parent, struct device *self, void *aux)
* RRB allocation, etc).
*/
- xbridge_setup(sc);
+ xbridge_setup(xb);
/*
* Attach children.
*/
- xbridge_extent_setup(sc);
+ xbridge_extent_setup(xb);
bzero(&pba, sizeof(pba));
pba.pba_busname = "pci";
- 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_ioex;
- pba.pba_memex = sc->sc_memex;
- pba.pba_pc = &sc->sc_pc;
+ pba.pba_iot = xb->xb_io_bus_space;
+ pba.pba_memt = xb->xb_mem_bus_space;
+ pba.pba_dmat = xb->xb_dmat;
+ pba.pba_ioex = xb->xb_ioex;
+ pba.pba_memex = xb->xb_memex;
+ pba.pba_pc = &xb->xb_pc;
pba.pba_domain = pci_ndomains++;
pba.pba_bus = 0;
- config_found(self, &pba, xbridge_print);
+ config_found(&sc->sc_dev, &pba, xbridge_print);
return;
fail3:
- free(sc->sc_io_bus_space, M_DEVBUF);
+ free(xb->xb_io_bus_space, M_DEVBUF);
fail2:
- free(sc->sc_mem_bus_space, M_DEVBUF);
+ free(xb->xb_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);
+ printf("%s: not enough memory to build bus %u access structures\n",
+ DEVNAME(xb), busno);
return;
}
@@ -454,13 +567,15 @@ xbridge_decompose_tag(void *cookie, pcitag_t tag, int *busp, int *devp,
int
xbridge_bus_maxdevs(void *cookie, int busno)
{
- return busno == 0 ? BRIDGE_NSLOTS : 32;
+ struct xbridge_bus *xb = cookie;
+
+ return busno == 0 ? xb->xb_nslots : 32;
}
pcireg_t
xbridge_conf_read(void *cookie, pcitag_t tag, int offset)
{
- struct xbridge_softc *sc = cookie;
+ struct xbridge_bus *xb = cookie;
pcireg_t data;
int bus, dev, fn;
paddr_t pa;
@@ -472,11 +587,20 @@ xbridge_conf_read(void *cookie, pcitag_t tag, int offset)
xbridge_decompose_tag(cookie, tag, &bus, &dev, &fn);
if (bus != 0) {
- bus_space_write_4(sc->sc_iot, sc->sc_regh, BRIDGE_PCI_CFG,
+ xbridge_write_reg(xb, BRIDGE_PCI_CFG,
(bus << 16) | (dev << 11));
- pa = sc->sc_regh + BRIDGE_PCI_CFG1_SPACE;
- } else
- pa = sc->sc_regh + BRIDGE_PCI_CFG_SPACE + (dev << 12);
+ pa = xb->xb_regh + BRIDGE_PCI_CFG1_SPACE;
+ } else {
+ if (ISSET(xb->xb_flags, XF_PIC)) {
+ /*
+ * On PIC, device 0 in configuration space is the
+ * PIC itself, device slots are offset by one.
+ */
+ pa = xb->xb_regh + BRIDGE_PCI_CFG_SPACE +
+ ((dev + 1) << 12);
+ } else
+ pa = xb->xb_regh + BRIDGE_PCI_CFG_SPACE + (dev << 12);
+ }
/*
* IOC3 devices only implement a subset of the PCI configuration
@@ -492,7 +616,7 @@ xbridge_conf_read(void *cookie, pcitag_t tag, int offset)
*/
skip = 0;
- if (bus == 0 && sc->sc_devices[dev].id ==
+ if (bus == 0 && xb->xb_devices[dev].id ==
PCI_ID_CODE(PCI_VENDOR_SGI, PCI_PRODUCT_SGI_IOC3)) {
switch (offset) {
case PCI_ID_REG:
@@ -530,7 +654,7 @@ xbridge_conf_read(void *cookie, pcitag_t tag, int offset)
void
xbridge_conf_write(void *cookie, pcitag_t tag, int offset, pcireg_t data)
{
- struct xbridge_softc *sc = cookie;
+ struct xbridge_bus *xb = cookie;
int bus, dev, fn;
paddr_t pa;
int skip;
@@ -541,11 +665,20 @@ xbridge_conf_write(void *cookie, pcitag_t tag, int offset, pcireg_t data)
xbridge_decompose_tag(cookie, tag, &bus, &dev, &fn);
if (bus != 0) {
- bus_space_write_4(sc->sc_iot, sc->sc_regh, BRIDGE_PCI_CFG,
+ xbridge_write_reg(xb, BRIDGE_PCI_CFG,
(bus << 16) | (dev << 11));
- pa = sc->sc_regh + BRIDGE_PCI_CFG1_SPACE;
- } else
- pa = sc->sc_regh + BRIDGE_PCI_CFG_SPACE + (dev << 12);
+ pa = xb->xb_regh + BRIDGE_PCI_CFG1_SPACE;
+ } else {
+ if (ISSET(xb->xb_flags, XF_PIC)) {
+ /*
+ * On PIC, device 0 in configuration space is the
+ * PIC itself, device slots are offset by one.
+ */
+ pa = xb->xb_regh + BRIDGE_PCI_CFG_SPACE +
+ ((dev + 1) << 12);
+ } else
+ pa = xb->xb_regh + BRIDGE_PCI_CFG_SPACE + (dev << 12);
+ }
/*
* IOC3 devices only implement a subset of the PCI configuration
@@ -559,7 +692,7 @@ xbridge_conf_write(void *cookie, pcitag_t tag, int offset, pcireg_t data)
*/
skip = 0;
- if (bus == 0 && sc->sc_devices[dev].id ==
+ if (bus == 0 && xb->xb_devices[dev].id ==
PCI_ID_CODE(PCI_VENDOR_SGI, PCI_PRODUCT_SGI_IOC3)) {
switch (offset) {
case PCI_COMMAND_STATUS_REG:
@@ -611,7 +744,7 @@ struct xbridge_intrhandler {
};
struct xbridge_intr {
- struct xbridge_softc *xi_bridge;
+ struct xbridge_bus *xi_bus;
int xi_intrsrc; /* interrupt source on interrupt widget */
int xi_intrbit; /* interrupt source on BRIDGE */
LIST_HEAD(, xbridge_intrhandler) xi_handlers;
@@ -626,7 +759,7 @@ struct xbridge_intr {
int
xbridge_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
{
- struct xbridge_softc *sc = pa->pa_pc->pc_conf_v;
+ struct xbridge_bus *xb = pa->pa_pc->pc_conf_v;
int bus, device, intr;
int pin;
@@ -655,7 +788,7 @@ xbridge_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
/*
* For IOC devices, the real information is in pa_intrline.
*/
- if (sc->sc_devices[device].id ==
+ if (xb->xb_devices[device].id ==
PCI_ID_CODE(PCI_VENDOR_SGI, PCI_PRODUCT_SGI_IOC3)) {
intr = pa->pa_intrline;
} else {
@@ -684,7 +817,7 @@ void *
xbridge_intr_establish(void *cookie, pci_intr_handle_t ih, int level,
int (*func)(void *), void *arg, char *name)
{
- struct xbridge_softc *sc = (struct xbridge_softc *)cookie;
+ struct xbridge_bus *xb = (struct xbridge_bus *)cookie;
struct xbridge_intr *xi;
struct xbridge_intrhandler *xih;
uint32_t int_addr;
@@ -697,23 +830,23 @@ xbridge_intr_establish(void *cookie, pci_intr_handle_t ih, int level,
* Allocate bookkeeping structure if this is the
* first time we're using this interrupt source.
*/
- if ((xi = sc->sc_intr[intrbit]) == NULL) {
+ if ((xi = xb->xb_intr[intrbit]) == NULL) {
xi = (struct xbridge_intr *)
malloc(sizeof(*xi), M_DEVBUF, M_NOWAIT);
if (xi == NULL)
return NULL;
- xi->xi_bridge = sc;
+ xi->xi_bus = xb;
xi->xi_intrbit = intrbit;
LIST_INIT(&xi->xi_handlers);
- if (xbow_intr_register(sc->sc_widget, level, &intrsrc) != 0) {
+ if (xbow_intr_register(xb->xb_widget, level, &intrsrc) != 0) {
free(xi, M_DEVBUF);
return NULL;
}
xi->xi_intrsrc = intrsrc;
- sc->sc_intr[intrbit] = xi;
+ xb->xb_intr[intrbit] = xi;
}
/*
@@ -730,7 +863,7 @@ xbridge_intr_establish(void *cookie, pci_intr_handle_t ih, int level,
if (xbow_intr_establish(xbridge_intr_handler, xi, intrsrc,
IPL_BIO, NULL)) {
printf("%s: unable to register interrupt handler\n",
- sc->sc_dev.dv_xname);
+ DEVNAME(xb));
return NULL;
}
}
@@ -749,14 +882,16 @@ xbridge_intr_establish(void *cookie, pci_intr_handle_t ih, int level,
LIST_INSERT_HEAD(&xi->xi_handlers, xih, xih_nxt);
if (new) {
- int_addr =
- ((xbow_intr_widget_register >> 30) & 0x0003ff00) | intrsrc;
-
- bus_space_write_4(sc->sc_iot, sc->sc_regh,
- BRIDGE_INT_ADDR(intrbit), int_addr);
- bus_space_write_4(sc->sc_iot, sc->sc_regh, BRIDGE_IER,
- bus_space_read_4(sc->sc_iot, sc->sc_regh, BRIDGE_IER) |
- (1 << intrbit));
+ if (ISSET(xb->xb_flags, XF_PIC))
+ int_addr = ((uint64_t)intrsrc << 48) |
+ (xbow_intr_widget_register & ((1UL << 48) - 1));
+ else
+ int_addr = ((xbow_intr_widget_register >> 30) &
+ 0x0003ff00) | intrsrc;
+
+ xbridge_write_reg(xb, BRIDGE_INT_ADDR(intrbit), int_addr);
+ xbridge_write_reg(xb, BRIDGE_IER,
+ xbridge_read_reg(xb, BRIDGE_IER) | (1 << intrbit));
/*
* INT_MODE register controls which interrupt pins cause
* ``interrupt clear'' packets to be sent for high->low
@@ -764,13 +899,12 @@ xbridge_intr_establish(void *cookie, pci_intr_handle_t ih, int level,
* We enable such packets to be sent in order not to have to
* clear interrupts ourselves.
*/
- bus_space_write_4(sc->sc_iot, sc->sc_regh, BRIDGE_INT_MODE,
- bus_space_read_4(sc->sc_iot, sc->sc_regh, BRIDGE_INT_MODE) |
- (1 << intrbit));
- bus_space_write_4(sc->sc_iot, sc->sc_regh, BRIDGE_INT_DEV,
- bus_space_read_4(sc->sc_iot, sc->sc_regh, BRIDGE_INT_DEV) |
+ xbridge_write_reg(xb, BRIDGE_INT_MODE,
+ xbridge_read_reg(xb, BRIDGE_INT_MODE) | (1 << intrbit));
+ xbridge_write_reg(xb, BRIDGE_INT_DEV,
+ xbridge_read_reg(xb, BRIDGE_INT_DEV) |
(device << (intrbit * 3)));
- (void)bus_space_read_4(sc->sc_iot, sc->sc_regh, WIDGET_TFLUSH);
+ (void)xbridge_read_reg(xb, WIDGET_TFLUSH);
}
return (void *)xih;
@@ -779,7 +913,7 @@ xbridge_intr_establish(void *cookie, pci_intr_handle_t ih, int level,
void
xbridge_intr_disestablish(void *cookie, void *vih)
{
- struct xbridge_softc *sc = cookie;
+ struct xbridge_bus *xb = cookie;
struct xbridge_intrhandler *xih = (struct xbridge_intrhandler *)vih;
struct xbridge_intr *xi = xih->xih_main;
int intrbit = xi->xi_intrbit;
@@ -788,22 +922,19 @@ xbridge_intr_disestablish(void *cookie, void *vih)
LIST_REMOVE(xih, xih_nxt);
if (LIST_EMPTY(&xi->xi_handlers)) {
- bus_space_write_4(sc->sc_iot, sc->sc_regh,
- BRIDGE_INT_ADDR(intrbit), 0);
- bus_space_write_4(sc->sc_iot, sc->sc_regh, BRIDGE_IER,
- bus_space_read_4(sc->sc_iot, sc->sc_regh, BRIDGE_IER) &
- ~(1 << intrbit));
- bus_space_write_4(sc->sc_iot, sc->sc_regh, BRIDGE_INT_MODE,
- bus_space_read_4(sc->sc_iot, sc->sc_regh, BRIDGE_INT_MODE) &
- ~(1 << intrbit));
- bus_space_write_4(sc->sc_iot, sc->sc_regh, BRIDGE_INT_DEV,
- bus_space_read_4(sc->sc_iot, sc->sc_regh, BRIDGE_INT_DEV) &
+ xbridge_write_reg(xb, BRIDGE_INT_ADDR(intrbit), 0);
+ xbridge_write_reg(xb, BRIDGE_IER,
+ xbridge_read_reg(xb, BRIDGE_IER) & ~(1 << intrbit));
+ xbridge_write_reg(xb, BRIDGE_INT_MODE,
+ xbridge_read_reg(xb, BRIDGE_INT_MODE) & ~(1 << intrbit));
+ xbridge_write_reg(xb, BRIDGE_INT_DEV,
+ xbridge_read_reg(xb, BRIDGE_INT_DEV) &
~(7 << (intrbit * 3)));
- (void)bus_space_read_4(sc->sc_iot, sc->sc_regh, WIDGET_TFLUSH);
+ (void)xbridge_read_reg(xb, WIDGET_TFLUSH);
xbow_intr_disestablish(xi->xi_intrsrc);
/*
- * Note we could free sc->sc_intr[intrbit] at this point,
+ * Note we could free xb->xb_intr[intrbit] at this point,
* but it's not really worth doing.
*/
}
@@ -821,14 +952,14 @@ int
xbridge_intr_handler(void *v)
{
struct xbridge_intr *xi = (struct xbridge_intr *)v;
- struct xbridge_softc *sc = xi->xi_bridge;
+ struct xbridge_bus *xb = xi->xi_bus;
struct xbridge_intrhandler *xih;
int rc = 0;
int spurious;
+ uint32_t isr;
if (LIST_EMPTY(&xi->xi_handlers)) {
- printf("%s: spurious irq %d\n",
- sc->sc_dev.dv_xname, xi->xi_intrbit);
+ printf("%s: spurious irq %d\n", DEVNAME(xb), xi->xi_intrbit);
return 0;
}
@@ -836,16 +967,14 @@ xbridge_intr_handler(void *v)
* Flush PCI write buffers before servicing the interrupt.
*/
LIST_FOREACH(xih, &xi->xi_handlers, xih_nxt)
- bus_space_read_4(sc->sc_iot, sc->sc_regh,
- BRIDGE_DEVICE_WBFLUSH(xih->xih_device));
+ xbridge_read_reg(xb, BRIDGE_DEVICE_WBFLUSH(xih->xih_device));
- if ((bus_space_read_4(sc->sc_iot, sc->sc_regh, BRIDGE_ISR) &
- (1 << xi->xi_intrbit)) == 0) {
+ isr = xbridge_read_reg(xb, BRIDGE_ISR);
+ if ((isr & (1 << xi->xi_intrbit)) == 0) {
spurious = 1;
#ifdef DEBUG
printf("%s: irq %d but not pending in ISR %08x\n",
- sc->sc_dev.dv_xname, xi->xi_intrbit,
- bus_space_read_4(sc->sc_iot, sc->sc_regh, BRIDGE_ISR));
+ DEVNAME(xb), xi->xi_intrbit, isr);
#endif
} else
spurious = 0;
@@ -858,8 +987,7 @@ xbridge_intr_handler(void *v)
}
}
if (rc == 0 && spurious == 0)
- printf("%s: spurious irq %d\n",
- sc->sc_dev.dv_xname, xi->xi_intrbit);
+ printf("%s: spurious irq %d\n", DEVNAME(xb), xi->xi_intrbit);
/*
* There is a known BRIDGE race in which, if two interrupts
@@ -875,12 +1003,10 @@ xbridge_intr_handler(void *v)
* do not even have to check if our interrupt is pending.
*/
- if (ISSET(sc->sc_flags, XBRIDGE_FLAGS_XBRIDGE)) {
- bus_space_write_4(sc->sc_iot, sc->sc_regh,
- BRIDGE_INT_FORCE_PIN(xi->xi_intrbit), 1);
- } else {
- if (bus_space_read_4(sc->sc_iot, sc->sc_regh,
- BRIDGE_ISR) & (1 << xi->xi_intrbit)) {
+ if (ISSET(xb->xb_flags, XF_XBRIDGE))
+ xbridge_write_reg(xb, BRIDGE_INT_FORCE_PIN(xi->xi_intrbit), 1);
+ else {
+ if (xbridge_read_reg(xb, BRIDGE_ISR) & (1 << xi->xi_intrbit)) {
switch (sys_config.system_type) {
#if defined(TGT_OCTANE)
case SGI_OCTANE:
@@ -890,7 +1016,7 @@ xbridge_intr_handler(void *v)
#if defined(TGT_ORIGIN200) || defined(TGT_ORIGIN2000)
case SGI_O200:
case SGI_O300:
- IP27_RHUB_PI_S(sc->sc_nasid, 0, HUBPI_IR_CHANGE,
+ IP27_RHUB_PI_S(xb->xb_nasid, 0, HUBPI_IR_CHANGE,
PI_IR_SET | xi->xi_intrsrc);
break;
#endif
@@ -902,6 +1028,35 @@ xbridge_intr_handler(void *v)
}
/*
+ ********************* chip register access.
+ */
+
+uint32_t
+bridge_read_reg(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t a)
+{
+ return widget_read_4(t, h, a);
+}
+void
+bridge_write_reg(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t a,
+ uint32_t v)
+{
+ widget_write_4(t, h, a, v);
+}
+
+uint32_t
+pic_read_reg(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t a)
+{
+ return (uint32_t)widget_read_8(t, h, a);
+}
+
+void
+pic_write_reg(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t a,
+ uint32_t v)
+{
+ widget_write_8(t, h, a, (uint64_t)v);
+}
+
+/*
********************* bus_space glue.
*/
@@ -1007,14 +1162,14 @@ int
xbridge_space_map_devio(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
int flags, bus_space_handle_t *bshp)
{
- struct xbridge_softc *sc = (struct xbridge_softc *)t->bus_private;
+ struct xbridge_bus *xb = (struct xbridge_bus *)t->bus_private;
bus_addr_t bpa;
#ifdef DIAGNOSTIC
bus_addr_t start, end;
uint d;
#endif
- if ((offs >> 24) != sc->sc_devio_skew)
+ if ((offs >> 24) != xb->xb_devio_skew)
return EINVAL; /* not a devio mapping */
/*
@@ -1023,8 +1178,8 @@ xbridge_space_map_devio(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
*/
bpa = offs & ((1UL << 24) - 1);
#ifdef DIAGNOSTIC
- for (d = 0; d < BRIDGE_NSLOTS; d++) {
- start = BRIDGE_DEVIO_OFFS(d);
+ for (d = 0; d < xb->xb_nslots; d++) {
+ start = PIC_DEVIO_OFFS(xb->xb_busno, d);
end = start + BRIDGE_DEVIO_SIZE(d);
if (bpa >= start && bpa < end) {
if (bpa + size > end)
@@ -1033,7 +1188,7 @@ xbridge_space_map_devio(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
break;
}
}
- if (d == BRIDGE_NSLOTS)
+ if (d == xb->xb_nslots)
return EINVAL;
#endif
@@ -1042,7 +1197,7 @@ xbridge_space_map_devio(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
* to our small window. Instead, use the one used by the xbridge
* driver itself, which _always_ points to the short window.
*/
- *bshp = sc->sc_iot->bus_base + bpa;
+ *bshp = xb->xb_regt->bus_base + bpa;
return 0;
}
@@ -1050,19 +1205,19 @@ int
xbridge_space_map_io(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
int flags, bus_space_handle_t *bshp)
{
- struct xbridge_softc *sc = (struct xbridge_softc *)t->bus_private;
+ struct xbridge_bus *xb = (struct xbridge_bus *)t->bus_private;
/*
* Base address is either within the devio area, or our direct
* window.
*/
- if ((offs >> 24) == sc->sc_devio_skew)
+ if ((offs >> 24) == xb->xb_devio_skew)
return xbridge_space_map_devio(t, offs, size, flags, bshp);
#ifdef DIAGNOSTIC
/* check that this does not overflow the mapping */
- if (offs < sc->sc_iostart || offs + size - 1 > sc->sc_ioend)
+ if (offs < xb->xb_iostart || offs + size - 1 > xb->xb_ioend)
return EINVAL;
#endif
@@ -1074,7 +1229,7 @@ int
xbridge_space_map_mem(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
int flags, bus_space_handle_t *bshp)
{
- struct xbridge_softc *sc = (struct xbridge_softc *)t->bus_private;
+ struct xbridge_bus *xb = (struct xbridge_bus *)t->bus_private;
/*
* Base address is either within the devio area, or our direct
@@ -1083,12 +1238,12 @@ xbridge_space_map_mem(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
*/
if (sys_config.system_type != SGI_OCTANE &&
- (offs >> 24) == sc->sc_devio_skew)
+ (offs >> 24) == xb->xb_devio_skew)
return xbridge_space_map_devio(t, offs, size, flags, bshp);
#ifdef DIAGNOSTIC
/* check that this does not overflow the mapping */
- if (offs < sc->sc_memstart || offs + size - 1 > sc->sc_memend)
+ if (offs < xb->xb_memstart || offs + size - 1 > xb->xb_memend)
return EINVAL;
#endif
@@ -1101,7 +1256,7 @@ xbridge_space_region_devio(bus_space_tag_t t , bus_space_handle_t bsh,
bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
{
#ifdef DIAGNOSTIC
- struct xbridge_softc *sc = (struct xbridge_softc *)t->bus_private;
+ struct xbridge_bus *xb = (struct xbridge_bus *)t->bus_private;
bus_addr_t bpa;
bus_addr_t start, end;
uint d;
@@ -1113,7 +1268,7 @@ xbridge_space_region_devio(bus_space_tag_t t , bus_space_handle_t bsh,
* to our small window. Instead, use the one used by the xbridge
* driver itself, which _always_ points to the short window.
*/
- bpa = (bus_addr_t)bsh - sc->sc_iot->bus_base;
+ bpa = (bus_addr_t)bsh - xb->xb_regt->bus_base;
if ((bpa >> 24) != 0)
return EINVAL; /* not a devio mapping */
@@ -1122,8 +1277,8 @@ xbridge_space_region_devio(bus_space_tag_t t , bus_space_handle_t bsh,
* Figure out which devio `slot' we are using, and make sure
* we do not overrun it.
*/
- for (d = 0; d < BRIDGE_NSLOTS; d++) {
- start = BRIDGE_DEVIO_OFFS(d);
+ for (d = 0; d < xb->xb_nslots; d++) {
+ start = PIC_DEVIO_OFFS(xb->xb_busno, d);
end = start + BRIDGE_DEVIO_SIZE(d);
if (bpa >= start && bpa < end) {
if (bpa + offset + size > end)
@@ -1132,7 +1287,7 @@ xbridge_space_region_devio(bus_space_tag_t t , bus_space_handle_t bsh,
break;
}
}
- if (d == BRIDGE_NSLOTS)
+ if (d == xb->xb_nslots)
return EINVAL;
#endif
@@ -1144,7 +1299,7 @@ int
xbridge_space_region_io(bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
{
- struct xbridge_softc *sc = (struct xbridge_softc *)t->bus_private;
+ struct xbridge_bus *xb = (struct xbridge_bus *)t->bus_private;
bus_addr_t bpa;
/*
@@ -1152,7 +1307,7 @@ xbridge_space_region_io(bus_space_tag_t t, bus_space_handle_t bsh,
* to our small window. Instead, use the one used by the xbridge
* driver itself, which _always_ points to the short window.
*/
- bpa = (bus_addr_t)bsh - sc->sc_iot->bus_base;
+ bpa = (bus_addr_t)bsh - xb->xb_regt->bus_base;
if ((bpa >> 24) == 0)
return xbridge_space_region_devio(t, bsh, offset, size, nbshp);
@@ -1160,7 +1315,7 @@ xbridge_space_region_io(bus_space_tag_t t, bus_space_handle_t bsh,
#ifdef DIAGNOSTIC
/* check that this does not overflow the mapping */
bpa = (bus_addr_t)bsh - t->bus_base;
- if (bpa + offset + size - 1 > sc->sc_ioend)
+ if (bpa + offset + size - 1 > xb->xb_ioend)
return EINVAL;
#endif
@@ -1172,7 +1327,7 @@ int
xbridge_space_region_mem(bus_space_tag_t t, bus_space_handle_t bsh,
bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
{
- struct xbridge_softc *sc = (struct xbridge_softc *)t->bus_private;
+ struct xbridge_bus *xb = (struct xbridge_bus *)t->bus_private;
bus_addr_t bpa;
/*
@@ -1187,7 +1342,7 @@ xbridge_space_region_mem(bus_space_tag_t t, bus_space_handle_t bsh,
* the xbridge driver itself, which _always_ points to the
* short window.
*/
- bpa = (bus_addr_t)bsh - sc->sc_iot->bus_base;
+ bpa = (bus_addr_t)bsh - xb->xb_regt->bus_base;
if ((bpa >> 24) == 0)
return xbridge_space_region_devio(t, bsh, offset, size,
@@ -1197,7 +1352,7 @@ xbridge_space_region_mem(bus_space_tag_t t, bus_space_handle_t bsh,
#ifdef DIAGNOSTIC
/* check that this does not overflow the mapping */
bpa = (bus_addr_t)bsh - t->bus_base;
- if (bpa + offset + size - 1 > sc->sc_memend)
+ if (bpa + offset + size - 1 > xb->xb_memend)
return EINVAL;
#endif
@@ -1255,13 +1410,13 @@ struct xbridge_ate {
#ifdef ATE_DEBUG
void
-xbridge_ate_dump(struct xbridge_softc *sc)
+xbridge_ate_dump(struct xbridge_bus *xb)
{
struct xbridge_ate *ate;
uint a;
- printf("%s ATE list (in array order)\n", sc->sc_dev.dv_xname);
- for (a = 0, ate = sc->sc_ate; a < sc->sc_atecnt; a++, ate++) {
+ printf("%s ATE list (in array order)\n", DEVNAME(xb));
+ for (a = 0, ate = xb->xb_ate; a < xb->xb_atecnt; a++, ate++) {
printf("%03x %p %02u", a, ate->xa_pa, ate->xa_refcnt);
if ((a % 3) == 2)
printf("\n");
@@ -1271,11 +1426,11 @@ xbridge_ate_dump(struct xbridge_softc *sc)
if ((a % 3) != 0)
printf("\n");
- printf("%s USED ATE list (in link order)\n", sc->sc_dev.dv_xname);
+ printf("%s USED ATE list (in link order)\n", DEVNAME(xb));
a = 0;
- LIST_FOREACH(ate, &sc->sc_used_ate, xa_nxt) {
+ LIST_FOREACH(ate, &xb->xb_used_ate, xa_nxt) {
printf("%03x %p %02u",
- ate - sc->sc_ate, ate->xa_pa, ate->xa_refcnt);
+ ate - xb->xb_ate, ate->xa_pa, ate->xa_refcnt);
if ((a % 3) == 2)
printf("\n");
else
@@ -1285,11 +1440,11 @@ xbridge_ate_dump(struct xbridge_softc *sc)
if ((a % 3) != 0)
printf("\n");
- printf("%s FREE ATE list (in link order)\n", sc->sc_dev.dv_xname);
+ printf("%s FREE ATE list (in link order)\n", DEVNAME(xb));
a = 0;
- LIST_FOREACH(ate, &sc->sc_free_ate, xa_nxt) {
+ LIST_FOREACH(ate, &xb->xb_free_ate, xa_nxt) {
printf("%03x %p %02u",
- ate - sc->sc_ate, ate->xa_pa, ate->xa_refcnt);
+ ate - xb->xb_ate, ate->xa_pa, ate->xa_refcnt);
if ((a % 3) == 2)
printf("\n");
else
@@ -1302,22 +1457,22 @@ xbridge_ate_dump(struct xbridge_softc *sc)
#endif
void
-xbridge_ate_setup(struct xbridge_softc *sc)
+xbridge_ate_setup(struct xbridge_bus *xb)
{
uint32_t ctrl;
uint a;
struct xbridge_ate *ate;
- mtx_init(&sc->sc_atemtx, IPL_HIGH);
+ mtx_init(&xb->xb_atemtx, IPL_HIGH);
- if (ISSET(sc->sc_flags, XBRIDGE_FLAGS_XBRIDGE))
- sc->sc_atecnt = XBRIDGE_INTERNAL_ATE;
+ if (ISSET(xb->xb_flags, XF_XBRIDGE))
+ xb->xb_atecnt = XBRIDGE_INTERNAL_ATE;
else
- sc->sc_atecnt = BRIDGE_INTERNAL_ATE;
+ xb->xb_atecnt = BRIDGE_INTERNAL_ATE;
- sc->sc_ate = (struct xbridge_ate *)malloc(sc->sc_atecnt *
+ xb->xb_ate = (struct xbridge_ate *)malloc(xb->xb_atecnt *
sizeof(struct xbridge_ate), M_DEVBUF, M_ZERO | M_NOWAIT);
- if (sc->sc_ate == NULL) {
+ if (xb->xb_ate == NULL) {
/* we could run without, but this would be a PITA */
panic("%s: no memory for ATE management", __func__);
}
@@ -1325,29 +1480,29 @@ xbridge_ate_setup(struct xbridge_softc *sc)
/*
* Setup the ATE lists.
*/
- LIST_INIT(&sc->sc_free_ate);
- LIST_INIT(&sc->sc_used_ate);
- for (ate = sc->sc_ate; ate != sc->sc_ate + sc->sc_atecnt; ate++)
- LIST_INSERT_HEAD(&sc->sc_free_ate, ate, xa_nxt);
+ LIST_INIT(&xb->xb_free_ate);
+ LIST_INIT(&xb->xb_used_ate);
+ for (ate = xb->xb_ate; ate != xb->xb_ate + xb->xb_atecnt; ate++)
+ LIST_INSERT_HEAD(&xb->xb_free_ate, ate, xa_nxt);
/*
* Switch to 16KB pages.
*/
- ctrl = bus_space_read_4(sc->sc_iot, sc->sc_regh, WIDGET_CONTROL);
- bus_space_write_4(sc->sc_iot, sc->sc_regh, WIDGET_CONTROL,
+ ctrl = xbridge_read_reg(xb, WIDGET_CONTROL);
+ xbridge_write_reg(xb, WIDGET_CONTROL,
ctrl | BRIDGE_WIDGET_CONTROL_LARGE_PAGES);
- (void)bus_space_read_4(sc->sc_iot, sc->sc_regh, WIDGET_TFLUSH);
+ (void)xbridge_read_reg(xb, WIDGET_TFLUSH);
/*
* Initialize all ATE entries to invalid.
*/
- for (a = 0; a < sc->sc_atecnt; a++)
- xbridge_ate_write(sc, a, ATE_NV);
+ for (a = 0; a < xb->xb_atecnt; a++)
+ xbridge_ate_write(xb, a, ATE_NV);
}
#ifdef unused
uint64_t
-xbridge_ate_read(struct xbridge_softc *sc, uint a)
+xbridge_ate_read(struct xbridge_bus *xb, uint a)
{
uint32_t lo, hi;
uint64_t ate;
@@ -1355,13 +1510,11 @@ xbridge_ate_read(struct xbridge_softc *sc, uint a)
/*
* ATE can not be read as a whole, and need two 32 bit accesses.
*/
- hi = bus_space_read_4(sc->sc_iot, sc->sc_regh, BRIDGE_ATE(a) + 4);
- if (ISSET(sc->sc_flags, XBRIDGE_FLAGS_XBRIDGE))
- lo = bus_space_read_4(sc->sc_iot, sc->sc_regh,
- BRIDGE_ATE(a + 1024) + 4);
+ hi = xbridge_read_reg(xb, BRIDGE_ATE(a) + 4);
+ if (ISSET(xb->xb_flags, XF_XBRIDGE))
+ lo = xbridge_read_reg(xb, BRIDGE_ATE(a + 1024) + 4);
else
- lo = bus_space_read_4(sc->sc_iot, sc->sc_regh,
- BRIDGE_ATE(a + 512) + 4);
+ lo = xbridge_read_reg(xb, BRIDGE_ATE(a + 512) + 4);
ate = (uint64_t)hi;
ate <<= 32;
@@ -1372,13 +1525,13 @@ xbridge_ate_read(struct xbridge_softc *sc, uint a)
#endif
void
-xbridge_ate_write(struct xbridge_softc *sc, uint a, uint64_t ate)
+xbridge_ate_write(struct xbridge_bus *xb, uint a, uint64_t ate)
{
- bus_space_write_8(sc->sc_iot, sc->sc_regh, BRIDGE_ATE(a), ate);
+ widget_write_8(xb->xb_regt, xb->xb_regh, BRIDGE_ATE(a), ate);
}
uint
-xbridge_ate_find(struct xbridge_softc *sc, paddr_t pa)
+xbridge_ate_find(struct xbridge_bus *xb, paddr_t pa)
{
uint a;
struct xbridge_ate *ate;
@@ -1391,9 +1544,9 @@ xbridge_ate_find(struct xbridge_softc *sc, paddr_t pa)
* XXX that stupid linear search. On the other hand there
* XXX aren't many ATE entries.
*/
- LIST_FOREACH(ate, &sc->sc_used_ate, xa_nxt)
+ LIST_FOREACH(ate, &xb->xb_used_ate, xa_nxt)
if (ate->xa_pa == pa) {
- a = ate - sc->sc_ate;
+ a = ate - xb->xb_ate;
#ifdef ATE_DEBUG
printf("%s: pa %p ate %u (r %u)\n",
__func__, pa, a, ate->xa_refcnt);
@@ -1405,7 +1558,7 @@ xbridge_ate_find(struct xbridge_softc *sc, paddr_t pa)
}
uint
-xbridge_ate_add(struct xbridge_softc *sc, paddr_t pa)
+xbridge_ate_add(struct xbridge_bus *xb, paddr_t pa)
{
uint a;
struct xbridge_ate *ate;
@@ -1413,49 +1566,49 @@ xbridge_ate_add(struct xbridge_softc *sc, paddr_t pa)
/* round to ATE page */
pa &= ~BRIDGE_ATE_LMASK;
- if (LIST_EMPTY(&sc->sc_free_ate)) {
+ if (LIST_EMPTY(&xb->xb_free_ate)) {
#ifdef ATE_DEBUG
- printf("%s: out of ATEs\n", sc->sc_dev.dv_xname);
+ printf("%s: out of ATEs\n", DEVNAME(xb));
#endif
return (uint)-1;
}
- ate = LIST_FIRST(&sc->sc_free_ate);
+ ate = LIST_FIRST(&xb->xb_free_ate);
LIST_REMOVE(ate, xa_nxt);
- LIST_INSERT_HEAD(&sc->sc_used_ate, ate, xa_nxt);
+ LIST_INSERT_HEAD(&xb->xb_used_ate, ate, xa_nxt);
ate->xa_refcnt = 1;
ate->xa_pa = pa;
- a = ate - sc->sc_ate;
+ a = ate - xb->xb_ate;
#ifdef ATE_DEBUG
printf("%s: pa %p ate %u\n", __func__, pa, a);
#endif
- xbridge_ate_write(sc, a, ate->xa_pa |
+ xbridge_ate_write(xb, a, ate->xa_pa |
(xbow_intr_widget << ATE_WIDGET_SHIFT) | ATE_COH | ATE_V);
return a;
}
void
-xbridge_ate_unref(struct xbridge_softc *sc, uint a, uint ref)
+xbridge_ate_unref(struct xbridge_bus *xb, uint a, uint ref)
{
struct xbridge_ate *ate;
- ate = sc->sc_ate + a;
+ ate = xb->xb_ate + a;
#ifdef DIAGNOSTIC
if (ref > ate->xa_refcnt)
panic("%s: ate #%u %p has only %u refs but needs to drop %u",
- sc->sc_dev.dv_xname, a, ate, ate->xa_refcnt, ref);
+ DEVNAME(xb), a, ate, ate->xa_refcnt, ref);
#endif
ate->xa_refcnt -= ref;
if (ate->xa_refcnt == 0) {
#ifdef ATE_DEBUG
printf("%s: free ate %u\n", __func__, a);
#endif
- xbridge_ate_write(sc, a, ATE_NV);
+ xbridge_ate_write(xb, a, ATE_NV);
LIST_REMOVE(ate, xa_nxt);
- LIST_INSERT_HEAD(&sc->sc_free_ate, ate, xa_nxt);
+ LIST_INSERT_HEAD(&xb->xb_free_ate, ate, xa_nxt);
} else {
#ifdef ATE_DEBUG
printf("%s: unref ate %u (r %u)\n", __func__, a, ate->xa_refcnt);
@@ -1468,7 +1621,7 @@ xbridge_ate_unref(struct xbridge_softc *sc, uint a, uint ref)
* using an ATE.
*/
int
-xbridge_address_map(struct xbridge_softc *sc, paddr_t pa, bus_addr_t *mapping,
+xbridge_address_map(struct xbridge_bus *xb, paddr_t pa, bus_addr_t *mapping,
bus_addr_t *limit)
{
struct xbridge_ate *ate;
@@ -1498,14 +1651,14 @@ xbridge_address_map(struct xbridge_softc *sc, paddr_t pa, bus_addr_t *mapping,
* allocate a new one.
*/
- mtx_enter(&sc->sc_atemtx);
+ mtx_enter(&xb->xb_atemtx);
- a = xbridge_ate_find(sc, pa);
+ a = xbridge_ate_find(xb, pa);
if (a != (uint)-1) {
- ate = sc->sc_ate + a;
+ ate = xb->xb_ate + a;
ate->xa_refcnt++;
} else
- a = xbridge_ate_add(sc, pa);
+ a = xbridge_ate_add(xb, pa);
if (a != (uint)-1) {
ba = ATE_ADDRESS(a, BRIDGE_ATE_LSHIFT);
@@ -1514,23 +1667,23 @@ xbridge_address_map(struct xbridge_softc *sc, paddr_t pa, bus_addr_t *mapping,
* this setting is device-global and is enforced by
* BRIDGE_DEVICE_SWAP_PMU set in the devio register.
*/
- if (ISSET(sc->sc_flags, XBRIDGE_FLAGS_XBRIDGE))
+ if (ISSET(xb->xb_flags, XF_XBRIDGE))
ba |= XBRIDGE_DMA_TRANSLATED_SWAP;
#ifdef ATE_DEBUG
printf("%s: ate %u through %p\n", __func__, a, ba);
#endif
*mapping = ba + (pa & BRIDGE_ATE_LMASK);
*limit = ba + BRIDGE_ATE_LSIZE;
- mtx_leave(&sc->sc_atemtx);
+ mtx_leave(&xb->xb_atemtx);
return 0;
}
- printf("%s: out of ATE\n", sc->sc_dev.dv_xname);
+ printf("%s: out of ATE\n", DEVNAME(xb));
#ifdef ATE_DEBUG
- xbridge_ate_dump(sc);
+ xbridge_ate_dump(xb);
#endif
- mtx_leave(&sc->sc_atemtx);
+ mtx_leave(&xb->xb_atemtx);
/*
* We could try allocating a bounce buffer here.
@@ -1541,7 +1694,7 @@ xbridge_address_map(struct xbridge_softc *sc, paddr_t pa, bus_addr_t *mapping,
}
void
-xbridge_address_unmap(struct xbridge_softc *sc, bus_addr_t ba, bus_size_t len)
+xbridge_address_unmap(struct xbridge_bus *xb, bus_addr_t ba, bus_size_t len)
{
uint a;
uint refs;
@@ -1558,9 +1711,9 @@ xbridge_address_unmap(struct xbridge_softc *sc, bus_addr_t ba, bus_size_t len)
a = ATE_INDEX(ba, BRIDGE_ATE_LSHIFT);
#ifdef DIAGNOSTIC
- if (a >= sc->sc_atecnt)
+ if (a >= xb->xb_atecnt)
panic("%s: bus address %p references nonexisting ATE %u/%u",
- __func__, ba, a, sc->sc_atecnt);
+ __func__, ba, a, xb->xb_atecnt);
#endif
/*
@@ -1571,9 +1724,9 @@ xbridge_address_unmap(struct xbridge_softc *sc, bus_addr_t ba, bus_size_t len)
*/
refs = 1 + atop(ba + len - 1) - atop(ba);
- mtx_enter(&sc->sc_atemtx);
- xbridge_ate_unref(sc, a, refs);
- mtx_leave(&sc->sc_atemtx);
+ mtx_enter(&xb->xb_atemtx);
+ xbridge_ate_unref(xb, a, refs);
+ mtx_leave(&xb->xb_atemtx);
}
/*
@@ -1584,7 +1737,7 @@ xbridge_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
bus_size_t buflen, struct proc *p, int flags, paddr_t *lastaddrp,
int *segp, int first)
{
- struct xbridge_softc *sc = t->_cookie;
+ struct xbridge_bus *xb = t->_cookie;
bus_size_t sgsize;
bus_addr_t lastaddr, baddr, bmask;
bus_addr_t busaddr, endaddr;
@@ -1621,7 +1774,7 @@ xbridge_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
* Compute the DMA address and the physical range
* this mapping can cover.
*/
- if (xbridge_address_map(sc, pa, &busaddr, &endaddr) != 0) {
+ if (xbridge_address_map(xb, pa, &busaddr, &endaddr) != 0) {
rc = ENOMEM;
goto fail_unmap;
}
@@ -1664,7 +1817,7 @@ xbridge_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
else {
if (++seg >= map->_dm_segcnt) {
/* drop partial ATE reference */
- xbridge_address_unmap(sc, busaddr,
+ xbridge_address_unmap(xb, busaddr,
sgsize);
break;
}
@@ -1699,7 +1852,7 @@ fail_unmap:
* If control goes there, we need to unref all our ATE, if any.
*/
for (seg = 0; seg < map->_dm_segcnt; seg++) {
- xbridge_address_unmap(sc, map->dm_segs[seg].ds_addr,
+ xbridge_address_unmap(xb, map->dm_segs[seg].ds_addr,
map->dm_segs[seg].ds_len);
map->dm_segs[seg].ds_addr = 0;
}
@@ -1713,11 +1866,11 @@ fail_unmap:
void
xbridge_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map)
{
- struct xbridge_softc *sc = t->_cookie;
+ struct xbridge_bus *xb = t->_cookie;
int seg;
for (seg = 0; seg < map->_dm_segcnt; seg++) {
- xbridge_address_unmap(sc, map->dm_segs[seg].ds_addr,
+ xbridge_address_unmap(xb, map->dm_segs[seg].ds_addr,
map->dm_segs[seg].ds_len);
map->dm_segs[seg].ds_addr = 0;
}
@@ -1798,7 +1951,7 @@ xbridge_device_to_pa(bus_addr_t addr)
*/
void
-xbridge_setup(struct xbridge_softc *sc)
+xbridge_setup(struct xbridge_bus *xb)
{
paddr_t pa;
uint32_t ctrl;
@@ -1810,11 +1963,11 @@ xbridge_setup(struct xbridge_softc *sc)
* to be able to check quickly whether a given device is an IOC3.
*/
- for (dev = 0; dev < BRIDGE_NSLOTS; dev++) {
- pa = sc->sc_regh + BRIDGE_PCI_CFG_SPACE +
+ for (dev = 0; dev < xb->xb_nslots; dev++) {
+ pa = xb->xb_regh + BRIDGE_PCI_CFG_SPACE +
(dev << 12) + PCI_ID_REG;
- if (guarded_read_4(pa, &sc->sc_devices[dev].id) != 0)
- sc->sc_devices[dev].id =
+ if (guarded_read_4(pa, &xb->xb_devices[dev].id) != 0)
+ xb->xb_devices[dev].id =
PCI_ID_CODE(PCI_VENDOR_INVALID, 0xffff);
}
@@ -1824,11 +1977,10 @@ xbridge_setup(struct xbridge_softc *sc)
*/
if (sys_config.system_type == SGI_OCTANE)
- bus_space_write_4(sc->sc_iot, sc->sc_regh, BRIDGE_DIR_MAP,
- (xbow_intr_widget << BRIDGE_DIRMAP_WIDGET_SHIFT) |
- BRIDGE_DIRMAP_ADD_512MB);
+ xbridge_write_reg(xb, BRIDGE_DIR_MAP, BRIDGE_DIRMAP_ADD_512MB |
+ (xbow_intr_widget << BRIDGE_DIRMAP_WIDGET_SHIFT));
else
- bus_space_write_4(sc->sc_iot, sc->sc_regh, BRIDGE_DIR_MAP,
+ xbridge_write_reg(xb, BRIDGE_DIR_MAP,
xbow_intr_widget << BRIDGE_DIRMAP_WIDGET_SHIFT);
/*
@@ -1836,14 +1988,14 @@ xbridge_setup(struct xbridge_softc *sc)
* setup our ATE management code.
*/
- xbridge_ate_setup(sc);
+ xbridge_ate_setup(xb);
/*
* Allocate RRB for the existing devices.
*/
- xbridge_rrb_setup(sc, 0);
- xbridge_rrb_setup(sc, 1);
+ xbridge_rrb_setup(xb, 0);
+ xbridge_rrb_setup(xb, 1);
/*
* Disable byteswapping on PIO accesses through the large window
@@ -1852,42 +2004,42 @@ xbridge_setup(struct xbridge_softc *sc)
* but better enforce this anyway.
*/
- ctrl = bus_space_read_4(sc->sc_iot, sc->sc_regh, WIDGET_CONTROL);
+ ctrl = xbridge_read_reg(xb, WIDGET_CONTROL);
ctrl &= ~BRIDGE_WIDGET_CONTROL_IO_SWAP;
ctrl &= ~BRIDGE_WIDGET_CONTROL_MEM_SWAP;
- bus_space_write_4(sc->sc_iot, sc->sc_regh, WIDGET_CONTROL, ctrl);
- (void)bus_space_read_4(sc->sc_iot, sc->sc_regh, WIDGET_TFLUSH);
+ xbridge_write_reg(xb, WIDGET_CONTROL, ctrl);
+ (void)xbridge_read_reg(xb, WIDGET_TFLUSH);
/*
* The PROM will only configure the onboard devices. Set up
* any other device we might encounter.
*/
- xbridge_resource_setup(sc);
+ xbridge_resource_setup(xb);
/*
* Setup interrupt handling.
*/
- bus_space_write_4(sc->sc_iot, sc->sc_regh, BRIDGE_IER, 0);
- bus_space_write_4(sc->sc_iot, sc->sc_regh, BRIDGE_INT_MODE, 0);
- bus_space_write_4(sc->sc_iot, sc->sc_regh, BRIDGE_INT_DEV, 0);
+ xbridge_write_reg(xb, BRIDGE_IER, 0);
+ xbridge_write_reg(xb, BRIDGE_INT_MODE, 0);
+ xbridge_write_reg(xb, BRIDGE_INT_DEV, 0);
- bus_space_write_4(sc->sc_iot, sc->sc_regh, WIDGET_INTDEST_ADDR_UPPER,
+ xbridge_write_reg(xb, WIDGET_INTDEST_ADDR_UPPER,
(xbow_intr_widget_register >> 32) | (xbow_intr_widget << 16));
- bus_space_write_4(sc->sc_iot, sc->sc_regh, WIDGET_INTDEST_ADDR_LOWER,
+ xbridge_write_reg(xb, WIDGET_INTDEST_ADDR_LOWER,
(uint32_t)xbow_intr_widget_register);
- (void)bus_space_read_4(sc->sc_iot, sc->sc_regh, WIDGET_TFLUSH);
+ (void)xbridge_read_reg(xb, WIDGET_TFLUSH);
}
/*
* Build a not-so-pessimistic RRB allocation register value.
*/
void
-xbridge_rrb_setup(struct xbridge_softc *sc, int odd)
+xbridge_rrb_setup(struct xbridge_bus *xb, int odd)
{
- uint rrb[BRIDGE_NSLOTS / 2]; /* tentative rrb assignment */
+ uint rrb[MAX_SLOTS / 2]; /* tentative rrb assignment */
uint total; /* rrb count */
uint32_t proto; /* proto rrb value */
int dev, i, j;
@@ -1897,9 +2049,10 @@ xbridge_rrb_setup(struct xbridge_softc *sc, int odd)
*/
total = 0;
- for (i = 0; i < BRIDGE_NSLOTS / 2; i++) {
+ for (i = 0; i < nitems(rrb); i++) {
dev = (i << 1) + !!odd;
- if (PCI_VENDOR(sc->sc_devices[dev].id) == PCI_VENDOR_INVALID)
+ if (dev >= xb->xb_nslots ||
+ PCI_VENDOR(xb->xb_devices[dev].id) == PCI_VENDOR_INVALID)
rrb[i] = 0;
else
rrb[i] = 4; /* optimistic value */
@@ -1916,7 +2069,7 @@ xbridge_rrb_setup(struct xbridge_softc *sc, int odd)
* All devices should be able to live with 3 RRBs, so
* reduce their allocation from 4 to 3.
*/
- for (i = 0; i < BRIDGE_NSLOTS / 2; i++) {
+ for (i = 0; i < nitems(rrb); i++) {
if (rrb[i] == 4) {
rrb[i]--;
if (--total == 8)
@@ -1931,10 +2084,10 @@ xbridge_rrb_setup(struct xbridge_softc *sc, int odd)
* be possible. Attempt to reduce from 3 to 2, except
* for isp(4) devices.
*/
- for (i = 0; i < BRIDGE_NSLOTS / 2; i++) {
+ for (i = 0; i < nitems(rrb); i++) {
if (rrb[i] == 3) {
dev = (i << 1) + !!odd;
- if (PCI_VENDOR(sc->sc_devices[dev].id) !=
+ if (PCI_VENDOR(xb->xb_devices[dev].id) !=
PCI_VENDOR_QLOGIC) {
rrb[i]--;
if (--total == 8)
@@ -1950,7 +2103,7 @@ xbridge_rrb_setup(struct xbridge_softc *sc, int odd)
* isp devices too. We'll try to favour the lowest
* slots, though, hence the reversed loop order.
*/
- for (i = BRIDGE_NSLOTS / 2 - 1; i >= 0; i--) {
+ for (i = nitems(rrb) - 1; i >= 0; i--) {
if (rrb[i] == 3) {
rrb[i]--;
if (--total == 8)
@@ -1964,22 +2117,21 @@ xbridge_rrb_setup(struct xbridge_softc *sc, int odd)
*/
proto = 0;
- for (i = 0; i < BRIDGE_NSLOTS / 2; i++) {
+ for (i = 0; i < nitems(rrb); i++) {
for (j = 0; j < rrb[i]; j++)
proto = (proto << RRB_SHIFT) | (RRB_VALID | i);
}
- bus_space_write_4(sc->sc_iot, sc->sc_regh,
- odd ? BRIDGE_RRB_ODD : BRIDGE_RRB_EVEN, proto);
+ xbridge_write_reg(xb, odd ? BRIDGE_RRB_ODD : BRIDGE_RRB_EVEN, proto);
}
/*
* Configure PCI resources for all devices.
*/
void
-xbridge_resource_setup(struct xbridge_softc *sc)
+xbridge_resource_setup(struct xbridge_bus *xb)
{
- pci_chipset_tag_t pc = &sc->sc_pc;
+ pci_chipset_tag_t pc = &xb->xb_pc;
int dev, nfuncs;
pcitag_t tag;
pcireg_t id, bhlcr;
@@ -1989,17 +2141,6 @@ xbridge_resource_setup(struct xbridge_softc *sc)
const struct pci_quirkdata *qd;
/*
- * Figure out where the devio mappings will go.
- * On Octane, they are relative to the start of the widget.
- * On Origin, they are computed from the widget number.
- */
-
- if (sys_config.system_type == SGI_OCTANE)
- sc->sc_devio_skew = 0;
- else
- sc->sc_devio_skew = sc->sc_widget;
-
- /*
* On Octane, we will want to map everything through the large
* windows, whenever possible.
*
@@ -2007,8 +2148,8 @@ xbridge_resource_setup(struct xbridge_softc *sc)
*/
if (sys_config.system_type == SGI_OCTANE) {
- sc->sc_ioex = xbridge_mapping_setup(sc, 1);
- sc->sc_memex = xbridge_mapping_setup(sc, 0);
+ xb->xb_ioex = xbridge_mapping_setup(xb, 1);
+ xb->xb_memex = xbridge_mapping_setup(xb, 0);
}
/*
@@ -2016,8 +2157,8 @@ xbridge_resource_setup(struct xbridge_softc *sc)
*/
nppb = npccbb = 0;
- for (dev = 0; dev < BRIDGE_NSLOTS; dev++) {
- id = sc->sc_devices[dev].id;
+ for (dev = 0; dev < xb->xb_nslots; dev++) {
+ id = xb->xb_devices[dev].id;
if (PCI_VENDOR(id) == PCI_VENDOR_INVALID || PCI_VENDOR(id) == 0)
continue;
@@ -2050,15 +2191,14 @@ xbridge_resource_setup(struct xbridge_softc *sc)
* we'll need to perform proper PCI resource allocation.
*/
- devio = bus_space_read_4(sc->sc_iot, sc->sc_regh,
- BRIDGE_DEVICE(dev));
+ devio = xbridge_read_reg(xb, BRIDGE_DEVICE(dev));
#ifdef DEBUG
printf("device %d: devio %08x\n", dev, devio);
#endif
if (id != PCI_ID_CODE(PCI_VENDOR_SGI, PCI_PRODUCT_SGI_IOC3))
need_setup = 1;
else
- need_setup = sc->sc_devio_skew !=
+ need_setup = xb->xb_devio_skew !=
((devio & BRIDGE_DEVICE_BASE_MASK) >>
(24 - BRIDGE_DEVICE_BASE_SHIFT));
@@ -2066,7 +2206,7 @@ xbridge_resource_setup(struct xbridge_softc *sc)
* Enable byte swapping for DMA, except on IOC3 and
* RAD1 devices.
*/
- if (ISSET(sc->sc_flags, XBRIDGE_FLAGS_XBRIDGE))
+ if (ISSET(xb->xb_flags, XF_XBRIDGE))
devio &= ~BRIDGE_DEVICE_SWAP_PMU;
else
devio |= BRIDGE_DEVICE_SWAP_PMU;
@@ -2089,7 +2229,7 @@ xbridge_resource_setup(struct xbridge_softc *sc)
devio |= BRIDGE_DEVICE_COHERENT;
if (need_setup == 0) {
- xbridge_set_devio(sc, dev, devio);
+ xbridge_set_devio(xb, dev, devio);
continue;
}
@@ -2098,7 +2238,7 @@ xbridge_resource_setup(struct xbridge_softc *sc)
*/
devio &= ~BRIDGE_DEVICE_BASE_MASK;
devio &= ~BRIDGE_DEVICE_IO_MEM;
- xbridge_set_devio(sc, dev, devio);
+ xbridge_set_devio(xb, dev, devio);
/*
* We now need to perform the resource allocation for this
@@ -2112,7 +2252,7 @@ xbridge_resource_setup(struct xbridge_softc *sc)
else
nfuncs = 1;
- xbridge_device_setup(sc, dev, nfuncs, devio);
+ xbridge_device_setup(xb, dev, nfuncs, devio);
}
/*
@@ -2127,16 +2267,16 @@ xbridge_resource_setup(struct xbridge_softc *sc)
* If there are PCI-CardBus bridges, we really want to be
* able to have large resource spaces...
*/
- if (sc->sc_ioex == NULL)
- sc->sc_ioex = xbridge_mapping_setup(sc, 1);
- if (sc->sc_memex == NULL)
- sc->sc_memex = xbridge_mapping_setup(sc, 0);
+ if (xb->xb_ioex == NULL)
+ xb->xb_ioex = xbridge_mapping_setup(xb, 1);
+ if (xb->xb_memex == NULL)
+ xb->xb_memex = xbridge_mapping_setup(xb, 0);
}
secondary = 1;
ppbstride = nppb == 0 ? 0 : (255 - npccbb) / nppb;
- for (dev = 0; dev < BRIDGE_NSLOTS; dev++) {
- id = sc->sc_devices[dev].id;
+ for (dev = 0; dev < xb->xb_nslots; dev++) {
+ id = xb->xb_devices[dev].id;
if (PCI_VENDOR(id) == PCI_VENDOR_INVALID || PCI_VENDOR(id) == 0)
continue;
@@ -2162,13 +2302,13 @@ xbridge_resource_setup(struct xbridge_softc *sc)
}
}
- if (sc->sc_ioex != NULL) {
- extent_destroy(sc->sc_ioex);
- sc->sc_ioex = NULL;
+ if (xb->xb_ioex != NULL) {
+ extent_destroy(xb->xb_ioex);
+ xb->xb_ioex = NULL;
}
- if (sc->sc_memex != NULL) {
- extent_destroy(sc->sc_memex);
- sc->sc_memex = NULL;
+ if (xb->xb_memex != NULL) {
+ extent_destroy(xb->xb_memex);
+ xb->xb_memex = NULL;
}
}
@@ -2178,23 +2318,23 @@ xbridge_resource_setup(struct xbridge_softc *sc)
* views, if applicable.
*/
void
-xbridge_extent_setup(struct xbridge_softc *sc)
+xbridge_extent_setup(struct xbridge_bus *xb)
{
int dev;
int errors;
bus_addr_t start, end;
uint32_t devio;
- snprintf(sc->sc_ioexname, sizeof(sc->sc_ioexname), "%s_io",
- sc->sc_dev.dv_xname);
- sc->sc_ioex = extent_create(sc->sc_ioexname, 0, 0xffffffff,
+ snprintf(xb->xb_ioexname, sizeof(xb->xb_ioexname), "%s_io",
+ DEVNAME(xb));
+ xb->xb_ioex = extent_create(xb->xb_ioexname, 0, 0xffffffff,
M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED);
- if (sc->sc_ioex != NULL) {
+ if (xb->xb_ioex != NULL) {
errors = 0;
/* make all configured devio ranges available... */
- for (dev = 0; dev < BRIDGE_NSLOTS; dev++) {
- devio = sc->sc_devices[dev].devio;
+ for (dev = 0; dev < xb->xb_nslots; dev++) {
+ devio = xb->xb_devices[dev].devio;
if (devio == 0)
continue;
if (ISSET(devio, BRIDGE_DEVICE_IO_MEM))
@@ -2203,89 +2343,89 @@ xbridge_extent_setup(struct xbridge_softc *sc)
BRIDGE_DEVICE_BASE_SHIFT;
if (start == 0)
continue;
- if (extent_free(sc->sc_ioex, start,
+ if (extent_free(xb->xb_ioex, start,
BRIDGE_DEVIO_SIZE(dev), EX_NOWAIT) != 0) {
errors++;
break;
}
}
/* ...as well as the large views, if any */
- if (sc->sc_ioend != 0) {
- start = sc->sc_iostart;
+ if (xb->xb_ioend != 0) {
+ start = xb->xb_iostart;
if (start == 0)
start = 1;
- end = sc->sc_devio_skew << 24;
+ end = xb->xb_devio_skew << 24;
if (start < end)
- if (extent_free(sc->sc_ioex, start,
+ if (extent_free(xb->xb_ioex, start,
end, EX_NOWAIT) != 0)
errors++;
- start = (sc->sc_devio_skew + 1) << 24;
- if (start < sc->sc_iostart)
- start = sc->sc_iostart;
- if (extent_free(sc->sc_ioex, start,
- sc->sc_ioend + 1 - start, EX_NOWAIT) != 0)
+ start = (xb->xb_devio_skew + 1) << 24;
+ if (start < xb->xb_iostart)
+ start = xb->xb_iostart;
+ if (extent_free(xb->xb_ioex, start,
+ xb->xb_ioend + 1 - start, EX_NOWAIT) != 0)
errors++;
}
if (errors != 0) {
- extent_destroy(sc->sc_ioex);
- sc->sc_ioex = NULL;
+ extent_destroy(xb->xb_ioex);
+ xb->xb_ioex = NULL;
}
}
- snprintf(sc->sc_memexname, sizeof(sc->sc_memexname), "%s_mem",
- sc->sc_dev.dv_xname);
- sc->sc_memex = extent_create(sc->sc_memexname, 0, 0xffffffff,
+ snprintf(xb->xb_memexname, sizeof(xb->xb_memexname), "%s_mem",
+ DEVNAME(xb));
+ xb->xb_memex = extent_create(xb->xb_memexname, 0, 0xffffffff,
M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED);
- if (sc->sc_memex != NULL) {
+ if (xb->xb_memex != NULL) {
errors = 0;
/* make all configured devio ranges available... */
- for (dev = 0; dev < BRIDGE_NSLOTS; dev++) {
- devio = sc->sc_devices[dev].devio;
+ for (dev = 0; dev < xb->xb_nslots; dev++) {
+ devio = xb->xb_devices[dev].devio;
if (devio == 0 || !ISSET(devio, BRIDGE_DEVICE_IO_MEM))
continue;
start = (devio & BRIDGE_DEVICE_BASE_MASK) <<
BRIDGE_DEVICE_BASE_SHIFT;
if (start == 0)
continue;
- if (extent_free(sc->sc_memex, start,
+ if (extent_free(xb->xb_memex, start,
BRIDGE_DEVIO_SIZE(dev), EX_NOWAIT) != 0) {
errors++;
break;
}
}
/* ...as well as the large views, if any */
- if (sc->sc_memend != 0) {
- start = sc->sc_memstart;
+ if (xb->xb_memend != 0) {
+ start = xb->xb_memstart;
if (start == 0)
start = 1;
- end = sc->sc_devio_skew << 24;
+ end = xb->xb_devio_skew << 24;
if (start < end)
- if (extent_free(sc->sc_memex, start,
+ if (extent_free(xb->xb_memex, start,
end, EX_NOWAIT) != 0)
errors++;
- start = (sc->sc_devio_skew + 1) << 24;
- if (start < sc->sc_memstart)
- start = sc->sc_memstart;
- if (extent_free(sc->sc_memex, start,
- sc->sc_memend + 1 - start, EX_NOWAIT) != 0)
+ start = (xb->xb_devio_skew + 1) << 24;
+ if (start < xb->xb_memstart)
+ start = xb->xb_memstart;
+ if (extent_free(xb->xb_memex, start,
+ xb->xb_memend + 1 - start, EX_NOWAIT) != 0)
errors++;
}
if (errors != 0) {
- extent_destroy(sc->sc_memex);
- sc->sc_memex = NULL;
+ extent_destroy(xb->xb_memex);
+ xb->xb_memex = NULL;
}
}
}
struct extent *
-xbridge_mapping_setup(struct xbridge_softc *sc, int io)
+xbridge_mapping_setup(struct xbridge_bus *xb, int io)
{
- bus_addr_t offs;
+ bus_addr_t membase, offs;
bus_size_t len;
paddr_t base;
u_long start, end;
@@ -2299,11 +2439,11 @@ xbridge_mapping_setup(struct xbridge_softc *sc, int io)
* didn't work was the byteswap logic).
*/
- if (!ISSET(sc->sc_flags, XBRIDGE_FLAGS_NO_DIRECT_IO)) {
+ if (!ISSET(xb->xb_flags, XF_NO_DIRECT_IO)) {
offs = BRIDGE_PCI_IO_SPACE_BASE;
len = BRIDGE_PCI_IO_SPACE_LENGTH;
- base = xbow_widget_map_space(sc->sc_dev.dv_parent,
- sc->sc_widget, &offs, &len);
+ base = xbow_widget_map_space(xb->xb_sc->sc_dev.dv_parent,
+ xb->xb_widget, &offs, &len);
} else
base = 0;
@@ -2324,26 +2464,28 @@ xbridge_mapping_setup(struct xbridge_softc *sc, int io)
M_DEVBUF, NULL, 0, EX_NOWAIT);
if (ex != NULL) {
- sc->sc_io_bus_space->bus_base = base - offs;
- sc->sc_io_bus_space->_space_map =
+ xb->xb_io_bus_space->bus_base = base - offs;
+ xb->xb_io_bus_space->_space_map =
xbridge_space_map_io;
- sc->sc_io_bus_space->_space_subregion =
+ xb->xb_io_bus_space->_space_subregion =
xbridge_space_region_io;
- sc->sc_iostart = offs;
- sc->sc_ioend = offs + len - 1;
+ xb->xb_iostart = offs;
+ xb->xb_ioend = offs + len - 1;
}
}
} else {
/*
* Memory mappings are available in the widget at offset
- * BRIDGE_PCI_MEM_SPACE_BASE onwards.
+ * BRIDGE_PCI#_MEM_SPACE_BASE onwards.
*/
- offs = BRIDGE_PCI_MEM_SPACE_BASE;
+ membase = xb->xb_busno == 0 ? BRIDGE_PCI0_MEM_SPACE_BASE :
+ BRIDGE_PCI1_MEM_SPACE_BASE;
+ offs = membase;
len = BRIDGE_PCI_MEM_SPACE_LENGTH;
- base = xbow_widget_map_space(sc->sc_dev.dv_parent,
- sc->sc_widget, &offs, &len);
+ base = xbow_widget_map_space(xb->xb_sc->sc_dev.dv_parent,
+ xb->xb_widget, &offs, &len);
if (base != 0) {
/*
@@ -2351,30 +2493,29 @@ xbridge_mapping_setup(struct xbridge_softc *sc, int io)
* by the hardware, thus restricting memory mappings
* to 1GB.
*/
- if (offs + len > BRIDGE_PCI_MEM_SPACE_BASE +
- BRIDGE_PCI_MEM_SPACE_LENGTH)
- len = BRIDGE_PCI_MEM_SPACE_BASE +
- BRIDGE_PCI_MEM_SPACE_LENGTH - offs;
+ if (offs + len > membase + BRIDGE_PCI_MEM_SPACE_LENGTH)
+ len = membase + BRIDGE_PCI_MEM_SPACE_LENGTH -
+ offs;
#ifdef DEBUG
printf("direct mem %p-%p base %p\n",
offs, offs + len - 1, base);
#endif
- offs -= BRIDGE_PCI_MEM_SPACE_BASE;
+ offs -= membase;
ex = extent_create("xbridge_direct_mem",
offs == 0 ? 1 : offs, offs + len - 1,
M_DEVBUF, NULL, 0, EX_NOWAIT);
if (ex != NULL) {
- sc->sc_mem_bus_space->bus_base = base - offs;
- sc->sc_mem_bus_space->_space_map =
+ xb->xb_mem_bus_space->bus_base = base - offs;
+ xb->xb_mem_bus_space->_space_map =
xbridge_space_map_mem;
- sc->sc_mem_bus_space->_space_subregion =
+ xb->xb_mem_bus_space->_space_subregion =
xbridge_space_region_mem;
- sc->sc_memstart = offs;
- sc->sc_memend = offs + len - 1;
+ xb->xb_memstart = offs;
+ xb->xb_memend = offs + len - 1;
}
}
}
@@ -2387,8 +2528,8 @@ xbridge_mapping_setup(struct xbridge_softc *sc, int io)
* Note that xbow_widget_map_space() may have returned
* a range in which the devio area does not appear.
*/
- start = sc->sc_devio_skew << 24;
- end = (sc->sc_devio_skew + 1) << 24;
+ start = xb->xb_devio_skew << 24;
+ end = (xb->xb_devio_skew + 1) << 24;
if (end >= ex->ex_start && start <= ex->ex_end) {
if (start < ex->ex_start)
@@ -2399,8 +2540,7 @@ xbridge_mapping_setup(struct xbridge_softc *sc, int io)
EX_NOWAIT | EX_MALLOCOK) != 0) {
printf("%s: failed to expurge devio range"
" from %s large extent\n",
- sc->sc_dev.dv_xname,
- io ? "i/o" : "mem");
+ DEVNAME(xb), io ? "i/o" : "mem");
extent_destroy(ex);
ex = NULL;
}
@@ -2421,10 +2561,10 @@ xbridge_mapping_setup(struct xbridge_softc *sc, int io)
#define XR_MEM_OFLOW 0x20 /* can't fit memory in a large devio */
int
-xbridge_resource_explore(struct xbridge_softc *sc, pcitag_t tag,
+xbridge_resource_explore(struct xbridge_bus *xb, pcitag_t tag,
struct extent *ioex, struct extent *memex)
{
- pci_chipset_tag_t pc = &sc->sc_pc;
+ pci_chipset_tag_t pc = &xb->xb_pc;
pcireg_t bhlc, type, addr, mask;
bus_addr_t base;
bus_size_t size;
@@ -2518,10 +2658,10 @@ xbridge_resource_explore(struct xbridge_softc *sc, pcitag_t tag,
}
void
-xbridge_resource_manage(struct xbridge_softc *sc, pcitag_t tag,
+xbridge_resource_manage(struct xbridge_bus *xb, pcitag_t tag,
struct extent *ioex, struct extent *memex)
{
- pci_chipset_tag_t pc = &sc->sc_pc;
+ pci_chipset_tag_t pc = &xb->xb_pc;
pcireg_t bhlc, type, mask;
bus_addr_t base;
bus_size_t size;
@@ -2631,14 +2771,14 @@ xbridge_resource_manage(struct xbridge_softc *sc, pcitag_t tag,
}
void
-xbridge_device_setup(struct xbridge_softc *sc, int dev, int nfuncs,
+xbridge_device_setup(struct xbridge_bus *xb, int dev, int nfuncs,
uint32_t devio)
{
- pci_chipset_tag_t pc = &sc->sc_pc;
+ pci_chipset_tag_t pc = &xb->xb_pc;
int function;
pcitag_t tag;
pcireg_t id, csr;
- uint32_t basewin;
+ uint32_t baseio;
int resources;
int io_devio, mem_devio;
struct extent *ioex, *memex;
@@ -2656,13 +2796,13 @@ xbridge_device_setup(struct xbridge_softc *sc, int dev, int nfuncs,
* This can fail; in that case we'll try to use a large mapping
* whenever possible, or silently fail to configure the device.
*/
- if (sc->sc_ioex != NULL)
+ if (xb->xb_ioex != NULL)
ioex = NULL;
else
ioex = extent_create("xbridge_io",
0, BRIDGE_DEVIO_LARGE - 1,
M_DEVBUF, NULL, 0, EX_NOWAIT);
- if (sc->sc_memex != NULL)
+ if (xb->xb_memex != NULL)
memex = NULL;
else
memex = extent_create("xbridge_mem",
@@ -2682,7 +2822,7 @@ xbridge_device_setup(struct xbridge_softc *sc, int dev, int nfuncs,
pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr &
~(PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE));
- resources |= xbridge_resource_explore(sc, tag, ioex, memex);
+ resources |= xbridge_resource_explore(xb, tag, ioex, memex);
}
if (memex != NULL) {
@@ -2708,25 +2848,25 @@ xbridge_device_setup(struct xbridge_softc *sc, int dev, int nfuncs,
if (ISSET(resources, XR_IO)) {
if (!ISSET(resources, XR_IO_OFLOW) &&
(sys_config.system_type != SGI_OCTANE ||
- sc->sc_ioex == NULL))
- io_devio = xbridge_allocate_devio(sc, dev,
+ xb->xb_ioex == NULL))
+ io_devio = xbridge_allocate_devio(xb, dev,
ISSET(resources, XR_IO_OFLOW_S));
if (io_devio >= 0) {
- basewin = (sc->sc_devio_skew << 24) |
- BRIDGE_DEVIO_OFFS(io_devio);
- xbridge_set_devio(sc, io_devio, devio |
- (basewin >> BRIDGE_DEVICE_BASE_SHIFT));
+ baseio = (xb->xb_devio_skew << 24) |
+ PIC_DEVIO_OFFS(xb->xb_busno, io_devio);
+ xbridge_set_devio(xb, io_devio, devio |
+ (baseio >> BRIDGE_DEVICE_BASE_SHIFT));
- ioex = extent_create("xbridge_io", basewin,
- basewin + BRIDGE_DEVIO_SIZE(io_devio) - 1,
+ ioex = extent_create("xbridge_io", baseio,
+ baseio + BRIDGE_DEVIO_SIZE(io_devio) - 1,
M_DEVBUF, NULL, 0, EX_NOWAIT);
} else {
/*
* Try to get a large window mapping if we don't
* have one already.
*/
- if (sc->sc_ioex == NULL)
- sc->sc_ioex = xbridge_mapping_setup(sc, 1);
+ if (xb->xb_ioex == NULL)
+ xb->xb_ioex = xbridge_mapping_setup(xb, 1);
}
}
@@ -2734,25 +2874,25 @@ xbridge_device_setup(struct xbridge_softc *sc, int dev, int nfuncs,
if (ISSET(resources, XR_MEM)) {
if (!ISSET(resources, XR_MEM_OFLOW) &&
sys_config.system_type != SGI_OCTANE)
- mem_devio = xbridge_allocate_devio(sc, dev,
+ mem_devio = xbridge_allocate_devio(xb, dev,
ISSET(resources, XR_MEM_OFLOW_S));
if (mem_devio >= 0) {
- basewin = (sc->sc_devio_skew << 24) |
- BRIDGE_DEVIO_OFFS(mem_devio);
- xbridge_set_devio(sc, mem_devio, devio |
+ baseio = (xb->xb_devio_skew << 24) |
+ PIC_DEVIO_OFFS(xb->xb_busno, mem_devio);
+ xbridge_set_devio(xb, mem_devio, devio |
BRIDGE_DEVICE_IO_MEM |
- (basewin >> BRIDGE_DEVICE_BASE_SHIFT));
+ (baseio >> BRIDGE_DEVICE_BASE_SHIFT));
- memex = extent_create("xbridge_mem", basewin,
- basewin + BRIDGE_DEVIO_SIZE(mem_devio) - 1,
+ memex = extent_create("xbridge_mem", baseio,
+ baseio + BRIDGE_DEVIO_SIZE(mem_devio) - 1,
M_DEVBUF, NULL, 0, EX_NOWAIT);
} else {
/*
* Try to get a large window mapping if we don't
* have one already.
*/
- if (sc->sc_memex == NULL)
- sc->sc_memex = xbridge_mapping_setup(sc, 0);
+ if (xb->xb_memex == NULL)
+ xb->xb_memex = xbridge_mapping_setup(xb, 0);
}
}
@@ -2769,9 +2909,9 @@ xbridge_device_setup(struct xbridge_softc *sc, int dev, int nfuncs,
PCI_VENDOR(id) == 0)
continue;
- xbridge_resource_manage(sc, tag,
- ioex != NULL ? ioex : sc->sc_ioex,
- memex != NULL ? memex : sc->sc_memex);
+ xbridge_resource_manage(xb, tag,
+ ioex != NULL ? ioex : xb->xb_ioex,
+ memex != NULL ? memex : xb->xb_memex);
}
if (memex != NULL)
@@ -2784,15 +2924,15 @@ int
xbridge_ppb_setup(void *cookie, pcitag_t tag, bus_addr_t *iostart,
bus_addr_t *ioend, bus_addr_t *memstart, bus_addr_t *memend)
{
- struct xbridge_softc *sc = cookie;
- pci_chipset_tag_t pc = &sc->sc_pc;
+ struct xbridge_bus *xb = cookie;
+ pci_chipset_tag_t pc = &xb->xb_pc;
uint32_t base, devio;
bus_size_t exsize;
u_long exstart;
int dev, devio_idx, tries;
pci_decompose_tag(pc, tag, NULL, &dev, NULL);
- devio = bus_space_read_4(sc->sc_iot, sc->sc_regh, BRIDGE_DEVICE(dev));
+ devio = xbridge_read_reg(xb, BRIDGE_DEVICE(dev));
/*
* Since our caller computes resource needs starting at zero, we
@@ -2806,33 +2946,33 @@ xbridge_ppb_setup(void *cookie, pcitag_t tag, bus_addr_t *iostart,
if (exsize++ != 0) {
/* try to allocate through a devio slot whenever possible... */
if (exsize < BRIDGE_DEVIO_SHORT)
- devio_idx = xbridge_allocate_devio(sc, dev, 0);
+ devio_idx = xbridge_allocate_devio(xb, dev, 0);
else if (exsize < BRIDGE_DEVIO_LARGE)
- devio_idx = xbridge_allocate_devio(sc, dev, 1);
+ devio_idx = xbridge_allocate_devio(xb, dev, 1);
else
devio_idx = -1;
/* ...if it fails, try the large view.... */
- if (devio_idx < 0 && sc->sc_memex == NULL)
- sc->sc_memex = xbridge_mapping_setup(sc, 0);
+ if (devio_idx < 0 && xb->xb_memex == NULL)
+ xb->xb_memex = xbridge_mapping_setup(xb, 0);
/* ...if it is not available, try to get a devio slot anyway. */
- if (devio_idx < 0 && sc->sc_memex == NULL) {
+ if (devio_idx < 0 && xb->xb_memex == NULL) {
if (exsize > BRIDGE_DEVIO_SHORT)
- devio_idx = xbridge_allocate_devio(sc, dev, 1);
+ devio_idx = xbridge_allocate_devio(xb, dev, 1);
if (devio_idx < 0)
- devio_idx = xbridge_allocate_devio(sc, dev, 0);
+ devio_idx = xbridge_allocate_devio(xb, dev, 0);
}
if (devio_idx >= 0) {
- base = (sc->sc_devio_skew << 24) |
- BRIDGE_DEVIO_OFFS(devio_idx);
- xbridge_set_devio(sc, devio_idx, devio |
+ base = (xb->xb_devio_skew << 24) |
+ PIC_DEVIO_OFFS(xb->xb_busno, devio_idx);
+ xbridge_set_devio(xb, devio_idx, devio |
BRIDGE_DEVICE_IO_MEM |
(base >> BRIDGE_DEVICE_BASE_SHIFT));
*memstart = base;
*memend = base + BRIDGE_DEVIO_SIZE(devio_idx) - 1;
- } else if (sc->sc_memex != NULL) {
+ } else if (xb->xb_memex != NULL) {
/*
* We know that the direct memory resource range fits
* within the 32 bit address space, and is limited to
@@ -2842,7 +2982,7 @@ xbridge_ppb_setup(void *cookie, pcitag_t tag, bus_addr_t *iostart,
if (exsize < 1UL << 20)
exsize = 1UL << 20;
for (tries = 0; tries < 5; tries++) {
- if (extent_alloc(sc->sc_memex, exsize,
+ if (extent_alloc(xb->xb_memex, exsize,
1UL << 20, 0, 0, EX_NOWAIT | EX_MALLOCOK,
&exstart) == 0) {
*memstart = exstart;
@@ -2862,32 +3002,32 @@ xbridge_ppb_setup(void *cookie, pcitag_t tag, bus_addr_t *iostart,
if (exsize++ != 0) {
/* try to allocate through a devio slot whenever possible... */
if (exsize < BRIDGE_DEVIO_SHORT)
- devio_idx = xbridge_allocate_devio(sc, dev, 0);
+ devio_idx = xbridge_allocate_devio(xb, dev, 0);
else if (exsize < BRIDGE_DEVIO_LARGE)
- devio_idx = xbridge_allocate_devio(sc, dev, 1);
+ devio_idx = xbridge_allocate_devio(xb, dev, 1);
else
devio_idx = -1;
/* ...if it fails, try the large view.... */
- if (devio_idx < 0 && sc->sc_ioex == NULL)
- sc->sc_ioex = xbridge_mapping_setup(sc, 1);
+ if (devio_idx < 0 && xb->xb_ioex == NULL)
+ xb->xb_ioex = xbridge_mapping_setup(xb, 1);
/* ...if it is not available, try to get a devio slot anyway. */
- if (devio_idx < 0 && sc->sc_ioex == NULL) {
+ if (devio_idx < 0 && xb->xb_ioex == NULL) {
if (exsize > BRIDGE_DEVIO_SHORT)
- devio_idx = xbridge_allocate_devio(sc, dev, 1);
+ devio_idx = xbridge_allocate_devio(xb, dev, 1);
if (devio_idx < 0)
- devio_idx = xbridge_allocate_devio(sc, dev, 0);
+ devio_idx = xbridge_allocate_devio(xb, dev, 0);
}
if (devio_idx >= 0) {
- base = (sc->sc_devio_skew << 24) |
- BRIDGE_DEVIO_OFFS(devio_idx);
- xbridge_set_devio(sc, devio_idx, devio |
+ base = (xb->xb_devio_skew << 24) |
+ PIC_DEVIO_OFFS(xb->xb_busno, devio_idx);
+ xbridge_set_devio(xb, devio_idx, devio |
(base >> BRIDGE_DEVICE_BASE_SHIFT));
*iostart = base;
*ioend = base + BRIDGE_DEVIO_SIZE(devio_idx) - 1;
- } else if (sc->sc_ioex != NULL) {
+ } else if (xb->xb_ioex != NULL) {
/*
* We know that the direct I/O resource range fits
* within the 32 bit address space, so our allocation,
@@ -2896,7 +3036,7 @@ xbridge_ppb_setup(void *cookie, pcitag_t tag, bus_addr_t *iostart,
if (exsize < 1UL << 12)
exsize = 1UL << 12;
for (tries = 0; tries < 5; tries++) {
- if (extent_alloc(sc->sc_ioex, exsize,
+ if (extent_alloc(xb->xb_ioex, exsize,
1UL << 12, 0, 0, EX_NOWAIT | EX_MALLOCOK,
&exstart) == 0) {
*iostart = exstart;
@@ -2978,7 +3118,7 @@ xbridge_rbus_parent_io(struct pci_attach_args *pa)
void *
xbridge_rbus_parent_mem(struct pci_attach_args *pa)
{
- struct xbridge_softc *sc = pa->pa_pc->pc_conf_v;
+ struct xbridge_bus *xb = pa->pa_pc->pc_conf_v;
struct extent *ex = pa->pa_memex;
bus_addr_t start;
rbus_tag_t rb = NULL;
@@ -2989,7 +3129,7 @@ xbridge_rbus_parent_mem(struct pci_attach_args *pa)
* devio range (for md_space_unmap to work correctly).
*/
if (ex != NULL) {
- start = (sc->sc_devio_skew + 1) << 24;
+ start = (xb->xb_devio_skew + 1) << 24;
if (start < ex->ex_start)
start = ex->ex_start;
@@ -3015,7 +3155,7 @@ xbridge_rbus_parent_mem(struct pci_attach_args *pa)
#endif /* NCARDBUS > 0 */
int
-xbridge_allocate_devio(struct xbridge_softc *sc, int dev, int wantlarge)
+xbridge_allocate_devio(struct xbridge_bus *xb, int dev, int wantlarge)
{
pcireg_t id;
@@ -3024,7 +3164,7 @@ xbridge_allocate_devio(struct xbridge_softc *sc, int dev, int wantlarge)
* use it.
*/
- if (sc->sc_devices[dev].devio == 0) {
+ if (xb->xb_devices[dev].devio == 0) {
if (BRIDGE_DEVIO_SIZE(dev) >=
wantlarge ? BRIDGE_DEVIO_LARGE : BRIDGE_DEVIO_SHORT)
return dev;
@@ -3035,11 +3175,11 @@ xbridge_allocate_devio(struct xbridge_softc *sc, int dev, int wantlarge)
* request.
*/
- for (dev = 0; dev < BRIDGE_NSLOTS; dev++) {
- if (sc->sc_devices[dev].devio != 0)
+ for (dev = 0; dev < xb->xb_nslots; dev++) {
+ if (xb->xb_devices[dev].devio != 0)
continue; /* devio in use */
- id = sc->sc_devices[dev].id;
+ id = xb->xb_devices[dev].id;
if (PCI_VENDOR(id) != PCI_VENDOR_INVALID && PCI_VENDOR(id) != 0)
continue; /* devio to be used soon */
@@ -3052,11 +3192,11 @@ xbridge_allocate_devio(struct xbridge_softc *sc, int dev, int wantlarge)
}
void
-xbridge_set_devio(struct xbridge_softc *sc, int dev, uint32_t devio)
+xbridge_set_devio(struct xbridge_bus *xb, int dev, uint32_t devio)
{
- bus_space_write_4(sc->sc_iot, sc->sc_regh, BRIDGE_DEVICE(dev), devio);
- (void)bus_space_read_4(sc->sc_iot, sc->sc_regh, WIDGET_TFLUSH);
- sc->sc_devices[dev].devio = devio;
+ xbridge_write_reg(xb, BRIDGE_DEVICE(dev), devio);
+ (void)xbridge_read_reg(xb, WIDGET_TFLUSH);
+ xb->xb_devices[dev].devio = devio;
#ifdef DEBUG
printf("device %d: new devio %08x\n", dev, devio);
#endif