Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
ACPI itself won't enumerate the entire PCI bus usually. What it will do is locate PCI(-Express) root bridges for you via _HID or _CID values. From there your OS should basically run a PCI root bridge driver which enumerates the PCI Bus behind the Root bridge and indicate to the PCI Firmware what features it supports via the _OSC method if it exists. The specifics of which are covered in the PCI Firmware Specification v3.0.
So, what I need to do is to find PCI Root bridge and then scan it for the devices on the bus? Are there any methods in ACPICA to do this or it has nothing to do with ACPICA?
You can do it using AcpiGetDevices. Just have the walk function retrieve the device info via AcpiGetObjectInfo. Methods like _SEG or _BBN that are useful for enumerating a PCI root bridge can be executed and their values returned by calling AcpiEvaluateObject. If I remember correctly there might even be a flag in the ACPI_DEVICE_INFO structure that indicates a device is a PCI root bridge.
All external ACPI interfaces are available and the host OS can perform the following initialization steps:
Enumerate devices using the _HID method
Load, configure, and install device drivers
Device Drivers install handlers for other address spaces such as SMBus, EC, IPMI, and custom address spaces
The PCI driver enumerates PCI devices and loads PCIConfig handlers for PCI-to-PCI- bridge devices (which causes the associated child PCI bus_REG methods to run, etc.)
For these operation regions, the namespace is searched upwards from the region to find the corresponding PCI Root Bridge.
If a _HID or _CID method under a device object indicates the presence of a PCI Root Bridge (an ID value of PNP0A03 or PNP0A08 for PCI Express), perform PCI Configuration Space initialization on the bridge. Install the PCI address space handler on the bridge (and on all descendents) and run the _REG method for the device if it is present. Then execute the _ADR, _SEG, and _BBN methods (in the bridge scope) to obtain the PCI Device, Function, Segment, and Bus numbers. Finally, run the associated _REG method to indicate the availability of the region.
The initial PCI Device and Function values are obtained from the _ADR method.
The initial PCI Segment number is obtained from the _SEG method.
The initial PCI Bus number is obtained from the _BBN method.
The final PCI ID consisting of Device, Function, Segment, and Bus is obtained by calling the AcpiHwDerivePciId OSL interface. This function adjusts the Bus, Device, and Function numbers based upon the PCI device tree and the PCI configuration space registers. This allows for a dynamic value for the Bus number based upon the hardware configuration and initialization.
When accessing a PCI_Config operation region, all I/O from/to the PCI confituration space is performed via the OSL interfaces AcpiOsReadPciConfiguration and AcpiOsWritePciConfiguration.
The (internal) AcpiHwDerivePciId function derives a full PCI ID for a PCI device, consisting of a Segment number, a Bus number, and a Device number.
The PCI hardware dynamically configures PCI bus numbers depending on the bus topology discovered during system initialization. The AcpiHwDerivePciId function is invoked by the ACPICA subsystem during configuration of a PCI_Config Operation Region in order to (possibly) update the Bus number in the PciId with the actual Bus number as determined by the hardware and operating system configuration.
But it is unclear wether it is done by ACPICA or should be done by OS.
At least I decided that it is not a good idea to use ACPI to enumerate PCI-devices. It is possible to get a list of PCI-devices, along with ACPI names and IRQ number from ACPI, but it confers no advantage over manual probing, and also doesn't work on older systems that doesn't have proper ACPI-support. Instead, I only use ACPI (if present) as the preferred way to determine IRQ routing (using PCI registers as a backup-method). After all, many device-drivers want a specific PCI device or class, which ACPI cannot directly deliver. ACPIs PCI-concept is horribly complex and doesn't deliver any obvious advantage.
In general it's possible that PCI devices might be listed in the ACPI namespace, but there's generally little reason to unless it confers some extra information. For example a motherboard manufacturer might list the devices built into the chipset itself, like USB controllers, SATA/ATA controllers, integrated audio and so forth. But these are basically just entry stubs consisting of a device device and _ADR tag. Some ATA controllers will have some extra information for power management, but that's really about it in practice. PCI has it's own enumeration abilities which should always be used to determine what's directly connected to the bus. ACPI's job in all this is simply to say "here's a root bus, enable access to it and enumerate it later".
Thanks a lot guys. Now it looks pretty much clear. Basically enumeration of the PCI devices by ACPI relays upon motherboard and ACPI firmware ability to report ones. Am I right?
One more thing, the reason I wanted to use ACPI is to avoid probing for legacy ISA bus for devices on it. Is it safe to assume that all of those devices will be reported by ACPICA? Or am I wrong again?
They should be, that doesn't mean its impossible for their to be bugs or poorly programmed AML though. In general if the system boots from BIOS and doesn't say an item is there that should be part of the PC standard you can probably assume it's there that's pretty much the alternative without ACPI anyways.
guitarist wrote:One more thing, the reason I wanted to use ACPI is to avoid probing for legacy ISA bus for devices on it. Is it safe to assume that all of those devices will be reported by ACPICA? Or am I wrong again?
You could split "ISA devices" into 3 categories:
Legacy devices built into the chipset (e.g. into the LPC bridge), which ACPI should know about and should mention.
"Plug and Play compatible" ISA cards plugged into ISA slots. ACPI should know about these and should tell the OS about them, but may not (I'd assume a "higher than normal" chance of firmware bugs here). Unfortunately, PCI was introduced soon after "PnP ISA", so most ISA cards aren't "Plug and Play compatible".
Normal ISA cards plugged into ISA slots. ACPI won't know about these and won't tell the OS about them.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
After some research I found that one can't rely on ACPI to enumerate even legacy devices. For instance I noticed that bochs does not report COM ports while on VmWare and Others reports them.