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>