Date: Thu, 28 Feb 2008 00:13:58 +0200 From: Andriy Gapon <avg@icyb.net.ua> To: John Baldwin <jhb@freebsd.org> Cc: freebsd-acpi@freebsd.org Subject: Re: acpi_throttle: quirk based on pci info Message-ID: <47C5E0A6.5030102@icyb.net.ua> In-Reply-To: <200802271126.30132.jhb@freebsd.org> References: <47B96989.6070008@icyb.net.ua> <47C32D3C.2020205@icyb.net.ua> <47C5173E.40207@icyb.net.ua> <200802271126.30132.jhb@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
on 27/02/2008 18:26 John Baldwin said the following: > On Wednesday 27 February 2008 02:54:38 am Andriy Gapon wrote: [snip] >> So what I am getting at - it is certainly not hard to make >> acpi_pcib_acpi (and consecutively pci) be attached earlier than >> acpi_cpu. All is needed is to add another special case in >> acpi_probe_order after the existing ones, I actually did it as an >> experiment: >> else if (acpi_MatchHid(handle, "PNP0A03")) >> *order = 4; >> This worked for me as expected and without any side effects. >> >> But I have a big concern about whether we have any devices/drivers that >> rely on a current typical order. That is, drivers that expect cpu >> device/bus to be already probed and attached at the time when >> probe/attach is called for something on pci bus. >> I guess one example here is famous ichss that adds a child to cpu bus in >> its pci probe routine, and calls device_probe_and_attach for it in the >> same place too. I guess that while BUS_ADD_CHILD should work at that >> place, device_probe_and_attach may not because cpu itself is not probed >> and attached yet. >> >> On the other hand, as I said in the beginning, I think that even now >> there are no strict guarantees about the order, it just happens to work. >> >> Anyway, I am not sure if the discussed change in ordering has any merit. >> It seems that whatever the order it would be convenient in some places >> and inconvenient in others, so some jumping through the hoops is inevitable. >> >> I wonder if it would be possible to create some mechanism for attaching >> "important" devices first and then the rest later. E.g. cpu and pcib+pci >> are attached first (in whatever order), then their children are attached >> later (in whatever order). What is important is that all those "late" >> children can expect both cpu and pci to be fully available. > > I actually have had patches for a while to make CPU devices attach in a > certain order with respect to Host-PCI bridges precisely to help address > this. What I did was to force CPUs to probe before PCI devices so then the > ichss drivers current method (adding devices to CPUs) always works as the > CPUs are around when ichss goes to attach devices to them. > > This is the patch I've had for a while. It also attaches Host-PCI bridges in > a more deterministic order: > > --- //depot/vendor/freebsd/src/sys/dev/acpica/acpi.c 2007/10/09 07:52:34 > +++ //depot/user/jhb/acpipci/dev/acpica/acpi.c 2008/01/22 23:22:19 > @@ -1533,18 +1534,32 @@ > static int > acpi_probe_order(ACPI_HANDLE handle, int *order) > { > + ACPI_OBJECT_TYPE type; > + u_int addr; > > /* > * 1. I/O port and memory system resource holders > * 2. Embedded controllers (to handle early accesses) > - * 3. PCI Link Devices > + * 3. CPUs > + * 4. PCI Link Devices > + * 11 - 266. Host-PCI bridges sorted by _ADR > */ > + AcpiGetType(handle, &type); > if (acpi_MatchHid(handle, "PNP0C01") || acpi_MatchHid(handle, "PNP0C02")) > *order = 1; > else if (acpi_MatchHid(handle, "PNP0C09")) > *order = 2; > + else if (type == ACPI_TYPE_PROCESSOR) > + *order = 3; > else if (acpi_MatchHid(handle, "PNP0C0F")) > - *order = 3; > + *order = 4; > + else if (acpi_MatchHid(handle, "PNP0A03")) { > + if (ACPI_SUCCESS(acpi_GetInteger(handle, "_ADR", &addr))) > + *order = 11 + ACPI_ADR_PCI_SLOT(addr) * (PCI_FUNCMAX + 1) + > + ACPI_ADR_PCI_FUNC(addr); > + else > + *order = 11; > + } > return (0); > } > > @@ -1591,14 +1606,16 @@ > break; > > /* > - * Create a placeholder device for this node. Sort the placeholder > - * so that the probe/attach passes will run breadth-first. Orders > - * less than ACPI_DEV_BASE_ORDER are reserved for special objects > - * (i.e., system resources). Larger values are used for all other > - * devices. > + * Create a placeholder device for this node. Sort the > + * placeholder so that the probe/attach passes will run > + * breadth-first. Orders less than ACPI_DEV_BASE_ORDER > + * are reserved for special objects (i.e., system > + * resources). Values between ACPI_DEV_BASE_ORDER and 300 > + * are reserved for Host-PCI bridges. Larger values are > + * used for all other devices. > */ > ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "scanning '%s'\n", handle_str)); > - order = (level + 1) * ACPI_DEV_BASE_ORDER; > + order = level * 10 + 300; > acpi_probe_order(handle, &order); > child = BUS_ADD_CHILD(bus, order, NULL, -1); > if (child == NULL) > > With this patch PCI drivers that want to work with CPU devices would use the > same approach as ichss. I'm not sure that is the best approach though. The > fact that smist0 wants to check if ichss0 is attached probably wouldn't work > as with this patch smist0 would attach first before ichss0 got a chance to > probe via PCI. > > We could flip this around to have PCI bridges first before CPUs. As you > suggest. However, that will break ichss in its current form as cpu0 won't > exist yet (the device wouldn't be probed, so it would be called cpu0 yet). > > This is begging for multi-pass. :( (But that's another topic). > > In practice, I think you could change ichss to not use a PCI probe, but to > just read config registers directly and hardcode the address of the ICH. You > could even walk PCI bus 0 looking for a PCI-ISA bridge instead of hardcoding > the address I think. Then ichss would just be a CPU device and not depend on > the PCI bus at all. I'm not sure if that is workable for the other case you > are worried about. > > BTW, once an order is decided upon of CPUs relative to Host-PCI bridges we can > fix that order for the non-ACPI case easily enough in legacy.c. > John, thank you for this detailed reply! I looked through the code and I think that ichss is the only device that explicitly requires cpu and pci buses to be "configured". acpi_throttle is another one that implicitly requires that. My personal preference is to probe/attach pci first and then go with cpu. This is mostly because pci can provide a lot of useful information and resources to various devices. On the other hand, cpu mostly exists so that others could attach to it (it does provide a little bit, but it's a very little bit). So, in my opinion, it is more likely that a child of cpu would need something from pci than vice versa. If we agree on this order and implement it, then I agree with you that it would be quite easy to modify ichss to be a "normal" child of cpu and use pci_find_device to find a proper pci device. And the rest of the code that uses pci_read_config, bus_set_resource and bus_alloc_resource_any would remain practically the same. I'd even say that this would be a trivial change. And I'd even say that this would be a change in right direction, because ichss would lose most of its 'specialness'. -- Andriy Gapon
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?47C5E0A6.5030102>