From owner-p4-projects@FreeBSD.ORG Mon May 14 00:02:41 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id AC18616A406; Mon, 14 May 2007 00:02:40 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 7D47616A400 for ; Mon, 14 May 2007 00:02:40 +0000 (UTC) (envelope-from bms@incunabulum.net) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 51D6D13C43E for ; Mon, 14 May 2007 00:02:40 +0000 (UTC) (envelope-from bms@incunabulum.net) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l4E02e6H006552 for ; Mon, 14 May 2007 00:02:40 GMT (envelope-from bms@incunabulum.net) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l4E02eoZ006549 for perforce@freebsd.org; Mon, 14 May 2007 00:02:40 GMT (envelope-from bms@incunabulum.net) Date: Mon, 14 May 2007 00:02:40 GMT Message-Id: <200705140002.l4E02eoZ006549@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bms@incunabulum.net using -f From: Bruce M Simpson To: Perforce Change Reviews Cc: Subject: PERFORCE change 119807 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 May 2007 00:02:41 -0000 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 #include #include +#include #include #include @@ -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),