diff options
author | Peter Maydell | 2017-06-02 12:51:47 +0200 |
---|---|---|
committer | Peter Maydell | 2017-06-02 12:51:47 +0200 |
commit | e7b921c2d9efc249f99b9feb0e7dca82c96aa5c4 (patch) | |
tree | 2407de57c50fd9d94f85b6bdc21efd9d6d7e8b57 /target/arm/cpu.h | |
parent | arm: Add support for M profile CPUs having different MMU index semantics (diff) | |
download | qemu-e7b921c2d9efc249f99b9feb0e7dca82c96aa5c4.tar.gz qemu-e7b921c2d9efc249f99b9feb0e7dca82c96aa5c4.tar.xz qemu-e7b921c2d9efc249f99b9feb0e7dca82c96aa5c4.zip |
arm: Use different ARMMMUIdx values for M profile
Make M profile use completely separate ARMMMUIdx values from
those that A profile CPUs use. This is a prelude to adding
support for the MPU and for v8M, which together will require
6 MMU indexes which don't map cleanly onto the A profile
uses:
non secure User
non secure Privileged
non secure Privileged, execution priority < 0
secure User
secure Privileged
secure Privileged, execution priority < 0
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1493122030-32191-4-git-send-email-peter.maydell@linaro.org
Diffstat (limited to 'target/arm/cpu.h')
-rw-r--r-- | target/arm/cpu.h | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 4b1e98284c..cadec09ac4 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2057,8 +2057,9 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, * of the AT/ATS operations. * The values used are carefully arranged to make mmu_idx => EL lookup easy. */ -#define ARM_MMU_IDX_A 0x10 /* A profile (and M profile, for the moment) */ +#define ARM_MMU_IDX_A 0x10 /* A profile */ #define ARM_MMU_IDX_NOTLB 0x20 /* does not have a TLB */ +#define ARM_MMU_IDX_M 0x40 /* M profile */ #define ARM_MMU_IDX_TYPE_MASK (~0x7) #define ARM_MMU_IDX_COREIDX_MASK 0x7 @@ -2071,6 +2072,8 @@ typedef enum ARMMMUIdx { ARMMMUIdx_S1SE0 = 4 | ARM_MMU_IDX_A, ARMMMUIdx_S1SE1 = 5 | ARM_MMU_IDX_A, ARMMMUIdx_S2NS = 6 | ARM_MMU_IDX_A, + ARMMMUIdx_MUser = 0 | ARM_MMU_IDX_M, + ARMMMUIdx_MPriv = 1 | ARM_MMU_IDX_M, /* Indexes below here don't have TLBs and are used only for AT system * instructions or for the first stage of an S12 page table walk. */ @@ -2089,6 +2092,8 @@ typedef enum ARMMMUIdxBit { ARMMMUIdxBit_S1SE0 = 1 << 4, ARMMMUIdxBit_S1SE1 = 1 << 5, ARMMMUIdxBit_S2NS = 1 << 6, + ARMMMUIdxBit_MUser = 1 << 0, + ARMMMUIdxBit_MPriv = 1 << 1, } ARMMMUIdxBit; #define MMU_USER_IDX 0 @@ -2100,7 +2105,11 @@ static inline int arm_to_core_mmu_idx(ARMMMUIdx mmu_idx) static inline ARMMMUIdx core_to_arm_mmu_idx(CPUARMState *env, int mmu_idx) { - return mmu_idx | ARM_MMU_IDX_A; + if (arm_feature(env, ARM_FEATURE_M)) { + return mmu_idx | ARM_MMU_IDX_M; + } else { + return mmu_idx | ARM_MMU_IDX_A; + } } /* Return the exception level we're running at if this is our mmu_idx */ @@ -2109,6 +2118,8 @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx) switch (mmu_idx & ARM_MMU_IDX_TYPE_MASK) { case ARM_MMU_IDX_A: return mmu_idx & 3; + case ARM_MMU_IDX_M: + return mmu_idx & 1; default: g_assert_not_reached(); } @@ -2119,6 +2130,12 @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch) { int el = arm_current_el(env); + if (arm_feature(env, ARM_FEATURE_M)) { + ARMMMUIdx mmu_idx = el == 0 ? ARMMMUIdx_MUser : ARMMMUIdx_MPriv; + + return arm_to_core_mmu_idx(mmu_idx); + } + if (el < 2 && arm_is_secure_below_el3(env)) { return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el); } |