vmm: Populate MCFG table with details of all PCI segments

The MCFG table holds the PCI MMIO config details for all the MMIO PCI
config devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2021-10-05 15:06:55 +01:00
parent c886d71d29
commit 080ce9b068
3 changed files with 19 additions and 12 deletions

View File

@ -222,20 +222,22 @@ fn create_facp_table(dsdt_offset: GuestAddress) -> Sdt {
facp facp
} }
fn create_mcfg_table() -> Sdt { fn create_mcfg_table(device_manager: &Arc<Mutex<DeviceManager>>) -> Sdt {
let mut mcfg = Sdt::new(*b"MCFG", 36, 1, *b"CLOUDH", *b"CHMCFG ", 1); let mut mcfg = Sdt::new(*b"MCFG", 36, 1, *b"CLOUDH", *b"CHMCFG ", 1);
// MCFG reserved 8 bytes // MCFG reserved 8 bytes
mcfg.append(0u64); mcfg.append(0u64);
// 32-bit PCI enhanced configuration mechanism for segment in device_manager.lock().unwrap().pci_segments() {
mcfg.append(PciRangeEntry { // 32-bit PCI enhanced configuration mechanism
base_address: arch::layout::PCI_MMCONFIG_START.0, mcfg.append(PciRangeEntry {
segment: 0, base_address: segment.mmio_config_address,
start: 0, segment: segment.id,
end: 0, start: 0,
..Default::default() end: 0,
}); ..Default::default()
});
}
mcfg mcfg
} }
@ -536,7 +538,7 @@ pub fn create_acpi_tables(
} }
// MCFG // MCFG
let mcfg = create_mcfg_table(); let mcfg = create_mcfg_table(device_manager);
let mcfg_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap(); let mcfg_offset = prev_tbl_off.checked_add(prev_tbl_len).unwrap();
guest_mem guest_mem
.write_slice(mcfg.as_slice(), mcfg_offset) .write_slice(mcfg.as_slice(), mcfg_offset)

View File

@ -3265,6 +3265,11 @@ impl DeviceManager {
Arc::clone(self.pci_segments[0].pci_config_io.as_ref().unwrap()) Arc::clone(self.pci_segments[0].pci_config_io.as_ref().unwrap())
} }
#[cfg(feature = "acpi")]
pub(crate) fn pci_segments(&self) -> &Vec<PciSegment> {
&self.pci_segments
}
pub fn console(&self) -> &Arc<Console> { pub fn console(&self) -> &Arc<Console> {
&self.console &self.console
} }

View File

@ -25,10 +25,10 @@ use vm_device::BusDevice;
const PCI_MMIO_CONFIG_SIZE: u64 = 4096 * 256; const PCI_MMIO_CONFIG_SIZE: u64 = 4096 * 256;
pub(crate) struct PciSegment { pub(crate) struct PciSegment {
id: u16, pub(crate) id: u16,
pub(crate) pci_bus: Arc<Mutex<PciBus>>, pub(crate) pci_bus: Arc<Mutex<PciBus>>,
pub(crate) pci_config_mmio: Arc<Mutex<PciConfigMmio>>, pub(crate) pci_config_mmio: Arc<Mutex<PciConfigMmio>>,
mmio_config_address: u64, pub(crate) mmio_config_address: u64,
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub(crate) pci_config_io: Option<Arc<Mutex<PciConfigIo>>>, pub(crate) pci_config_io: Option<Arc<Mutex<PciConfigIo>>>,