From 2cdc3e3546547eb852232a01e529dbbfb270a3ed Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Tue, 9 Feb 2021 11:32:40 +0100 Subject: [PATCH] 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 --- vmm/src/device_manager.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 01f1acbd4..8918e9bb7 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -3566,6 +3566,23 @@ impl Aml for DeviceManager { let pci_device_methods = PciDevSlotMethods {}; 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 = 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 = aml::Device::new("_SB_.PCI0".into(), pci_dsdt_inner_data).to_aml_bytes();