188 lines
9.9 KiB
Plaintext
188 lines
9.9 KiB
Plaintext
|
ACPI considerations for PCI host bridges
|
|||
|
|
|||
|
The general rule is that the ACPI namespace should describe everything the
|
|||
|
OS might use unless there's another way for the OS to find it [1, 2].
|
|||
|
|
|||
|
For example, there's no standard hardware mechanism for enumerating PCI
|
|||
|
host bridges, so the ACPI namespace must describe each host bridge, the
|
|||
|
method for accessing PCI config space below it, the address space windows
|
|||
|
the host bridge forwards to PCI (using _CRS), and the routing of legacy
|
|||
|
INTx interrupts (using _PRT).
|
|||
|
|
|||
|
PCI devices, which are below the host bridge, generally do not need to be
|
|||
|
described via ACPI. The OS can discover them via the standard PCI
|
|||
|
enumeration mechanism, using config accesses to discover and identify
|
|||
|
devices and read and size their BARs. However, ACPI may describe PCI
|
|||
|
devices if it provides power management or hotplug functionality for them
|
|||
|
or if the device has INTx interrupts connected by platform interrupt
|
|||
|
controllers and a _PRT is needed to describe those connections.
|
|||
|
|
|||
|
ACPI resource description is done via _CRS objects of devices in the ACPI
|
|||
|
namespace [2]. The _CRS is like a generalized PCI BAR: the OS can read
|
|||
|
_CRS and figure out what resource is being consumed even if it doesn't have
|
|||
|
a driver for the device [3]. That's important because it means an old OS
|
|||
|
can work correctly even on a system with new devices unknown to the OS.
|
|||
|
The new devices might not do anything, but the OS can at least make sure no
|
|||
|
resources conflict with them.
|
|||
|
|
|||
|
Static tables like MCFG, HPET, ECDT, etc., are *not* mechanisms for
|
|||
|
reserving address space. The static tables are for things the OS needs to
|
|||
|
know early in boot, before it can parse the ACPI namespace. If a new table
|
|||
|
is defined, an old OS needs to operate correctly even though it ignores the
|
|||
|
table. _CRS allows that because it is generic and understood by the old
|
|||
|
OS; a static table does not.
|
|||
|
|
|||
|
If the OS is expected to manage a non-discoverable device described via
|
|||
|
ACPI, that device will have a specific _HID/_CID that tells the OS what
|
|||
|
driver to bind to it, and the _CRS tells the OS and the driver where the
|
|||
|
device's registers are.
|
|||
|
|
|||
|
PCI host bridges are PNP0A03 or PNP0A08 devices. Their _CRS should
|
|||
|
describe all the address space they consume. This includes all the windows
|
|||
|
they forward down to the PCI bus, as well as registers of the host bridge
|
|||
|
itself that are not forwarded to PCI. The host bridge registers include
|
|||
|
things like secondary/subordinate bus registers that determine the bus
|
|||
|
range below the bridge, window registers that describe the apertures, etc.
|
|||
|
These are all device-specific, non-architected things, so the only way a
|
|||
|
PNP0A03/PNP0A08 driver can manage them is via _PRS/_CRS/_SRS, which contain
|
|||
|
the device-specific details. The host bridge registers also include ECAM
|
|||
|
space, since it is consumed by the host bridge.
|
|||
|
|
|||
|
ACPI defines a Consumer/Producer bit to distinguish the bridge registers
|
|||
|
("Consumer") from the bridge apertures ("Producer") [4, 5], but early
|
|||
|
BIOSes didn't use that bit correctly. The result is that the current ACPI
|
|||
|
spec defines Consumer/Producer only for the Extended Address Space
|
|||
|
descriptors; the bit should be ignored in the older QWord/DWord/Word
|
|||
|
Address Space descriptors. Consequently, OSes have to assume all
|
|||
|
QWord/DWord/Word descriptors are windows.
|
|||
|
|
|||
|
Prior to the addition of Extended Address Space descriptors, the failure of
|
|||
|
Consumer/Producer meant there was no way to describe bridge registers in
|
|||
|
the PNP0A03/PNP0A08 device itself. The workaround was to describe the
|
|||
|
bridge registers (including ECAM space) in PNP0C02 catch-all devices [6].
|
|||
|
With the exception of ECAM, the bridge register space is device-specific
|
|||
|
anyway, so the generic PNP0A03/PNP0A08 driver (pci_root.c) has no need to
|
|||
|
know about it.
|
|||
|
|
|||
|
New architectures should be able to use "Consumer" Extended Address Space
|
|||
|
descriptors in the PNP0A03 device for bridge registers, including ECAM,
|
|||
|
although a strict interpretation of [6] might prohibit this. Old x86 and
|
|||
|
ia64 kernels assume all address space descriptors, including "Consumer"
|
|||
|
Extended Address Space ones, are windows, so it would not be safe to
|
|||
|
describe bridge registers this way on those architectures.
|
|||
|
|
|||
|
PNP0C02 "motherboard" devices are basically a catch-all. There's no
|
|||
|
programming model for them other than "don't use these resources for
|
|||
|
anything else." So a PNP0C02 _CRS should claim any address space that is
|
|||
|
(1) not claimed by _CRS under any other device object in the ACPI namespace
|
|||
|
and (2) should not be assigned by the OS to something else.
|
|||
|
|
|||
|
The PCIe spec requires the Enhanced Configuration Access Method (ECAM)
|
|||
|
unless there's a standard firmware interface for config access, e.g., the
|
|||
|
ia64 SAL interface [7]. A host bridge consumes ECAM memory address space
|
|||
|
and converts memory accesses into PCI configuration accesses. The spec
|
|||
|
defines the ECAM address space layout and functionality; only the base of
|
|||
|
the address space is device-specific. An ACPI OS learns the base address
|
|||
|
from either the static MCFG table or a _CBA method in the PNP0A03 device.
|
|||
|
|
|||
|
The MCFG table must describe the ECAM space of non-hot pluggable host
|
|||
|
bridges [8]. Since MCFG is a static table and can't be updated by hotplug,
|
|||
|
a _CBA method in the PNP0A03 device describes the ECAM space of a
|
|||
|
hot-pluggable host bridge [9]. Note that for both MCFG and _CBA, the base
|
|||
|
address always corresponds to bus 0, even if the bus range below the bridge
|
|||
|
(which is reported via _CRS) doesn't start at 0.
|
|||
|
|
|||
|
|
|||
|
[1] ACPI 6.2, sec 6.1:
|
|||
|
For any device that is on a non-enumerable type of bus (for example, an
|
|||
|
ISA bus), OSPM enumerates the devices' identifier(s) and the ACPI
|
|||
|
system firmware must supply an _HID object ... for each device to
|
|||
|
enable OSPM to do that.
|
|||
|
|
|||
|
[2] ACPI 6.2, sec 3.7:
|
|||
|
The OS enumerates motherboard devices simply by reading through the
|
|||
|
ACPI Namespace looking for devices with hardware IDs.
|
|||
|
|
|||
|
Each device enumerated by ACPI includes ACPI-defined objects in the
|
|||
|
ACPI Namespace that report the hardware resources the device could
|
|||
|
occupy [_PRS], an object that reports the resources that are currently
|
|||
|
used by the device [_CRS], and objects for configuring those resources
|
|||
|
[_SRS]. The information is used by the Plug and Play OS (OSPM) to
|
|||
|
configure the devices.
|
|||
|
|
|||
|
[3] ACPI 6.2, sec 6.2:
|
|||
|
OSPM uses device configuration objects to configure hardware resources
|
|||
|
for devices enumerated via ACPI. Device configuration objects provide
|
|||
|
information about current and possible resource requirements, the
|
|||
|
relationship between shared resources, and methods for configuring
|
|||
|
hardware resources.
|
|||
|
|
|||
|
When OSPM enumerates a device, it calls _PRS to determine the resource
|
|||
|
requirements of the device. It may also call _CRS to find the current
|
|||
|
resource settings for the device. Using this information, the Plug and
|
|||
|
Play system determines what resources the device should consume and
|
|||
|
sets those resources by calling the device’s _SRS control method.
|
|||
|
|
|||
|
In ACPI, devices can consume resources (for example, legacy keyboards),
|
|||
|
provide resources (for example, a proprietary PCI bridge), or do both.
|
|||
|
Unless otherwise specified, resources for a device are assumed to be
|
|||
|
taken from the nearest matching resource above the device in the device
|
|||
|
hierarchy.
|
|||
|
|
|||
|
[4] ACPI 6.2, sec 6.4.3.5.1, 2, 3, 4:
|
|||
|
QWord/DWord/Word Address Space Descriptor (.1, .2, .3)
|
|||
|
General Flags: Bit [0] Ignored
|
|||
|
|
|||
|
Extended Address Space Descriptor (.4)
|
|||
|
General Flags: Bit [0] Consumer/Producer:
|
|||
|
1–This device consumes this resource
|
|||
|
0–This device produces and consumes this resource
|
|||
|
|
|||
|
[5] ACPI 6.2, sec 19.6.43:
|
|||
|
ResourceUsage specifies whether the Memory range is consumed by
|
|||
|
this device (ResourceConsumer) or passed on to child devices
|
|||
|
(ResourceProducer). If nothing is specified, then
|
|||
|
ResourceConsumer is assumed.
|
|||
|
|
|||
|
[6] PCI Firmware 3.2, sec 4.1.2:
|
|||
|
If the operating system does not natively comprehend reserving the
|
|||
|
MMCFG region, the MMCFG region must be reserved by firmware. The
|
|||
|
address range reported in the MCFG table or by _CBA method (see Section
|
|||
|
4.1.3) must be reserved by declaring a motherboard resource. For most
|
|||
|
systems, the motherboard resource would appear at the root of the ACPI
|
|||
|
namespace (under \_SB) in a node with a _HID of EISAID (PNP0C02), and
|
|||
|
the resources in this case should not be claimed in the root PCI bus’s
|
|||
|
_CRS. The resources can optionally be returned in Int15 E820 or
|
|||
|
EFIGetMemoryMap as reserved memory but must always be reported through
|
|||
|
ACPI as a motherboard resource.
|
|||
|
|
|||
|
[7] PCI Express 4.0, sec 7.2.2:
|
|||
|
For systems that are PC-compatible, or that do not implement a
|
|||
|
processor-architecture-specific firmware interface standard that allows
|
|||
|
access to the Configuration Space, the ECAM is required as defined in
|
|||
|
this section.
|
|||
|
|
|||
|
[8] PCI Firmware 3.2, sec 4.1.2:
|
|||
|
The MCFG table is an ACPI table that is used to communicate the base
|
|||
|
addresses corresponding to the non-hot removable PCI Segment Groups
|
|||
|
range within a PCI Segment Group available to the operating system at
|
|||
|
boot. This is required for the PC-compatible systems.
|
|||
|
|
|||
|
The MCFG table is only used to communicate the base addresses
|
|||
|
corresponding to the PCI Segment Groups available to the system at
|
|||
|
boot.
|
|||
|
|
|||
|
[9] PCI Firmware 3.2, sec 4.1.3:
|
|||
|
The _CBA (Memory mapped Configuration Base Address) control method is
|
|||
|
an optional ACPI object that returns the 64-bit memory mapped
|
|||
|
configuration base address for the hot plug capable host bridge. The
|
|||
|
base address returned by _CBA is processor-relative address. The _CBA
|
|||
|
control method evaluates to an Integer.
|
|||
|
|
|||
|
This control method appears under a host bridge object. When the _CBA
|
|||
|
method appears under an active host bridge object, the operating system
|
|||
|
evaluates this structure to identify the memory mapped configuration
|
|||
|
base address corresponding to the PCI Segment Group for the bus number
|
|||
|
range specified in _CRS method. An ACPI name space object that contains
|
|||
|
the _CBA method must also contain a corresponding _SEG method.
|