Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 May 2007 00:02:40 GMT
From:      Bruce M Simpson <bms@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 119807 for review
Message-ID:  <200705140002.l4E02eoZ006549@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=119807

Change 119807 by bms@bms_anglepoise on 2007/05/14 00:02:36

	bringin config tag stuff from CuWiN/NetBSD fork courtesy of dyoung;
	note that pci configuration enumeration still doesn't work right.
	the child pcib wasn't getting its resources activated and thus
	mapped into KSEG1; fixed.
	however, the configuration space still looks odd. It looks like
	the PCI configuration space reads needs to be byte-swapped; the
	MIPS is running in little endian mode, but the data appears to
	be big endian. must come back to this. in the meantime, it looks
	like it's starting to pick things up.

Affected files ...

.. //depot/projects/mips2/src/sys/dev/siba/siba_pcib.c#3 edit

Differences ...

==== //depot/projects/mips2/src/sys/dev/siba/siba_pcib.c#3 (text+ko) ====

@@ -38,6 +38,7 @@
 #include <sys/module.h>
 #include <sys/rman.h>
 #include <sys/malloc.h>
+#include <sys/endian.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
@@ -63,30 +64,29 @@
 #define MIPS_MEM_RID 0x20
 #endif
 
-#define SIBA_PCI_SLOTMAX 16
+#define SBPCI_SLOTMAX 15
 
-#define siba_pcib_read_4(sc, reg)					\
+#define SBPCI_READ_4(sc, reg)					\
 	bus_space_write_4((sc)->sc_bt, (sc)->sc_bh, (reg))
 
-#define siba_pcib_write_4(sc, reg, val)					\
+#define SBPCI_WRITE_4(sc, reg, val)					\
 	bus_space_write_4((sc)->sc_bt, (sc)->sc_bh, (reg), (val))
 
-#define SIBA_PCIB_CFG 0x0c000000	/* bottom pci window (64MB) */
+/*
+ * PCI Configuration space window (64MB).
+ * contained in SBTOPCI1 window.
+ */
+#define SBPCI_CFGBASE			0x0C000000
+#define SBPCI_CFGSIZE			0x01000000
 
-#define SIBA_PCIB_SBTOPCI0		0x0100
-#define SIBA_PCIB_SBTOPCI1		0x0104
-#define SIBA_PCIB_SBTOPCI2		0x0108
+#define SBPCI_SBTOPCI0 0x100
+#define SBPCI_SBTOPCI1 0x104
+#define SBPCI_SBTOPCI2 0x108
 
-#define SIBA_PCIB_SBTOPCICFG0		0x00000002
-#define SIBA_PCIB_SBTOPCICFG1		0x00000003
-#define SIBA_PCIB_SBTOPCICFG0_MASK	0xfc000000
-#define SIBA_PCIB_SBTOPCICFG1_MASK	0xfc000000
-#define SIBA_PCIB_SBTOPCICFG2_MASK	0xc0000000
-
 /*
+ * TODO: implement type 1 config space access (ie beyond bus 0)
+ * we may need to tweak the windows to do this
  * TODO: interrupt routing.
- * TODO: implement configuration space access.
- * TODO: map pci i/o windows.
  * TODO: fully implement bus allocation.
  * TODO: implement resource managers.
  * TODO: code cleanup.
@@ -100,8 +100,6 @@
 static int	siba_pcib_attach(device_t);
 static int	siba_pcib_deactivate_resource(device_t, device_t, int,
 		    int, struct resource *);
-static bus_addr_t
-		siba_pcib_map_csr(device_t, u_int, u_int, u_int, u_int);
 static int	siba_pcib_maxslots(device_t);
 static int	siba_pcib_probe(device_t);
 static u_int32_t
@@ -134,6 +132,8 @@
 	return (ENXIO);
 }
 
+//extern int rman_debug;
+
 static int
 siba_pcib_attach(device_t dev)
 {
@@ -144,7 +144,8 @@
 	 * Allocate the resources which the parent bus has already
 	 * determined for us.
 	 */
-	rid = MIPS_MEM_RID;
+	rid = MIPS_MEM_RID;	/* XXX */
+	//rman_debug = 1;
 	sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
 	    RF_ACTIVE);
 	if (sc->sc_mem == NULL) {
@@ -155,6 +156,43 @@
 	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%08x vaddr %p\n",
+	    sc->sc_bh, rman_get_virtual(sc->sc_mem));
+
+	SBPCI_WRITE_4(sc, 0x0000, 0x05);
+	SBPCI_WRITE_4(sc, 0x0000, 0x0D);
+	DELAY(150);
+	SBPCI_WRITE_4(sc, 0x0000, 0x0F);
+	SBPCI_WRITE_4(sc, 0x0010, 0x01);
+	DELAY(1);
+
+	bus_space_handle_t sc_cfg_hand;
+	int error;
+
+	/*
+	 * XXX this doesn't actually do anything on mips; however... should
+	 * we not be mapping to KSEG1? we need to wire down the range.
+	 */
+	error = bus_space_map(sc->sc_bt, SBPCI_CFGBASE, SBPCI_CFGSIZE,
+	    0, &sc_cfg_hand);
+	if (error) {
+		device_printf(dev, "cannot map PCI configuration space\n");
+		return (ENXIO);
+	}
+	device_printf(dev, "mapped pci config space at 0x%08x\n", sc_cfg_hand);
+
+	/*
+	 * Setup configuration, io, and dma space windows.
+	 * 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 */
+	DELAY(500);
+
+	/* XXX resource managers */
+
 	device_add_child(dev, "pci", -1);
 	return (bus_generic_attach(dev));
 }
@@ -215,7 +253,7 @@
 {
 #if 1
 
-	device_printf(bus, "%s: not yet implemented\n", __func__);
+	//device_printf(bus, "%s: not yet implemented\n", __func__);
 	return (NULL);
 #else
 	bus_space_tag_t tag;
@@ -294,38 +332,52 @@
 siba_pcib_maxslots(device_t dev)
 {
 
-	//return (SIBA_PCI_SLOTMAX);
-	// For now, only probe the first function including the bridge.
-	return (1);
+	return (SBPCI_SLOTMAX);
 }
 
+/*
+ * 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)
+siba_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func,
+    u_int reg, int bytes)
 {
-	bus_addr_t csrbase;
+	struct siba_pcib_softc *sc = device_get_softc(dev);
+	bus_addr_t cfgaddr;
+	uint32_t cfgtag;
 	uint32_t val;
 
+	/* 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
+	}
+
+	device_printf(dev, "requested %d bytes from b/s/f %d/%d/%d reg %d\n",
+	    bytes, bus, slot, func, reg);
+
 	/*
-	 * XXX: TODO de-mipsify; we should map windows for the space
-	 * the bridge uses and do bus_space_read in those as nexus will
-	 * translate accesses into KSEG1 for us.
+	 * The configuration tag on the broadcom is weird.
 	 */
-	csrbase = siba_pcib_map_csr(dev, bus, slot, func, reg);
-	val = *(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(csrbase);
+	SBPCI_WRITE_4(sc, SBPCI_SBTOPCI1, 2);	/* XXX again??? */
+	cfgtag = ((1 << slot) << 16) | (func << 8);
+	cfgaddr = SBPCI_CFGBASE | cfgtag | (reg & ~3);
+
+	/* 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 */
+
+	// this is just...odd. it doesn't look right.
+
+	//val = bswap32(val);	/* XXX ? */
 
-	switch (bytes) {
-	case 1:
-		val &= 0xff;
-		break;
-	case 2:
-		val &= 0xffff;
-		break;
-	case 4:
-		break;
-	default:
-		return (ENXIO);
-	}
+	/* swizzle and return what was asked for */
+	val &= 0xffffffff >> ((4 - bytes) * 8);
 
 	return (val);
 }
@@ -336,54 +388,17 @@
 {
 
 	/* write to pci configuration space */
-	device_printf(dev, "%s: not yet implemented\n", __func__);
+	//device_printf(dev, "%s: not yet implemented\n", __func__);
 }
 
 static int
 siba_pcib_route_interrupt(device_t bridge, device_t device, int pin)
 {
 
-	device_printf(bridge, "%s: not yet implemented\n", __func__);
+	//device_printf(bridge, "%s: not yet implemented\n", __func__);
 	return (-1);
 }
 
-/*
- * Map CSR registers of a device on the PCI bus into an available window.
- * XXX This should really use bus_space_map.
- * XXX I need to map these windows before I can use them.
- */
-static bus_addr_t
-siba_pcib_map_csr(device_t dev, u_int bus, u_int slot, u_int func, u_int reg)
-{
-	struct siba_pcib_softc *sc = device_get_softc(dev);
-	bus_addr_t csrbase, csrmap;
-
-	printf("%s: entry", __func__);
-	(void)sc;
-
-	if (bus == 0) {
-		csrbase = SIBA_PCIB_SBTOPCICFG0 |
-		    ((1 << (slot + 16)) & SIBA_PCIB_SBTOPCICFG1_MASK);
-		// XXX exception here
-		//siba_pcib_write_4(sc, SIBA_PCIB_SBTOPCI0, csrbase);
-
-		csrmap = SIBA_PCIB_CFG |
-		    ((1 << (slot + 16)) & ~SIBA_PCIB_SBTOPCICFG1_MASK) |
-		    (func << 8) | (reg & ~3);
-	} else {
-		// XXX exception here
-		//siba_pcib_write_4(sc, SIBA_PCIB_SBTOPCI0,
-		//    SIBA_PCIB_SBTOPCICFG1);
-		csrmap = SIBA_PCIB_CFG | (bus << 16) | (slot << 11) |
-		    (func << 8) | (reg & ~3);
-	}
-
-	printf("%s: %d/%d/%d reg %d mapped at %08x\n", __func__, bus, slot, func, reg,
-	    csrmap);
-
-	return (csrmap);
-}
-
 static device_method_t siba_pcib_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_attach,	siba_pcib_attach),



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200705140002.l4E02eoZ006549>