[PATCH qemu 38/38] target-arm: Add VBAR support to ARM1176 CPUs

Cédric Le Goater clg at kaod.org
Sat Nov 19 01:22:18 AEDT 2016


ARM1176 CPUs support the Vector Base Address Register but currently,
qemu only supports VBAR on ARMv7 CPUs. Fix this by adding a new
feature ARM_FEATURE_VBAR which is used for ARMv7 and ARM1176 CPUs.

Signed-off-by: Cédric Le Goater <clg at kaod.org>

>From Peter Maydell :

    Is it sufficient to set ARM_FEATURE_VBAR in the realizefn
    if FEATURE_V7 or FEATURE_EL3? (watch out that realizefn
    may change the value of the FEATURE_EL3 bit partway down
    so you'd need to do the check there) ?

    We implement VBAR in v7-without-EL3 even though architecturally
    it should only exist in v7-with-EL3 because we have some
    legacy board models which we implement as without-EL3 but
    where the guest (Linux) assumes it's running on a with-EL3
    CPU in NS mode. I'd rather we stick to the architectural
    definition for 1176 if we can rather than expanding the
    "things we do which aren't architectural" set if there's
    no legacy config that requires it. (If it is necessary
    to define it for 1176 always then that's OK, I'd just
    prefer not to unless we know we have to.)

    We should probably also have a brief comment noting that
    we define VBAR always in v7, even though architecturally
    it doesn't exist in non-EL3 configs, for the benefit of
    legacy board models.

    (In v8 VBAR is required whether EL3 is implemented or not.)

    thanks
Signed-off-by: Cédric Le Goater <clg at kaod.org>
---
 target-arm/cpu.c    |  2 ++
 target-arm/cpu.h    |  1 +
 target-arm/helper.c | 18 ++++++++++++------
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 99f0dbebb9f6..f8566deb0939 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -589,6 +589,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
         set_feature(env, ARM_FEATURE_LPAE);
     }
     if (arm_feature(env, ARM_FEATURE_V7)) {
+        set_feature(env, ARM_FEATURE_VBAR);
         set_feature(env, ARM_FEATURE_VAPA);
         set_feature(env, ARM_FEATURE_THUMB2);
         set_feature(env, ARM_FEATURE_MPIDR);
@@ -911,6 +912,7 @@ static void arm1176_initfn(Object *obj)
 
     cpu->dtb_compatible = "arm,arm1176";
     set_feature(&cpu->env, ARM_FEATURE_V6K);
+    set_feature(&cpu->env, ARM_FEATURE_VBAR);
     set_feature(&cpu->env, ARM_FEATURE_VFP);
     set_feature(&cpu->env, ARM_FEATURE_VAPA);
     set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index ca5c849ed65e..c6841df8afb9 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1125,6 +1125,7 @@ enum arm_features {
     ARM_FEATURE_V8_PMULL, /* implements PMULL part of v8 Crypto Extensions */
     ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */
     ARM_FEATURE_PMU, /* has PMU support */
+    ARM_FEATURE_VBAR, /* has cp15 VBAR (ARM1176) */
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index b5b65caadf8a..9bfffa4a4b60 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1252,12 +1252,6 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
       .access = PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS,
       .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
       .writefn = pmintenclr_write },
-    { .name = "VBAR", .state = ARM_CP_STATE_BOTH,
-      .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
-      .access = PL1_RW, .writefn = vbar_write,
-      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
-                             offsetof(CPUARMState, cp15.vbar_ns) },
-      .resetvalue = 0 },
     { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
       .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
       .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
@@ -1411,6 +1405,15 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
       .resetvalue = 0 },
     REGINFO_SENTINEL
 };
+static const ARMCPRegInfo vbar_cp_reginfo[] = {
+    { .name = "VBAR", .state = ARM_CP_STATE_BOTH,
+      .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
+      .access = PL1_RW, .writefn = vbar_write,
+      .bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
+                             offsetof(CPUARMState, cp15.vbar_ns) },
+      .resetvalue = 0 },
+    REGINFO_SENTINEL
+};
 
 #ifndef CONFIG_USER_ONLY
 
@@ -4506,6 +4509,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
     if (arm_feature(env, ARM_FEATURE_V6K)) {
         define_arm_cp_regs(cpu, v6k_cp_reginfo);
     }
+    if (arm_feature(env, ARM_FEATURE_VBAR)) {
+        define_arm_cp_regs(cpu, vbar_cp_reginfo);
+    }
     if (arm_feature(env, ARM_FEATURE_V7MP) &&
         !arm_feature(env, ARM_FEATURE_MPU)) {
         define_arm_cp_regs(cpu, v7mp_cp_reginfo);
-- 
2.7.4



More information about the openbmc mailing list