Skip to content

Commit 50a61ee

Browse files
committed
pci: define PCI segment in FDT
Write the PCI root bridge in FDT when PCI is enabled. Signed-off-by: Babis Chalios <bchalios@amazon.es>
1 parent f45cce2 commit 50a61ee

File tree

1 file changed

+59
-0
lines changed
  • src/vmm/src/arch/aarch64

1 file changed

+59
-0
lines changed

src/vmm/src/arch/aarch64/fdt.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,13 @@ use vm_memory::GuestMemoryError;
1313

1414
use super::cache_info::{CacheEntry, read_cache_config};
1515
use super::gic::GICDevice;
16+
use crate::arch::{
17+
MEM_32BIT_DEVICES_SIZE, MEM_32BIT_DEVICES_START, MEM_64BIT_DEVICES_SIZE,
18+
MEM_64BIT_DEVICES_START, PCI_MMIO_CONFIG_SIZE_PER_SEGMENT,
19+
};
1620
use crate::device_manager::DeviceManager;
1721
use crate::device_manager::mmio::MMIODeviceInfo;
22+
use crate::device_manager::pci_mngr::PciDevices;
1823
use crate::devices::acpi::vmgenid::{VMGENID_MEM_SIZE, VmGenId};
1924
use crate::initrd::InitrdConfig;
2025
use crate::vstate::memory::{Address, GuestMemory, GuestMemoryMmap};
@@ -90,6 +95,7 @@ pub fn create_fdt(
9095
create_psci_node(&mut fdt_writer)?;
9196
create_devices_node(&mut fdt_writer, device_manager)?;
9297
create_vmgenid_node(&mut fdt_writer, &device_manager.acpi_devices.vmgenid)?;
98+
create_pci_nodes(&mut fdt_writer, &device_manager.pci_devices)?;
9399

94100
// End Header node.
95101
fdt_writer.end_node(root)?;
@@ -431,6 +437,59 @@ fn create_devices_node(
431437
Ok(())
432438
}
433439

440+
fn create_pci_nodes(fdt: &mut FdtWriter, pci_devices: &PciDevices) -> Result<(), FdtError> {
441+
if pci_devices.pci_segment.is_none() {
442+
return Ok(());
443+
}
444+
445+
// Fine to unwrap here, we just checked it's not `None`.
446+
let segment = pci_devices.pci_segment.as_ref().unwrap();
447+
448+
let pci_node_name = format!("pci@{:x}", segment.mmio_config_address);
449+
let ranges = [
450+
// 32bit addresses
451+
0x200_0000u32,
452+
(MEM_32BIT_DEVICES_START >> 32) as u32, // PCI address
453+
(MEM_32BIT_DEVICES_START & 0xffff_ffff) as u32,
454+
(MEM_32BIT_DEVICES_START >> 32) as u32, // CPU address
455+
(MEM_32BIT_DEVICES_START & 0xffff_ffff) as u32,
456+
(MEM_32BIT_DEVICES_SIZE >> 32) as u32, // Range size
457+
(MEM_32BIT_DEVICES_SIZE & 0xffff_ffff) as u32,
458+
// 64bit addresses
459+
0x300_0000u32,
460+
// PCI address
461+
(MEM_64BIT_DEVICES_START >> 32) as u32, // PCI address
462+
(MEM_64BIT_DEVICES_START & 0xffff_ffff) as u32,
463+
// CPU address
464+
(MEM_64BIT_DEVICES_START >> 32) as u32, // CPU address
465+
(MEM_64BIT_DEVICES_START & 0xffff_ffff) as u32,
466+
// Range size
467+
(MEM_64BIT_DEVICES_SIZE >> 32) as u32, // Range size
468+
((MEM_64BIT_DEVICES_SIZE & 0xffff_ffff) >> 32) as u32,
469+
];
470+
let pci_node = fdt.begin_node(&pci_node_name)?;
471+
472+
fdt.property_string("compatible", "pci-host-ecam-generic")?;
473+
fdt.property_string("device_type", "pci")?;
474+
fdt.property_array_u32("ranges", &ranges)?;
475+
fdt.property_array_u32("bus-range", &[0, 0])?;
476+
fdt.property_u32("linux,pci-domain", segment.id.into())?;
477+
fdt.property_u32("#address-cells", 3)?;
478+
fdt.property_u32("#size-cells", 2)?;
479+
fdt.property_array_u64(
480+
"reg",
481+
&[
482+
segment.mmio_config_address,
483+
PCI_MMIO_CONFIG_SIZE_PER_SEGMENT,
484+
],
485+
)?;
486+
fdt.property_u32("#interrupt-cells", 1)?;
487+
fdt.property_null("interrupt-map")?;
488+
fdt.property_null("interrupt-map-mask")?;
489+
fdt.property_null("dma-coherent")?;
490+
Ok(fdt.end_node(pci_node)?)
491+
}
492+
434493
#[cfg(test)]
435494
mod tests {
436495
use std::ffi::CString;

0 commit comments

Comments
 (0)