summaryrefslogtreecommitdiffstats
path: root/target/arm/cpu.h
diff options
context:
space:
mode:
authorPeter Maydell2017-06-02 12:51:47 +0200
committerPeter Maydell2017-06-02 12:51:47 +0200
commite7b921c2d9efc249f99b9feb0e7dca82c96aa5c4 (patch)
tree2407de57c50fd9d94f85b6bdc21efd9d6d7e8b57 /target/arm/cpu.h
parentarm: Add support for M profile CPUs having different MMU index semantics (diff)
downloadqemu-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.h21
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);
}