Changing how PCI-PCI bridges do resource allocation
John Baldwin
jhb at freebsd.org
Wed Apr 27 15:01:05 UTC 2011
On Tuesday, April 26, 2011 5:54:34 pm Alexander Motin wrote:
> John Baldwin wrote:
> > On Tuesday, April 26, 2011 10:45:33 am Alexander Motin wrote:
> >> John Baldwin wrote:
> >>> On Tuesday, April 26, 2011 2:53:24 am Alexander Motin wrote:
> >>>> On 26.04.2011 00:21, John Baldwin wrote:
> >>>>> On Monday, April 25, 2011 3:09:47 pm John Baldwin wrote:
> >>>>>> On Wednesday, April 20, 2011 4:38:30 am Alexander Motin wrote:
> >>>>>>> On 19.04.2011 21:50, John Baldwin wrote:
> >>>>>>>> I've already had at least one testing report that this fixes the issues with
> >>>>>>>> some machines' BIOS clearing the I/O windows on some PCI-PCI bridges when ACPI
> >>>>>>>> is enabled as this code re-discovers the original windows and programs them
> >>>>>>>> correctly. More testing would be good however.
> >>>>>>> I would like this helped my Acer TM6292 which also has alike problems
> >>>>>>> with missing PCIe bridge resources, but unluckily it doesn't.
> >>>>>>>
> >>>>>>> Here is verbose dmesg when my system uses this dirty hack:
> >>>>>>> http://people.freebsd.org/~mav/tm6292_pcie.patch
> >>>>>>> to restore bridges resources to the pre-ACPI state:
> >>>>>>> http://people.freebsd.org/~mav/dmesg.boot.hacks
> >>>>>>>
> >>>>>>> Here is respective `pciconf -lvcb` output:
> >>>>>>> http://people.freebsd.org/~mav/pciconf.hacks
> >>>>>>>
> >>>>>>> Here is dmesg with patches, but without NEW_PCIB:
> >>>>>>> http://people.freebsd.org/~mav/dmesg.boot.olbpcib
> >>>>>>>
> >>>>>>> Here is dmesg with patches with NEW_PCIB:
> >>>>>>> http://people.freebsd.org/~mav/dmesg.boot.newpcib
> >>>>>> Ah, your problem is we pick bad ranges when we alloc fresh resources for your
> >>>>>> bridges. I am working on making that better for ACPI, but for now you can try
> >>>>>> setting hw.acpi.host_mem_start to a value like '0xf0000000' in loader.conf.
> >>>>>>
> >>>>>> Although, it looks like it is not being honored currently. Try adding a printf
> >>>>>> in acpi_pcib_alloc_resource() in sys/dev/acpica/acpi_pcib_acpi.c to log the
> >>>>>> type, start, and end of each resource range.
> >>>>> Actually, try this patch. Then I think you can use the host_mem_start tunable:
> >>>> I've tried it. With this patch host_mem_start tunable seems like makes
> >>>> effect. Numbers look closer, but bge0 and iwn0 beyond the bridges are
> >>>> still not working.
> >>> Hmmm, I think I need to clear the completely bogus windows when we fail to
> >>> allocate the initial window. Try this (relative to the previous patches):
> >> Dmesg changed a bit, but still no luck:
> >> http://people.freebsd.org/~mav/newpcib/dmesg.next
> >
> > Oh, I'm dumb. 'w->base' should be set to 'max_address' and 'w->limit' should
> > be set to 0 to turn off the bogus windows like this:
>
> No luck:
> http://people.freebsd.org/~mav/newpcib/dmesg.next2
Ahh, I know what's wrong. I need to force MEMEN and/or IOEN in the bridge's
command register when enabling a window. Here is an updated patch relative
to pcib_window.patch (so it includes the previous patch to disable bogus
windows):
--- //depot/projects/pci/sys/dev/pci/pci_pci.c 2011-04-19 17:42:14.000000000 0000
+++ /home/jhb/work/p4/pci/sys/dev/pci/pci_pci.c 2011-04-19 17:42:14.000000000 0000
@@ -60,6 +60,7 @@
static int pcib_resume(device_t dev);
static int pcib_power_for_sleep(device_t pcib, device_t dev,
int *pstate);
+static void pcib_write_windows(struct pcib_softc *sc, int mask);
static device_method_t pcib_methods[] = {
/* Device interface */
@@ -146,7 +147,20 @@
return (pw->valid && pw->base < pw->limit);
}
+/*
+ * XXX: If RF_ACTIVE did not also imply allocate a bus space tag and
+ * handle for the resource, we could pass RF_ACTIVE up to the PCI bus
+ * when allocating the resource windows and rely on the PCI bus driver
+ * to do this for us.
+ */
static void
+pcib_activate_window(struct pcib_softc *sc, int type)
+{
+
+ PCI_ENABLE_IO(device_get_parent(sc->dev), dev, type);
+}
+
+static void
pcib_alloc_window(struct pcib_softc *sc, struct pcib_window *w, int type,
int flags, pci_addr_t max_address)
{
@@ -181,8 +195,12 @@
device_printf(sc->dev,
"failed to allocate initial %s window: %#jx-%#jx\n",
w->name, (uintmax_t)w->base, (uintmax_t)w->limit);
+ w->base = max_address;
+ w->limit = 0;
+ pcib_write_windows(sc, w->mask);
return;
}
+ pcib_activate_window(sc, type);
error = rman_manage_region(&w->rman, rman_get_start(w->res),
rman_get_end(w->res));
@@ -859,7 +877,7 @@
count = roundup2(count, 1ul << w->step);
rid = w->reg;
w->res = bus_alloc_resource(sc->dev, type, &rid, start, end,
- count, flags);
+ count, flags & ~RF_ACTIVE);
if (w->res == NULL) {
if (bootverbose)
device_printf(sc->dev,
@@ -883,6 +901,7 @@
w->res = NULL;
return (error);
}
+ pcib_activate_window(sc, type);
goto updatewin;
}
>
>
> --
> Alexander Motin
>
--
John Baldwin
More information about the freebsd-arch
mailing list