vmm: device_manager: Add PCI routing table to ACPI

Here we are adding the PCI routing table, commonly called _PRT, to the
ACPI DSDT. For simplification reasons, we chose not to implement PCI
links as this involves dynamic decision from the guest OS, which result
in lots of complexity both from an AML perspective and from a device
manager perspective.

That's why the _PRT creates a static list of 32 entries, each assigned
with the IRQ number previously reserved by the device manager.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2021-02-09 11:32:40 +01:00 committed by Rob Bradford
parent de9471fc72
commit 2cdc3e3546

View File

@ -3566,6 +3566,23 @@ impl Aml for DeviceManager {
let pci_device_methods = PciDevSlotMethods {}; let pci_device_methods = PciDevSlotMethods {};
pci_dsdt_inner_data.push(&pci_device_methods); pci_dsdt_inner_data.push(&pci_device_methods);
// Build PCI routing table, listing IRQs assigned to PCI devices.
let prt_package_list: Vec<(u32, u32)> = self
.pci_device_irqs
.iter()
.map(|(bdf, irq)| (((((*bdf >> 3) & 0x1fu32) << 16) | 0xffffu32), *irq))
.collect();
let prt_package_list: Vec<aml::Package> = prt_package_list
.iter()
.map(|(bdf, irq)| aml::Package::new(vec![bdf, &0u8, &0u8, irq]))
.collect();
let prt_package_list: Vec<&dyn Aml> = prt_package_list
.iter()
.map(|item| item as &dyn Aml)
.collect();
let prt = aml::Name::new("_PRT".into(), &aml::Package::new(prt_package_list));
pci_dsdt_inner_data.push(&prt);
let pci_dsdt_data = let pci_dsdt_data =
aml::Device::new("_SB_.PCI0".into(), pci_dsdt_inner_data).to_aml_bytes(); aml::Device::new("_SB_.PCI0".into(), pci_dsdt_inner_data).to_aml_bytes();