From 1acd9efdc26fb38d5588bae538084403530ec9a1 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Sun, 4 Mar 2018 20:45:39 -0500 Subject: [PATCH] target/arm: Implement ARMv8M's PMSAv8 registers As part of ARMv8M, we need to add support for the PMSAv8 MPU architecture. PMSAv8 differs from PMSAv7 both in register/data layout (for instance using base and limit registers rather than base and size) and also in behaviour (for example it does not have subregions); rather than trying to wedge it into the existing PMSAv7 code and data structures, we define separate ones. This commit adds the data structures which hold the state for a PMSAv8 MPU and the register interface to it. The implementation of the MPU behaviour will be added in a subsequent commit. Backports commit 0e1a46bbd2d6c39614b87f4e88ea305acce8a35f from qemu --- qemu/target/arm/cpu.c | 36 +++++++++++++++++++++++++----------- qemu/target/arm/cpu.h | 13 +++++++++++++ 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/qemu/target/arm/cpu.c b/qemu/target/arm/cpu.c index 49ef739c..3b049ffb 100644 --- a/qemu/target/arm/cpu.c +++ b/qemu/target/arm/cpu.c @@ -231,17 +231,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); @@ -603,9 +611,15 @@ static int arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **err } 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/qemu/target/arm/cpu.h b/qemu/target/arm/cpu.h index 02cbd4d5..4711d9d0 100644 --- a/qemu/target/arm/cpu.h +++ b/qemu/target/arm/cpu.h @@ -529,6 +529,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;