mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 15:23:53 -06:00
{include/}hw/arm: refactor virt PPI logic
GIC Private Peripheral Interrupts (PPI) are defined as GIC INTID 16-31. As in, PPI0 is INTID16 .. PPI15 is INTID31. Arm's Base System Architecture specification (BSA) lists the mandated and recommended private interrupt IDs by INTID, not by PPI index. But current definitions in virt define them by PPI index, complicating cross referencing. Meanwhile, the PPI(x) macro counterintuitively adds 16 to the input value, converting a PPI index to an INTID. Resolve this by redefining the BSA-allocated PPIs by their INTIDs, and replacing the PPI(x) macro with an INTID_TO_PPI(x) one where required. Signed-off-by: Leif Lindholm <quic_llindhol@quicinc.com> Message-id: 20230919090229.188092-2-quic_llindhol@quicinc.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
d01448c79d
commit
9036e917f8
3 changed files with 27 additions and 23 deletions
|
@ -366,10 +366,14 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
|
|||
}
|
||||
qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
|
||||
qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
|
||||
GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_S_EL1_IRQ, irqflags,
|
||||
GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL1_IRQ, irqflags,
|
||||
GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_VIRT_IRQ, irqflags,
|
||||
GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL2_IRQ, irqflags);
|
||||
GIC_FDT_IRQ_TYPE_PPI,
|
||||
INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
|
||||
GIC_FDT_IRQ_TYPE_PPI,
|
||||
INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
|
||||
GIC_FDT_IRQ_TYPE_PPI,
|
||||
INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
|
||||
GIC_FDT_IRQ_TYPE_PPI,
|
||||
INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
|
||||
}
|
||||
|
||||
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
||||
|
@ -800,7 +804,7 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
|
|||
*/
|
||||
for (i = 0; i < smp_cpus; i++) {
|
||||
DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
|
||||
int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
|
||||
int intidbase = NUM_IRQS + i * GIC_INTERNAL;
|
||||
/* Mapping from the output timer irq lines from the CPU to the
|
||||
* GIC PPI inputs we use for the virt board.
|
||||
*/
|
||||
|
@ -814,22 +818,22 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
|
|||
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
|
||||
qdev_connect_gpio_out(cpudev, irq,
|
||||
qdev_get_gpio_in(vms->gic,
|
||||
ppibase + timer_irq[irq]));
|
||||
intidbase + timer_irq[irq]));
|
||||
}
|
||||
|
||||
if (vms->gic_version != VIRT_GIC_VERSION_2) {
|
||||
qemu_irq irq = qdev_get_gpio_in(vms->gic,
|
||||
ppibase + ARCH_GIC_MAINT_IRQ);
|
||||
intidbase + ARCH_GIC_MAINT_IRQ);
|
||||
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
|
||||
0, irq);
|
||||
} else if (vms->virt) {
|
||||
qemu_irq irq = qdev_get_gpio_in(vms->gic,
|
||||
ppibase + ARCH_GIC_MAINT_IRQ);
|
||||
intidbase + ARCH_GIC_MAINT_IRQ);
|
||||
sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq);
|
||||
}
|
||||
|
||||
qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
|
||||
qdev_get_gpio_in(vms->gic, ppibase
|
||||
qdev_get_gpio_in(vms->gic, intidbase
|
||||
+ VIRTUAL_PMU_IRQ));
|
||||
|
||||
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
|
||||
|
@ -1989,7 +1993,7 @@ static void virt_cpu_post_init(VirtMachineState *vms, MemoryRegion *sysmem)
|
|||
if (pmu) {
|
||||
assert(arm_feature(&ARM_CPU(cpu)->env, ARM_FEATURE_PMU));
|
||||
if (kvm_irqchip_in_kernel()) {
|
||||
kvm_arm_pmu_set_irq(cpu, PPI(VIRTUAL_PMU_IRQ));
|
||||
kvm_arm_pmu_set_irq(cpu, VIRTUAL_PMU_IRQ);
|
||||
}
|
||||
kvm_arm_pmu_init(cpu);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue