PERFORCE change 152856 for review
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Tue Nov 11 23:45:41 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=152856
Change 152856 by gonzo at gonzo_jeeves on 2008/11/12 07:45:25
- Use bus_read_X/bus_write_X to instead of bus_space_XXX
- Replace immediate values with defines in initialization code
- Implement PCI config registers write function. Code is still
MIPS-only.
Affected files ...
.. //depot/projects/mips2/src/sys/dev/siba/siba_pcib.c#6 edit
.. //depot/projects/mips2/src/sys/dev/siba/siba_pcibvar.h#4 edit
Differences ...
==== //depot/projects/mips2/src/sys/dev/siba/siba_pcib.c#6 (text+ko) ====
@@ -66,12 +66,6 @@
#define SBPCI_SLOTMAX 15
-#define SBPCI_READ_4(sc, reg) \
- bus_space_write_4((sc)->sc_bt, (sc)->sc_bh, (reg))
-
-#define SBPCI_WRITE_4(sc, reg, val) \
- bus_space_write_4((sc)->sc_bt, (sc)->sc_bh, (reg), (val))
-
/*
* PCI Configuration space window (64MB).
* contained in SBTOPCI1 window.
@@ -102,9 +96,9 @@
int, struct resource *);
static int siba_pcib_maxslots(device_t);
static int siba_pcib_probe(device_t);
-static u_int32_t
- siba_pcib_read_config(device_t, u_int, u_int, u_int, u_int,
- int);
+static uint32_t
+ siba_pcib_read_config(device_t, unsigned int, unsigned int,
+ unsigned int, unsigned int, int);
static int siba_pcib_read_ivar(device_t, device_t, int, uintptr_t *);
static int siba_pcib_release_resource(device_t, device_t, int, int,
struct resource *);
@@ -113,8 +107,8 @@
int, driver_filter_t *, driver_intr_t *, void *, void **);
static int siba_pcib_teardown_intr(device_t, device_t, struct resource *,
void *);
-static void siba_pcib_write_config(device_t, u_int, u_int, u_int, u_int,
- u_int32_t, int);
+static void siba_pcib_write_config(device_t, unsigned int, unsigned int,
+ unsigned int, unsigned int, uint32_t, int);
static int siba_pcib_write_ivar(device_t, device_t, int, uintptr_t);
static int
@@ -139,6 +133,9 @@
{
struct siba_pcib_softc *sc = device_get_softc(dev);
int rid;
+ uint32_t ctl;
+ uint16_t vid, svid;
+
/*
* Allocate the resources which the parent bus has already
@@ -153,19 +150,37 @@
return (ENXIO);
}
- sc->sc_bt = rman_get_bustag(sc->sc_mem);
- sc->sc_bh = rman_get_bushandle(sc->sc_mem);
+ device_printf(dev, "bridge registers addr 0x%08lx vaddr %p\n",
+ rman_get_start(sc->sc_mem), rman_get_virtual(sc->sc_mem));
- device_printf(dev, "bridge registers addr 0x%08x vaddr %p\n",
- (uint32_t)sc->sc_bh, rman_get_virtual(sc->sc_mem));
+ /* Enable putputs for PCI_RESET and clock */
+ ctl = SIBA_PCI_CTL_RST_EN | SIBA_PCI_CTL_CLK_EN;
+ SBPCI_WRITE_4(sc, SIBA_PCI_CTL, ctl);
- SBPCI_WRITE_4(sc, 0x0000, 0x05);
- SBPCI_WRITE_4(sc, 0x0000, 0x0D);
+ /* Clock on */
+ ctl |= SIBA_PCI_CTL_CLK;
+ SBPCI_WRITE_4(sc, SIBA_PCI_CTL, ctl);
DELAY(150);
- SBPCI_WRITE_4(sc, 0x0000, 0x0F);
- SBPCI_WRITE_4(sc, 0x0010, 0x01);
- DELAY(1);
+
+ ctl |= SIBA_PCI_CTL_RST;
+ SBPCI_WRITE_4(sc, SIBA_PCI_CTL, ctl);
+
+ /* Use internal arbiter */
+ SBPCI_WRITE_4(sc, SIBA_PCI_ARBITER_CTL, SIBA_PCI_ARBITER_INT);
+ DELAY(10);
+
+ SBPCI_WRITE_4(sc, SIBA_PCI_TRANS0, SIBA_PCI_TRANS_IO);
+ SBPCI_WRITE_4(sc, SIBA_PCI_TRANS1, SIBA_PCI_TRANS_CFG0);
+ SBPCI_WRITE_4(sc, SIBA_PCI_TRANS2, SIBA_PCI_TRANS_MEM);
+
+
+ vid = siba_pcib_read_config(dev, 0, 0, 0, 0, 2);
+ svid = siba_pcib_read_config(dev, 0, 0, 0, 2, 2);
+ printf("bridge vid=%08x, svid=%08x\n", vid, svid);
+
+
+#if 0
bus_space_handle_t sc_cfg_hand;
int error;
@@ -187,12 +202,13 @@
* XXX we need to be able to do type 1 too.
* we probably don't need to be able to do i/o cycles.
*/
- SBPCI_WRITE_4(sc, SBPCI_SBTOPCI0, 1); /* I/O read/write window */
- SBPCI_WRITE_4(sc, SBPCI_SBTOPCI1, 2); /* type 0 configuration only */
- SBPCI_WRITE_4(sc, SBPCI_SBTOPCI2, 1 << 30); /* memory only */
+ SBPCI_WRITE_4(sc->sc_mem, SBPCI_SBTOPCI0, 1); /* I/O read/write window */
+ SBPCI_WRITE_4(sc->sc_mem, SBPCI_SBTOPCI1, 2); /* type 0 configuration only */
+ SBPCI_WRITE_4(sc->sc_mem, SBPCI_SBTOPCI2, 1 << 30); /* memory only */
DELAY(500);
/* XXX resource managers */
+#endif
device_add_child(dev, "pci", -1);
return (bus_generic_attach(dev));
@@ -207,6 +223,9 @@
sc = device_get_softc(dev);
switch (which) {
+ case PCIB_IVAR_DOMAIN:
+ *result = 0;
+ return (0);
case PCIB_IVAR_BUS:
*result = sc->sc_bus;
return (0);
@@ -250,7 +269,7 @@
static struct resource *
siba_pcib_alloc_resource(device_t bus, device_t child, int type, int *rid,
- u_long start, u_long end, u_long count, u_int flags)
+ u_long start, u_long end, u_long count, unsigned int flags)
{
#if 1
@@ -336,58 +355,131 @@
return (SBPCI_SLOTMAX);
}
+static void
+siba_pcib_conf_setup(struct siba_pcib_softc *sc, int bus, int slot, int func,
+ int reg, bus_addr_t *addr)
+{
+ uint32_t cfgtag;
+
+ /*
+ * The configuration tag on the broadcom is weird.
+ */
+ if (bus == 0) {
+ SBPCI_WRITE_4(sc, SIBA_PCI_TRANS1, SIBA_PCI_TRANS_CFG0);
+ cfgtag = ((1 << slot) << 16) | (func << 8);
+ *addr = SBPCI_CFGBASE | cfgtag | (reg & ~3);
+ } else
+ {
+ SBPCI_WRITE_4(sc, SIBA_PCI_TRANS1, SIBA_PCI_TRANS_CFG1);
+ cfgtag = ((bus << 16) | (slot << 11) | (func << 8));
+ *addr = SBPCI_CFGBASE | cfgtag | (reg & ~3);
+ }
+}
+
+
+
/*
* This needs hacking and fixery. It is currently broke and hangs.
* Debugging it will be tricky; there seems to be no way to enable
* a target abort which would cause a nice target abort.
* Look at linux again?
*/
-static u_int32_t
-siba_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func,
- u_int reg, int bytes)
+static uint32_t
+siba_pcib_read_config(device_t dev, unsigned int bus, unsigned int slot, unsigned int func,
+ unsigned int reg, int bytes)
{
struct siba_pcib_softc *sc = device_get_softc(dev);
bus_addr_t cfgaddr;
- uint32_t cfgtag;
uint32_t val;
+ uint32_t *kseg1addr;
- /* XXX anything higher than slot 2 currently seems to hang the bus.
- * not sure why this is; look at linux again
- */
- if (bus != 0 || slot > 2) {
- printf("%s: bad b/s/f %d/%d/%d\n", __func__, bus, slot, func);
- return 0xffffffff; // XXX
- }
-
+#ifdef DEBUG_SIBA_PCI
device_printf(dev, "requested %d bytes from b/s/f %d/%d/%d reg %d\n",
bytes, bus, slot, func, reg);
+#endif
- /*
- * The configuration tag on the broadcom is weird.
- */
- SBPCI_WRITE_4(sc, SBPCI_SBTOPCI1, 2); /* XXX again??? */
- cfgtag = ((1 << slot) << 16) | (func << 8);
- cfgaddr = SBPCI_CFGBASE | cfgtag | (reg & ~3);
+ siba_pcib_conf_setup(sc, bus, slot, func, reg, &cfgaddr);
+ /* cfg space i/o is always 32 bits on this bridge */
+ kseg1addr = (uint32_t *)MIPS_PHYS_TO_KSEG1(cfgaddr);
- /* cfg space i/o is always 32 bits on this bridge */
- printf("reading 4 bytes from %08x\n", cfgaddr);
- val = *(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(cfgaddr); /* XXX MIPS */
+#ifdef DEBUG_SIBA_PCI
+ printf("reading 4 bytes from %p\n", kseg1addr);
+#endif
- val = bswap32(val); /* XXX seems to be needed for now */
+ if (badaddr((uint32_t *)kseg1addr, 4))
+ return 0xffffffff;
+ val = *(volatile uint32_t *)kseg1addr;
- /* swizzle and return what was asked for */
- val &= 0xffffffff >> ((4 - bytes) * 8);
+ val >>= (8 * (reg % 4));
- return (val);
+ switch(bytes)
+ {
+ case 1:
+ return (val & 0xff);
+ break;
+ case 2:
+ return (val & 0xffff);
+ break;
+ case 4:
+ return (val);
+ break;
+ default:
+ panic("%s: wrong bytes count", __func__);
+ break;
+ }
}
static void
-siba_pcib_write_config(device_t dev, u_int bus, u_int slot,
- u_int func, u_int reg, u_int32_t val, int bytes)
+siba_pcib_write_config(device_t dev, unsigned int bus, unsigned int slot,
+ unsigned int func, unsigned int reg, uint32_t val, int bytes)
{
+ struct siba_pcib_softc *sc = device_get_softc(dev);
+ bus_addr_t cfgaddr;
+ uint32_t data;
+ uint32_t *kseg1addr;
+ uint32_t shift, mask;
- /* write to pci configuration space */
- //device_printf(dev, "%s: not yet implemented\n", __func__);
+#ifdef DEBUG_SIBA_PCI
+ device_printf(dev, "writing %d bytes to b/s/f %d/%d/%d reg %d\n",
+ bytes, bus, slot, func, reg);
+#endif
+
+ siba_pcib_conf_setup(sc, bus, slot, func, reg, &cfgaddr);
+ /* cfg space i/o is always 32 bits on this bridge */
+ kseg1addr = (uint32_t *)MIPS_PHYS_TO_KSEG1(cfgaddr);
+
+#ifdef DEBUG_SIBA_PCI
+ printf("reading 4 bytes from %p\n", kseg1addr);
+#endif
+
+ if (badaddr((uint32_t *)kseg1addr, 4))
+ return;
+
+ data = *(volatile uint32_t *)kseg1addr;
+
+ shift = 8 * (reg & 3);
+ switch(bytes)
+ {
+ case 1:
+ mask = 0xff;
+ val = (data & ~ (mask << shift)) | (val << shift);
+ break;
+ case 2:
+ mask = 0xffff;
+ if(reg % 4 == 0)
+ val = (data & ~mask) | val;
+ else
+ val = (data & ~ (mask << shift)) |
+ (val << shift);
+ break;
+ case 4:
+ break;
+ default:
+ panic("%s: wrong bytes count", __func__);
+ break;
+ }
+
+ *(volatile uint32_t *)kseg1addr = val;
}
static int
==== //depot/projects/mips2/src/sys/dev/siba/siba_pcibvar.h#4 (text+ko) ====
@@ -29,15 +29,21 @@
#include <sys/rman.h>
+#define SBPCI_READ_4(sc, reg) \
+ bus_write_4((sc)->sc_mem, (reg))
+
+#define SBPCI_WRITE_4(sc, reg, val) \
+ bus_write_4((sc)->sc_mem, (reg), (val))
+
struct siba_pcib_softc {
device_t sc_dev; /* Device ID */
u_int sc_bus; /* PCI bus number */
struct resource *sc_mem; /* siba memory window */
struct resource *sc_csr; /* config space */
+#if 0
bus_space_tag_t sc_bt;
bus_space_handle_t sc_bh;
-#if 0
bus_addr_t sc_maddr;
bus_size_t sc_msize;
More information about the p4-projects
mailing list