fdt: add PMU node to fdt

PMU node in fdt stores some important info like irq number.

Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
This commit is contained in:
Jianyong Wu 2022-01-13 18:00:15 +08:00 committed by Xin Wang
parent 53060874a7
commit 81c5855184
3 changed files with 31 additions and 0 deletions

View File

@ -51,11 +51,16 @@ const SIZE_CELLS: u32 = 0x2;
// Look for "The 1st cell..." // Look for "The 1st cell..."
const GIC_FDT_IRQ_TYPE_SPI: u32 = 0; const GIC_FDT_IRQ_TYPE_SPI: u32 = 0;
const GIC_FDT_IRQ_TYPE_PPI: u32 = 1; 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 // 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_EDGE_RISING: u32 = 1;
const IRQ_TYPE_LEVEL_HI: u32 = 4; const IRQ_TYPE_LEVEL_HI: u32 = 4;
// PMU PPI interrupt number
pub const AARCH64_PMU_IRQ: u32 = 7;
// Keys and Buttons // Keys and Buttons
// System Power Down // System Power Down
const KEY_POWER: u32 = 116; const KEY_POWER: u32 = 116;
@ -91,6 +96,7 @@ pub fn create_fdt<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::BuildHash
pci_space_info: &[PciSpaceInfo], pci_space_info: &[PciSpaceInfo],
numa_nodes: &NumaNodes, numa_nodes: &NumaNodes,
virtio_iommu_bdf: Option<u32>, virtio_iommu_bdf: Option<u32>,
pmu_supported: bool,
) -> FdtWriterResult<Vec<u8>> { ) -> FdtWriterResult<Vec<u8>> {
// Allocate stuff necessary for the holding the blob. // Allocate stuff necessary for the holding the blob.
let mut fdt = FdtWriter::new().unwrap(); let mut fdt = FdtWriter::new().unwrap();
@ -114,6 +120,9 @@ pub fn create_fdt<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::BuildHash
create_chosen_node(&mut fdt, cmdline, initrd)?; create_chosen_node(&mut fdt, cmdline, initrd)?;
create_gic_node(&mut fdt, gic_device)?; create_gic_node(&mut fdt, gic_device)?;
create_timer_node(&mut fdt)?; create_timer_node(&mut fdt)?;
if pmu_supported {
create_pmu_node(&mut fdt, vcpu_mpidr.len())?;
}
create_clock_node(&mut fdt)?; create_clock_node(&mut fdt)?;
create_psci_node(&mut fdt)?; create_psci_node(&mut fdt)?;
create_devices_node(&mut fdt, device_info)?; create_devices_node(&mut fdt, device_info)?;
@ -540,6 +549,24 @@ fn create_devices_node<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::Buil
Ok(()) Ok(())
} }
fn create_pmu_node(fdt: &mut FdtWriter, cpu_nums: usize) -> 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( fn create_pci_nodes(
fdt: &mut FdtWriter, fdt: &mut FdtWriter,
pci_device_info: &[PciSpaceInfo], pci_device_info: &[PciSpaceInfo],

View File

@ -139,6 +139,7 @@ pub fn configure_system<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::Bui
virtio_iommu_bdf: Option<u32>, virtio_iommu_bdf: Option<u32>,
gic_device: &dyn GicDevice, gic_device: &dyn GicDevice,
numa_nodes: &NumaNodes, numa_nodes: &NumaNodes,
pmu_supported: bool,
) -> super::Result<()> { ) -> super::Result<()> {
let fdt_final = fdt::create_fdt( let fdt_final = fdt::create_fdt(
guest_mem, guest_mem,
@ -151,6 +152,7 @@ pub fn configure_system<T: DeviceInfoForFdt + Clone + Debug, S: ::std::hash::Bui
pci_space_info, pci_space_info,
numa_nodes, numa_nodes,
virtio_iommu_bdf, virtio_iommu_bdf,
pmu_supported,
) )
.map_err(|_| Error::SetupFdt)?; .map_err(|_| Error::SetupFdt)?;

View File

@ -1172,6 +1172,7 @@ impl Vm {
virtio_iommu_bdf.map(|bdf| bdf.into()), virtio_iommu_bdf.map(|bdf| bdf.into()),
&*gic_device, &*gic_device,
&self.numa_nodes, &self.numa_nodes,
pmu_supported,
) )
.map_err(Error::ConfigureSystem)?; .map_err(Error::ConfigureSystem)?;
@ -2791,6 +2792,7 @@ mod tests {
&Vec::new(), &Vec::new(),
&BTreeMap::new(), &BTreeMap::new(),
None, None,
true,
) )
.is_ok()) .is_ok())
} }