diff --git a/arch/src/aarch64/fdt.rs b/arch/src/aarch64/fdt.rs index 36cf59053..4878cf691 100644 --- a/arch/src/aarch64/fdt.rs +++ b/arch/src/aarch64/fdt.rs @@ -51,11 +51,16 @@ const SIZE_CELLS: u32 = 0x2; // Look for "The 1st cell..." const GIC_FDT_IRQ_TYPE_SPI: u32 = 0; const GIC_FDT_IRQ_TYPE_PPI: u32 = 1; +const GIC_FDT_IRQ_PPI_CPU_SHIFT: u32 = 8; +const GIC_FDT_IRQ_PPI_CPU_MASK: u32 = 0xff << GIC_FDT_IRQ_PPI_CPU_SHIFT; // From https://elixir.bootlin.com/linux/v4.9.62/source/include/dt-bindings/interrupt-controller/irq.h#L17 const IRQ_TYPE_EDGE_RISING: u32 = 1; const IRQ_TYPE_LEVEL_HI: u32 = 4; +// PMU PPI interrupt number +pub const AARCH64_PMU_IRQ: u32 = 7; + // Keys and Buttons // System Power Down const KEY_POWER: u32 = 116; @@ -91,6 +96,7 @@ pub fn create_fdt, + pmu_supported: bool, ) -> FdtWriterResult> { // Allocate stuff necessary for the holding the blob. let mut fdt = FdtWriter::new().unwrap(); @@ -114,6 +120,9 @@ pub fn create_fdt FdtWriterResult<()> { + let num_cpus = cpu_nums as u64 as u32; + let compatible = "arm,armv8-pmuv3"; + let cpu_mask: u32 = + (((1 << num_cpus) - 1) << GIC_FDT_IRQ_PPI_CPU_SHIFT) & GIC_FDT_IRQ_PPI_CPU_MASK; + let irq = [ + GIC_FDT_IRQ_TYPE_PPI, + AARCH64_PMU_IRQ, + cpu_mask | IRQ_TYPE_LEVEL_HI, + ]; + + let pmu_node = fdt.begin_node("pmu")?; + fdt.property_string("compatible", compatible)?; + fdt.property_array_u32("interrupts", &irq)?; + fdt.end_node(pmu_node)?; + Ok(()) +} + fn create_pci_nodes( fdt: &mut FdtWriter, pci_device_info: &[PciSpaceInfo], diff --git a/arch/src/aarch64/mod.rs b/arch/src/aarch64/mod.rs index 954c40bc3..a20687043 100644 --- a/arch/src/aarch64/mod.rs +++ b/arch/src/aarch64/mod.rs @@ -139,6 +139,7 @@ pub fn configure_system, gic_device: &dyn GicDevice, numa_nodes: &NumaNodes, + pmu_supported: bool, ) -> super::Result<()> { let fdt_final = fdt::create_fdt( guest_mem, @@ -151,6 +152,7 @@ pub fn configure_system