197 lines
7.9 KiB
Diff
197 lines
7.9 KiB
Diff
|
|
From 62b5c897e367c3db477a680b7557662347677433 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Keqian Zhu <zhukeqian1@huawei.com>
|
||
|
|
Date: Fri, 10 Apr 2020 10:59:55 +0800
|
||
|
|
Subject: [PATCH] intc/gicv3_cpuif: Factor out gicv3_init_one_cpuif
|
||
|
|
|
||
|
|
The CPU object of hotplugged CPU will be defer-created (during
|
||
|
|
hotplug session), so we must factor out some code to let it can
|
||
|
|
be applied to individual CPU.
|
||
|
|
|
||
|
|
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||
|
|
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||
|
|
---
|
||
|
|
hw/intc/arm_gicv3.c | 5 +-
|
||
|
|
hw/intc/arm_gicv3_cpuif.c | 122 ++++++++++++++++++--------------------
|
||
|
|
hw/intc/gicv3_internal.h | 2 +-
|
||
|
|
3 files changed, 64 insertions(+), 65 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
|
||
|
|
index 9f5f815db9..40016cb84a 100644
|
||
|
|
--- a/hw/intc/arm_gicv3.c
|
||
|
|
+++ b/hw/intc/arm_gicv3.c
|
||
|
|
@@ -382,6 +382,7 @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
|
||
|
|
GICv3State *s = ARM_GICV3(dev);
|
||
|
|
ARMGICv3Class *agc = ARM_GICV3_GET_CLASS(s);
|
||
|
|
Error *local_err = NULL;
|
||
|
|
+ int i;
|
||
|
|
|
||
|
|
agc->parent_realize(dev, &local_err);
|
||
|
|
if (local_err) {
|
||
|
|
@@ -391,7 +392,9 @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
|
||
|
|
|
||
|
|
gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops);
|
||
|
|
|
||
|
|
- gicv3_init_cpuif(s);
|
||
|
|
+ for (i = 0; i < s->num_cpu; i++) {
|
||
|
|
+ gicv3_init_one_cpuif(s, i);
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
|
||
|
|
static void arm_gicv3_class_init(ObjectClass *klass, void *data)
|
||
|
|
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
|
||
|
|
index 85fc369e55..70809bcddd 100644
|
||
|
|
--- a/hw/intc/arm_gicv3_cpuif.c
|
||
|
|
+++ b/hw/intc/arm_gicv3_cpuif.c
|
||
|
|
@@ -2625,76 +2625,72 @@ static void gicv3_cpuif_el_change_hook(ARMCPU *cpu, void *opaque)
|
||
|
|
gicv3_cpuif_update(cs);
|
||
|
|
}
|
||
|
|
|
||
|
|
-void gicv3_init_cpuif(GICv3State *s)
|
||
|
|
+void gicv3_init_one_cpuif(GICv3State *s, int ncpu)
|
||
|
|
{
|
||
|
|
/* Called from the GICv3 realize function; register our system
|
||
|
|
* registers with the CPU
|
||
|
|
*/
|
||
|
|
- int i;
|
||
|
|
-
|
||
|
|
- for (i = 0; i < s->num_cpu; i++) {
|
||
|
|
- ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));
|
||
|
|
- GICv3CPUState *cs = &s->cpu[i];
|
||
|
|
-
|
||
|
|
- /* Note that we can't just use the GICv3CPUState as an opaque pointer
|
||
|
|
- * in define_arm_cp_regs_with_opaque(), because when we're called back
|
||
|
|
- * it might be with code translated by CPU 0 but run by CPU 1, in
|
||
|
|
- * which case we'd get the wrong value.
|
||
|
|
- * So instead we define the regs with no ri->opaque info, and
|
||
|
|
- * get back to the GICv3CPUState from the CPUARMState.
|
||
|
|
+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(ncpu));
|
||
|
|
+ GICv3CPUState *cs = &s->cpu[ncpu];
|
||
|
|
+
|
||
|
|
+ /* Note that we can't just use the GICv3CPUState as an opaque pointer
|
||
|
|
+ * in define_arm_cp_regs_with_opaque(), because when we're called back
|
||
|
|
+ * it might be with code translated by CPU 0 but run by CPU 1, in
|
||
|
|
+ * which case we'd get the wrong value.
|
||
|
|
+ * So instead we define the regs with no ri->opaque info, and
|
||
|
|
+ * get back to the GICv3CPUState from the CPUARMState.
|
||
|
|
+ */
|
||
|
|
+ define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
|
||
|
|
+ if (arm_feature(&cpu->env, ARM_FEATURE_EL2)
|
||
|
|
+ && cpu->gic_num_lrs) {
|
||
|
|
+ int j;
|
||
|
|
+
|
||
|
|
+ cs->num_list_regs = cpu->gic_num_lrs;
|
||
|
|
+ cs->vpribits = cpu->gic_vpribits;
|
||
|
|
+ cs->vprebits = cpu->gic_vprebits;
|
||
|
|
+
|
||
|
|
+ /* Check against architectural constraints: getting these
|
||
|
|
+ * wrong would be a bug in the CPU code defining these,
|
||
|
|
+ * and the implementation relies on them holding.
|
||
|
|
*/
|
||
|
|
- define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
|
||
|
|
- if (arm_feature(&cpu->env, ARM_FEATURE_EL2)
|
||
|
|
- && cpu->gic_num_lrs) {
|
||
|
|
- int j;
|
||
|
|
-
|
||
|
|
- cs->num_list_regs = cpu->gic_num_lrs;
|
||
|
|
- cs->vpribits = cpu->gic_vpribits;
|
||
|
|
- cs->vprebits = cpu->gic_vprebits;
|
||
|
|
-
|
||
|
|
- /* Check against architectural constraints: getting these
|
||
|
|
- * wrong would be a bug in the CPU code defining these,
|
||
|
|
- * and the implementation relies on them holding.
|
||
|
|
- */
|
||
|
|
- g_assert(cs->vprebits <= cs->vpribits);
|
||
|
|
- g_assert(cs->vprebits >= 5 && cs->vprebits <= 7);
|
||
|
|
- g_assert(cs->vpribits >= 5 && cs->vpribits <= 8);
|
||
|
|
+ g_assert(cs->vprebits <= cs->vpribits);
|
||
|
|
+ g_assert(cs->vprebits >= 5 && cs->vprebits <= 7);
|
||
|
|
+ g_assert(cs->vpribits >= 5 && cs->vpribits <= 8);
|
||
|
|
|
||
|
|
- define_arm_cp_regs(cpu, gicv3_cpuif_hcr_reginfo);
|
||
|
|
+ define_arm_cp_regs(cpu, gicv3_cpuif_hcr_reginfo);
|
||
|
|
|
||
|
|
- for (j = 0; j < cs->num_list_regs; j++) {
|
||
|
|
- /* Note that the AArch64 LRs are 64-bit; the AArch32 LRs
|
||
|
|
- * are split into two cp15 regs, LR (the low part, with the
|
||
|
|
- * same encoding as the AArch64 LR) and LRC (the high part).
|
||
|
|
- */
|
||
|
|
- ARMCPRegInfo lr_regset[] = {
|
||
|
|
- { .name = "ICH_LRn_EL2", .state = ARM_CP_STATE_BOTH,
|
||
|
|
- .opc0 = 3, .opc1 = 4, .crn = 12,
|
||
|
|
- .crm = 12 + (j >> 3), .opc2 = j & 7,
|
||
|
|
- .type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||
|
|
- .access = PL2_RW,
|
||
|
|
- .readfn = ich_lr_read,
|
||
|
|
- .writefn = ich_lr_write,
|
||
|
|
- },
|
||
|
|
- { .name = "ICH_LRCn_EL2", .state = ARM_CP_STATE_AA32,
|
||
|
|
- .cp = 15, .opc1 = 4, .crn = 12,
|
||
|
|
- .crm = 14 + (j >> 3), .opc2 = j & 7,
|
||
|
|
- .type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||
|
|
- .access = PL2_RW,
|
||
|
|
- .readfn = ich_lr_read,
|
||
|
|
- .writefn = ich_lr_write,
|
||
|
|
- },
|
||
|
|
- REGINFO_SENTINEL
|
||
|
|
- };
|
||
|
|
- define_arm_cp_regs(cpu, lr_regset);
|
||
|
|
- }
|
||
|
|
- if (cs->vprebits >= 6) {
|
||
|
|
- define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr1_reginfo);
|
||
|
|
- }
|
||
|
|
- if (cs->vprebits == 7) {
|
||
|
|
- define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr23_reginfo);
|
||
|
|
- }
|
||
|
|
+ for (j = 0; j < cs->num_list_regs; j++) {
|
||
|
|
+ /* Note that the AArch64 LRs are 64-bit; the AArch32 LRs
|
||
|
|
+ * are split into two cp15 regs, LR (the low part, with the
|
||
|
|
+ * same encoding as the AArch64 LR) and LRC (the high part).
|
||
|
|
+ */
|
||
|
|
+ ARMCPRegInfo lr_regset[] = {
|
||
|
|
+ { .name = "ICH_LRn_EL2", .state = ARM_CP_STATE_BOTH,
|
||
|
|
+ .opc0 = 3, .opc1 = 4, .crn = 12,
|
||
|
|
+ .crm = 12 + (j >> 3), .opc2 = j & 7,
|
||
|
|
+ .type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||
|
|
+ .access = PL2_RW,
|
||
|
|
+ .readfn = ich_lr_read,
|
||
|
|
+ .writefn = ich_lr_write,
|
||
|
|
+ },
|
||
|
|
+ { .name = "ICH_LRCn_EL2", .state = ARM_CP_STATE_AA32,
|
||
|
|
+ .cp = 15, .opc1 = 4, .crn = 12,
|
||
|
|
+ .crm = 14 + (j >> 3), .opc2 = j & 7,
|
||
|
|
+ .type = ARM_CP_IO | ARM_CP_NO_RAW,
|
||
|
|
+ .access = PL2_RW,
|
||
|
|
+ .readfn = ich_lr_read,
|
||
|
|
+ .writefn = ich_lr_write,
|
||
|
|
+ },
|
||
|
|
+ REGINFO_SENTINEL
|
||
|
|
+ };
|
||
|
|
+ define_arm_cp_regs(cpu, lr_regset);
|
||
|
|
+ }
|
||
|
|
+ if (cs->vprebits >= 6) {
|
||
|
|
+ define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr1_reginfo);
|
||
|
|
+ }
|
||
|
|
+ if (cs->vprebits == 7) {
|
||
|
|
+ define_arm_cp_regs(cpu, gicv3_cpuif_ich_apxr23_reginfo);
|
||
|
|
}
|
||
|
|
- arm_register_el_change_hook(cpu, gicv3_cpuif_el_change_hook, cs);
|
||
|
|
}
|
||
|
|
+ arm_register_el_change_hook(cpu, gicv3_cpuif_el_change_hook, cs);
|
||
|
|
}
|
||
|
|
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
|
||
|
|
index b9c37453b0..65db012600 100644
|
||
|
|
--- a/hw/intc/gicv3_internal.h
|
||
|
|
+++ b/hw/intc/gicv3_internal.h
|
||
|
|
@@ -495,7 +495,7 @@ void gicv3_redist_update_lpi(GICv3CPUState *cs);
|
||
|
|
*/
|
||
|
|
void gicv3_redist_update_lpi_only(GICv3CPUState *cs);
|
||
|
|
void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns);
|
||
|
|
-void gicv3_init_cpuif(GICv3State *s);
|
||
|
|
+void gicv3_init_one_cpuif(GICv3State *s, int ncpu);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* gicv3_cpuif_update:
|
||
|
|
--
|
||
|
|
2.27.0
|
||
|
|
|