GICv5 requires a different set of FDT nodes to what was required for GICv2/v3. Therefore, add in a GICv5-specific function to generate the FDT nodes as this is much cleaner than trying to adapt the existing code to generate both variants. This change generates nodes for the GICv5 CPU interface only. This is enough to support PPIs. Additional FDT changes are to follow as the IRS and ITS support is added. Signed-off-by: Sascha Bischoff --- arm64/arm-cpu.c | 3 ++- arm64/gic.c | 25 ++++++++++++++++++++++++- arm64/include/kvm/gic.h | 3 ++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/arm64/arm-cpu.c b/arm64/arm-cpu.c index abdd6324..f460bee7 100644 --- a/arm64/arm-cpu.c +++ b/arm64/arm-cpu.c @@ -13,7 +13,8 @@ static void generate_fdt_nodes(void *fdt, struct kvm *kvm) { gic__generate_fdt_nodes(fdt, kvm->cfg.arch.irqchip, - kvm->cfg.arch.nested_virt); + kvm->cfg.arch.nested_virt, + kvm->nrcpus); timer__generate_fdt_nodes(fdt, kvm); pmu__generate_fdt_nodes(fdt, kvm); } diff --git a/arm64/gic.c b/arm64/gic.c index 8e4ff846..67b96734 100644 --- a/arm64/gic.c +++ b/arm64/gic.c @@ -368,7 +368,11 @@ static int gic__init_gic(struct kvm *kvm) } late_init(gic__init_gic) -void gic__generate_fdt_nodes(void *fdt, enum irqchip_type type, bool nested) +static void gic__generate_gicv5_fdt_nodes(void *fdt, enum irqchip_type type, + bool nested, int nr_cpus); + +void gic__generate_fdt_nodes(void *fdt, enum irqchip_type type, bool nested, + int nr_cpus) { const char *compatible, *msi_compatible = NULL; u64 msi_prop[2]; @@ -396,6 +400,8 @@ void gic__generate_fdt_nodes(void *fdt, enum irqchip_type type, bool nested) reg_prop[2] = cpu_to_fdt64(gic_redists_base); reg_prop[3] = cpu_to_fdt64(gic_redists_size); break; + case IRQCHIP_GICV5: + return gic__generate_gicv5_fdt_nodes(fdt, type, nested, nr_cpus); default: return; } @@ -428,6 +434,23 @@ void gic__generate_fdt_nodes(void *fdt, enum irqchip_type type, bool nested) _FDT(fdt_end_node(fdt)); } +static void gic__generate_gicv5_fdt_nodes(void *fdt, enum irqchip_type type, + bool nested, int nr_cpus) +{ + _FDT(fdt_begin_node(fdt, "gicv5-cpuif")); + _FDT(fdt_property_string(fdt, "compatible", "arm,gic-v5")); + _FDT(fdt_property_cell(fdt, "#interrupt-cells", GIC_FDT_IRQ_NUM_CELLS)); + _FDT(fdt_property(fdt, "interrupt-controller", NULL, 0)); + _FDT(fdt_property_cell(fdt, "#address-cells", 2)); + _FDT(fdt_property_cell(fdt, "#size-cells", 2)); + _FDT(fdt_property(fdt, "ranges", NULL, 0)); + + /* Use a hard-coded phandle for the GIC to help wire things up */ + _FDT(fdt_property_cell(fdt, "phandle", PHANDLE_GIC)); + + _FDT(fdt_end_node(fdt)); // End of GIC node +} + u32 gic__get_fdt_irq_cpumask(struct kvm *kvm) { /* Only for GICv2 */ diff --git a/arm64/include/kvm/gic.h b/arm64/include/kvm/gic.h index dd7729a2..13742bd5 100644 --- a/arm64/include/kvm/gic.h +++ b/arm64/include/kvm/gic.h @@ -43,7 +43,8 @@ struct kvm; int gic__alloc_irqnum(void); int gic__create(struct kvm *kvm, enum irqchip_type type); int gic__create_gicv2m_frame(struct kvm *kvm, u64 msi_frame_addr); -void gic__generate_fdt_nodes(void *fdt, enum irqchip_type type, bool nested); +void gic__generate_fdt_nodes(void *fdt, enum irqchip_type type, + bool nested, int nr_cpus); u32 gic__get_fdt_irq_cpumask(struct kvm *kvm); int gic__add_irqfd(struct kvm *kvm, unsigned int gsi, int trigger_fd, -- 2.34.1