diff options
Diffstat (limited to 'target-arm/helper.c')
-rw-r--r-- | target-arm/helper.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c index 3cf91818b9..d46defc118 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1608,12 +1608,28 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn) return 0; case 3: /* TLB type register. */ return 0; /* No lockable TLB entries. */ - case 5: /* CPU ID */ - if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) { - return env->cpu_index | 0x80000900; - } else { - return env->cpu_index; + 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; } |