"arm,armv7-timer");
}
qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
- if (vms->ns_el2_virt_timer_irq) {
+ if (vms->gic_version == VIRT_GIC_VERSION_5) {
+ /* The GICv5 architects the PPI numbers differently */
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
+ GICV5_PPI, GICV5_PPI_CNTPS, irqflags,
+ GICV5_PPI, GICV5_PPI_CNTP, irqflags,
+ GICV5_PPI, GICV5_PPI_CNTV, irqflags,
+ GICV5_PPI, GICV5_PPI_CNTHP, irqflags,
+ GICV5_PPI, GICV5_PPI_CNTHV, irqflags);
+ } else if (vms->ns_el2_virt_timer_irq) {
qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
GIC_FDT_IRQ_TYPE_PPI,
INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
qemu_fdt_add_subnode(ms->fdt, "/pmu");
if (arm_feature(&armcpu->env, ARM_FEATURE_V8)) {
const char compat[] = "arm,armv8-pmuv3";
+
qemu_fdt_setprop(ms->fdt, "/pmu", "compatible",
compat, sizeof(compat));
- qemu_fdt_setprop_cells(ms->fdt, "/pmu", "interrupts",
- GIC_FDT_IRQ_TYPE_PPI,
- INTID_TO_PPI(VIRTUAL_PMU_IRQ), irqflags);
+ if (vms->gic_version == VIRT_GIC_VERSION_5) {
+ qemu_fdt_setprop_cells(ms->fdt, "/pmu", "interrupts",
+ GICV5_PPI, GICV5_PPI_PMUIRQ, irqflags);
+ } else {
+ qemu_fdt_setprop_cells(ms->fdt, "/pmu", "interrupts",
+ GIC_FDT_IRQ_TYPE_PPI,
+ INTID_TO_PPI(VIRTUAL_PMU_IRQ),
+ irqflags);
+ }
}
}
#ifndef QEMU_ARM_FDT_H
#define QEMU_ARM_FDT_H
+/*
+ * These are for GICv2/v3/v4 only; GICv5 encodes the interrupt type in
+ * the DTB "interrupts" properties differently, using constants that
+ * match the architectural INTID.Type. In QEMU those are available as
+ * the GICV5_PPI and GICV5_SPI enum values in arm_gicv5_types.h.
+ */
#define GIC_FDT_IRQ_TYPE_SPI 0
#define GIC_FDT_IRQ_TYPE_PPI 1
+/*
+ * The trigger type/level field in the DTB "interrupts" property has
+ * the same encoding for GICv2/v3/v4 and v5.
+ */
#define GIC_FDT_IRQ_FLAGS_EDGE_LO_HI 1
#define GIC_FDT_IRQ_FLAGS_EDGE_HI_LO 2
#define GIC_FDT_IRQ_FLAGS_LEVEL_HI 4