Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Nov 2008 07:45:40 GMT
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 152856 for review
Message-ID:  <200811120745.mAC7jeGX058026@repoman.freebsd.org>

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

Change 152856 by gonzo@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;
 



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