On Saturday, May 28, 2011 9:45:48 pm deeptec...@gmail.com wrote: > On Thu, May 26, 2011 at 3:40 PM, John Baldwin <j...@freebsd.org> wrote: > > Ohh, you have two devices behind this bridge that have prefetch ranges. > > > > As a hack, can you try this: > > > > Index: pci_pci.c > > =================================================================== > > --- pci_pci.c (revision 222285) > > +++ pci_pci.c (working copy) > > @@ -162,8 +162,13 @@ pcib_write_windows(struct pcib_softc *sc, int mask > > { > > device_t dev; > > uint32_t val; > > + uint16_t cmd; > > > > dev = sc->dev; > > + cmd = pci_read_config(dev, PCIR_COMMAND, 2); > > + if (cmd & (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN)) > > + pci_write_config(dev, PCIR_COMMAND, > > + cmd & ~(PCIM_CMD_PORTEN | PCIM_CMD_MEMEN), 2); > > if (sc->io.valid && mask & WIN_IO) { > > val = pci_read_config(dev, PCIR_IOBASEL_1, 1); > > if ((val & PCIM_BRIO_MASK) == PCIM_BRIO_32) { > > @@ -192,6 +197,8 @@ pcib_write_windows(struct pcib_softc *sc, int mask > > pci_write_config(dev, PCIR_PMBASEL_1, sc->pmem.base >> 16, > > 2); > > pci_write_config(dev, PCIR_PMLIMITL_1, sc->pmem.limit >> 16, > > 2); > > } > > + if (cmd & (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN)) > > + pci_write_config(dev, PCIR_COMMAND, cmd, 2); > > } > > > > static void > > @@ -337,6 +344,9 @@ pcib_probe_windows(struct pcib_softc *sc) > > pci_read_config(dev, PCIR_PMLIMITL_1, 2)); > > max = 0xffffffff; > > } > > + /* XXX: Testing hack */ > > + if (device_get_unit(sc->sc_dev) == 1) > > i'm assuming that "sc->sc_dev" should be "dev" (this fixes a compilation > error). > > > + sc->pmem.limit = 0xefffffff; > > pcib_alloc_window(sc, &sc->pmem, SYS_RES_MEMORY, > > RF_PREFETCHABLE, max); > > } > > that seems to work! > > btw, is my machine a test-pig for an upcoming change to the PCI bus driver?
Can you try out this change. It is a possible "real" solution (or at least a stopgap until we start using multipass to untangle the resource mess a bit further): Index: dev/acpica/acpi_pcib_pci.c =================================================================== --- dev/acpica/acpi_pcib_pci.c (revision 222747) +++ dev/acpica/acpi_pcib_pci.c (working copy) @@ -114,13 +114,16 @@ acpi_pcib_pci_attach(device_t dev) { struct acpi_pcib_softc *sc; + int error; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); pcib_attach_common(dev); sc = device_get_softc(dev); sc->ap_handle = acpi_get_handle(dev); - return (acpi_pcib_attach(dev, &sc->ap_prt, sc->ap_pcibsc.secbus)); + error = acpi_pcib_attach(dev, &sc->ap_prt, sc->ap_pcibsc.secbus); + pcib_attach_final(dev); + return (error); } static int Index: dev/pci/pci_pci.c =================================================================== --- dev/pci/pci_pci.c (revision 222747) +++ dev/pci/pci_pci.c (working copy) @@ -162,8 +162,13 @@ { device_t dev; uint32_t val; + uint16_t cmd; dev = sc->dev; + cmd = pci_read_config(dev, PCIR_COMMAND, 2); + if (cmd & (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN)) + pci_write_config(dev, PCIR_COMMAND, + cmd & ~(PCIM_CMD_PORTEN | PCIM_CMD_MEMEN), 2); if (sc->io.valid && mask & WIN_IO) { val = pci_read_config(dev, PCIR_IOBASEL_1, 1); if ((val & PCIM_BRIO_MASK) == PCIM_BRIO_32) { @@ -192,6 +197,8 @@ pci_write_config(dev, PCIR_PMBASEL_1, sc->pmem.base >> 16, 2); pci_write_config(dev, PCIR_PMLIMITL_1, sc->pmem.limit >> 16, 2); } + if (cmd & (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN)) + pci_write_config(dev, PCIR_COMMAND, cmd, 2); } static void @@ -231,7 +238,7 @@ w->name, (uintmax_t)w->base, (uintmax_t)w->limit); w->base = max_address; w->limit = 0; - pcib_write_windows(sc, w->mask); + sc->win_deferred |= w->mask; return; } pcib_activate_window(sc, type); @@ -690,22 +697,33 @@ */ } +void +pcib_attach_final(device_t dev) +{ +#ifdef NEW_PCIB + struct pcib_softc *sc; + + sc = device_get_softc(dev); + if (sc->win_deferred) { + pcib_write_windows(sc, sc->win_deferred); + sc->win_deferred = 0; + } +#endif +} + int pcib_attach(device_t dev) { struct pcib_softc *sc; - device_t child; + int error; pcib_attach_common(dev); sc = device_get_softc(dev); - if (sc->secbus != 0) { - child = device_add_child(dev, "pci", sc->secbus); - if (child != NULL) - return(bus_generic_attach(dev)); - } - - /* no secondary bus; we should have fixed this */ - return(0); + if (sc->secbus != 0) + device_add_child(dev, "pci", sc->secbus); + error = bus_generic_attach(dev); + pcib_attach_final(dev); + return (error); } int @@ -1020,7 +1038,8 @@ ("start address is not aligned")); KASSERT((w->limit & ((1ul << w->step) - 1)) == (1ul << w->step) - 1, ("end address is not aligned")); - pcib_write_windows(sc, w->mask); + if (!(sc->win_deferred & w->mask)) + pcib_write_windows(sc, w->mask); return (0); } Index: dev/pci/pcib_private.h =================================================================== --- dev/pci/pcib_private.h (revision 222747) +++ dev/pci/pcib_private.h (working copy) @@ -75,6 +75,7 @@ struct pcib_window io; /* I/O port window */ struct pcib_window mem; /* memory window */ struct pcib_window pmem; /* prefetchable memory window */ + u_int win_deferred; #else pci_addr_t pmembase; /* base address of prefetchable memory */ pci_addr_t pmemlimit; /* topmost address of prefetchable memory */ @@ -94,6 +95,7 @@ int slot, int func, uint8_t *busnum); int pcib_attach(device_t dev); void pcib_attach_common(device_t dev); +void pcib_attach_final(device_t dev); int pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result); int pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value); struct resource *pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, Index: powerpc/ofw/ofw_pcib_pci.c =================================================================== --- powerpc/ofw/ofw_pcib_pci.c (revision 222747) +++ powerpc/ofw/ofw_pcib_pci.c (working copy) @@ -126,6 +126,7 @@ ofw_pcib_pci_attach(device_t dev) { struct ofw_pcib_softc *sc; + int error; sc = device_get_softc(dev); sc->ops_pcib_sc.dev = dev; @@ -138,7 +139,9 @@ device_add_child(dev, "pci", -1); - return (bus_generic_attach(dev)); + error = bus_generic_attach(dev); + pcib_attach_final(dev); + return (error); } static phandle_t Index: sparc64/pci/ofw_pcib.c =================================================================== --- sparc64/pci/ofw_pcib.c (revision 222747) +++ sparc64/pci/ofw_pcib.c (working copy) @@ -116,6 +116,7 @@ ofw_pcib_attach(device_t dev) { struct ofw_pcib_gen_softc *sc; + int error; sc = device_get_softc(dev); @@ -135,5 +136,7 @@ ofw_pcib_gen_setup(dev); pcib_attach_common(dev); device_add_child(dev, "pci", -1); - return (bus_generic_attach(dev)); + error = bus_generic_attach(dev); + pcib_attach_final(dev); + return (error); } -- John Baldwin _______________________________________________ freebsd-current@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-current To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"