diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/cpu.c | 36 | ||||
-rw-r--r-- | target/arm/cpu.h | 13 | ||||
-rw-r--r-- | target/arm/machine.c | 29 |
3 files changed, 66 insertions, 12 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 41ae6ba3c2..8b610ded23 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -228,17 +228,25 @@ static void arm_cpu_reset(CPUState *s) env->vfp.xregs[ARM_VFP_FPEXC] = 0; #endif - if (arm_feature(env, ARM_FEATURE_PMSA) && - arm_feature(env, ARM_FEATURE_V7)) { + if (arm_feature(env, ARM_FEATURE_PMSA)) { if (cpu->pmsav7_dregion > 0) { - memset(env->pmsav7.drbar, 0, - sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion); - memset(env->pmsav7.drsr, 0, - sizeof(*env->pmsav7.drsr) * cpu->pmsav7_dregion); - memset(env->pmsav7.dracr, 0, - sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion); + if (arm_feature(env, ARM_FEATURE_V8)) { + memset(env->pmsav8.rbar, 0, + sizeof(*env->pmsav8.rbar) * cpu->pmsav7_dregion); + memset(env->pmsav8.rlar, 0, + sizeof(*env->pmsav8.rlar) * cpu->pmsav7_dregion); + } else if (arm_feature(env, ARM_FEATURE_V7)) { + memset(env->pmsav7.drbar, 0, + sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion); + memset(env->pmsav7.drsr, 0, + sizeof(*env->pmsav7.drsr) * cpu->pmsav7_dregion); + memset(env->pmsav7.dracr, 0, + sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion); + } } env->pmsav7.rnr = 0; + env->pmsav8.mair0 = 0; + env->pmsav8.mair1 = 0; } set_flush_to_zero(1, &env->vfp.standard_fp_status); @@ -809,9 +817,15 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) } if (nr) { - env->pmsav7.drbar = g_new0(uint32_t, nr); - env->pmsav7.drsr = g_new0(uint32_t, nr); - env->pmsav7.dracr = g_new0(uint32_t, nr); + if (arm_feature(env, ARM_FEATURE_V8)) { + /* PMSAv8 */ + env->pmsav8.rbar = g_new0(uint32_t, nr); + env->pmsav8.rlar = g_new0(uint32_t, nr); + } else { + env->pmsav7.drbar = g_new0(uint32_t, nr); + env->pmsav7.drsr = g_new0(uint32_t, nr); + env->pmsav7.dracr = g_new0(uint32_t, nr); + } } } diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 92771d3790..9fd5de7313 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -522,6 +522,19 @@ typedef struct CPUARMState { uint32_t rnr; } pmsav7; + /* PMSAv8 MPU */ + struct { + /* The PMSAv8 implementation also shares some PMSAv7 config + * and state: + * pmsav7.rnr (region number register) + * pmsav7_dregion (number of configured regions) + */ + uint32_t *rbar; + uint32_t *rlar; + uint32_t mair0; + uint32_t mair1; + } pmsav8; + void *nvic; const struct arm_boot_info *boot_info; /* Store GICv3CPUState to access from this struct */ diff --git a/target/arm/machine.c b/target/arm/machine.c index 3193b00b04..7b6f9dec6b 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -159,7 +159,8 @@ static bool pmsav7_needed(void *opaque) CPUARMState *env = &cpu->env; return arm_feature(env, ARM_FEATURE_PMSA) && - arm_feature(env, ARM_FEATURE_V7); + arm_feature(env, ARM_FEATURE_V7) && + !arm_feature(env, ARM_FEATURE_V8); } static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id) @@ -209,6 +210,31 @@ static const VMStateDescription vmstate_pmsav7_rnr = { } }; +static bool pmsav8_needed(void *opaque) +{ + ARMCPU *cpu = opaque; + CPUARMState *env = &cpu->env; + + return arm_feature(env, ARM_FEATURE_PMSA) && + arm_feature(env, ARM_FEATURE_V8); +} + +static const VMStateDescription vmstate_pmsav8 = { + .name = "cpu/pmsav8", + .version_id = 1, + .minimum_version_id = 1, + .needed = pmsav8_needed, + .fields = (VMStateField[]) { + VMSTATE_VARRAY_UINT32(env.pmsav8.rbar, ARMCPU, pmsav7_dregion, 0, + vmstate_info_uint32, uint32_t), + VMSTATE_VARRAY_UINT32(env.pmsav8.rlar, ARMCPU, pmsav7_dregion, 0, + vmstate_info_uint32, uint32_t), + VMSTATE_UINT32(env.pmsav8.mair0, ARMCPU), + VMSTATE_UINT32(env.pmsav8.mair1, ARMCPU), + VMSTATE_END_OF_LIST() + } +}; + static int get_cpsr(QEMUFile *f, void *opaque, size_t size, VMStateField *field) { @@ -458,6 +484,7 @@ const VMStateDescription vmstate_arm_cpu = { */ &vmstate_pmsav7_rnr, &vmstate_pmsav7, + &vmstate_pmsav8, NULL } }; |