target-arm: Convert MPIDR

Convert the MPIDR to the new cp15 register scheme.
This includes giving it its own feature bit rather
than doing a CPUID value check.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index f4c9116..0c031ba 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -162,6 +162,7 @@
     if (arm_feature(env, ARM_FEATURE_V7)) {
         set_feature(env, ARM_FEATURE_VAPA);
         set_feature(env, ARM_FEATURE_THUMB2);
+        set_feature(env, ARM_FEATURE_MPIDR);
         if (!arm_feature(env, ARM_FEATURE_M)) {
             set_feature(env, ARM_FEATURE_V6K);
         } else {
@@ -350,6 +351,7 @@
     set_feature(&cpu->env, ARM_FEATURE_V6K);
     set_feature(&cpu->env, ARM_FEATURE_VFP);
     set_feature(&cpu->env, ARM_FEATURE_VAPA);
+    set_feature(&cpu->env, ARM_FEATURE_MPIDR);
     set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
     cpu->midr = ARM_CPUID_ARM11MPCORE;
     cpu->reset_fpsid = 0x410120b4;
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 0b984d8..2630fe7 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -386,6 +386,7 @@
     ARM_FEATURE_CACHE_TEST_CLEAN, /* 926/1026 style test-and-clean ops */
     ARM_FEATURE_CACHE_DIRTY_REG, /* 1136/1176 cache dirty status register */
     ARM_FEATURE_CACHE_BLOCK_OPS, /* v6 optional cache block operations */
+    ARM_FEATURE_MPIDR, /* has cp15 MPIDR */
 };
 
 static inline int arm_feature(CPUARMState *env, int feature)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 269740d..1acc212 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -833,6 +833,31 @@
     REGINFO_SENTINEL
 };
 
+static int mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
+                      uint64_t *value)
+{
+    uint32_t mpidr = env->cpu_index;
+    /* We don't support setting cluster ID ([8..11])
+     * so these bits always RAZ.
+     */
+    if (arm_feature(env, ARM_FEATURE_V7MP)) {
+        mpidr |= (1 << 31);
+        /* Cores which are uniprocessor (non-coherent)
+         * but still implement the MP extensions set
+         * bit 30. (For instance, A9UP.) However we do
+         * not currently model any of those cores.
+         */
+    }
+    *value = mpidr;
+    return 0;
+}
+
+static const ARMCPRegInfo mpidr_cp_reginfo[] = {
+    { .name = "MPIDR", .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
+      .access = PL1_R, .readfn = mpidr_read },
+    REGINFO_SENTINEL
+};
+
 static int sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
 {
     env->cp15.c1_sys = value;
@@ -975,6 +1000,9 @@
     if (arm_feature(env, ARM_FEATURE_DUMMY_C15_REGS)) {
         define_arm_cp_regs(cpu, dummy_c15_cp_reginfo);
     }
+    if (arm_feature(env, ARM_FEATURE_MPIDR)) {
+        define_arm_cp_regs(cpu, mpidr_cp_reginfo);
+    }
     if (arm_feature(env, ARM_FEATURE_AUXCR)) {
         ARMCPRegInfo auxcr = {
             .name = "AUXCR", .cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1,
@@ -2121,28 +2149,6 @@
                     return 0;
                 case 3: /* TLB type register.  */
                     return 0; /* No lockable TLB entries.  */
-                case 5: /* MPIDR */
-                    /* The MPIDR was standardised in v7; prior to
-                     * this it was implemented only in the 11MPCore.
-                     * For all other pre-v7 cores it does not exist.
-                     */
-                    if (arm_feature(env, ARM_FEATURE_V7) ||
-                        ARM_CPUID(env) == ARM_CPUID_ARM11MPCORE) {
-                        int mpidr = env->cpu_index;
-                        /* We don't support setting cluster ID ([8..11])
-                         * so these bits always RAZ.
-                         */
-                        if (arm_feature(env, ARM_FEATURE_V7MP)) {
-                            mpidr |= (1 << 31);
-                            /* Cores which are uniprocessor (non-coherent)
-                             * but still implement the MP extensions set
-                             * bit 30. (For instance, A9UP.) However we do
-                             * not currently model any of those cores.
-                             */
-                        }
-                        return mpidr;
-                    }
-                    /* otherwise fall through to the unimplemented-reg case */
                 default:
                     goto bad_reg;
                 }