diff options
Diffstat (limited to 'target/arm/cpu.h')
-rw-r--r-- | target/arm/cpu.h | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 5932ef1e22..92771d3790 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -416,8 +416,10 @@ typedef struct CPUARMState { uint32_t dfsr; /* Debug Fault Status Register */ uint32_t mmfar; /* MemManage Fault Address */ uint32_t bfar; /* BusFault Address */ - unsigned mpu_ctrl; /* MPU_CTRL (some bits kept in sctlr_el[1]) */ + unsigned mpu_ctrl; /* MPU_CTRL */ int exception; + uint32_t primask; + uint32_t faultmask; } v7m; /* Information associated with an exception about to be taken: @@ -583,6 +585,8 @@ struct ARMCPU { qemu_irq gt_timer_outputs[NUM_GTIMERS]; /* GPIO output for GICv3 maintenance interrupt signal */ qemu_irq gicv3_maintenance_interrupt; + /* GPIO output for the PMU interrupt */ + qemu_irq pmu_interrupt; /* MemoryRegion to use for secure physical accesses */ MemoryRegion *secure_memory; @@ -882,6 +886,22 @@ void pmccntr_sync(CPUARMState *env); /* Mask of bits which may be set by exception return copying them from SPSR */ #define CPSR_ERET_MASK (~CPSR_RESERVED) +/* Bit definitions for M profile XPSR. Most are the same as CPSR. */ +#define XPSR_EXCP 0x1ffU +#define XPSR_SPREALIGN (1U << 9) /* Only set in exception stack frames */ +#define XPSR_IT_2_7 CPSR_IT_2_7 +#define XPSR_GE CPSR_GE +#define XPSR_SFPA (1U << 20) /* Only set in exception stack frames */ +#define XPSR_T (1U << 24) /* Not the same as CPSR_T ! */ +#define XPSR_IT_0_1 CPSR_IT_0_1 +#define XPSR_Q CPSR_Q +#define XPSR_V CPSR_V +#define XPSR_C CPSR_C +#define XPSR_Z CPSR_Z +#define XPSR_N CPSR_N +#define XPSR_NZCV CPSR_NZCV +#define XPSR_IT CPSR_IT + #define TTBCR_N (7U << 0) /* TTBCR.EAE==0 */ #define TTBCR_T0SZ (7U << 0) /* TTBCR.EAE==1 */ #define TTBCR_PD0 (1U << 4) @@ -986,26 +1006,28 @@ static inline uint32_t xpsr_read(CPUARMState *env) /* Set the xPSR. Note that some bits of mask must be all-set or all-clear. */ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) { - if (mask & CPSR_NZCV) { - env->ZF = (~val) & CPSR_Z; + if (mask & XPSR_NZCV) { + env->ZF = (~val) & XPSR_Z; env->NF = val; env->CF = (val >> 29) & 1; env->VF = (val << 3) & 0x80000000; } - if (mask & CPSR_Q) - env->QF = ((val & CPSR_Q) != 0); - if (mask & (1 << 24)) - env->thumb = ((val & (1 << 24)) != 0); - if (mask & CPSR_IT_0_1) { + if (mask & XPSR_Q) { + env->QF = ((val & XPSR_Q) != 0); + } + if (mask & XPSR_T) { + env->thumb = ((val & XPSR_T) != 0); + } + if (mask & XPSR_IT_0_1) { env->condexec_bits &= ~3; env->condexec_bits |= (val >> 25) & 3; } - if (mask & CPSR_IT_2_7) { + if (mask & XPSR_IT_2_7) { env->condexec_bits &= 3; env->condexec_bits |= (val >> 8) & 0xfc; } - if (mask & 0x1ff) { - env->v7m.exception = val & 0x1ff; + if (mask & XPSR_EXCP) { + env->v7m.exception = val & XPSR_EXCP; } } @@ -1609,13 +1631,19 @@ static inline int arm_highest_el(CPUARMState *env) return 1; } +/* Return true if a v7M CPU is in Handler mode */ +static inline bool arm_v7m_is_handler_mode(CPUARMState *env) +{ + return env->v7m.exception != 0; +} + /* Return the current Exception Level (as per ARMv8; note that this differs * from the ARMv7 Privilege Level). */ static inline int arm_current_el(CPUARMState *env) { if (arm_feature(env, ARM_FEATURE_M)) { - return !((env->v7m.exception == 0) && (env->v7m.control & 1)); + return arm_v7m_is_handler_mode(env) || !(env->v7m.control & 1); } if (is_a64(env)) { @@ -2160,7 +2188,7 @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch) * we're in a HardFault or NMI handler. */ if ((env->v7m.exception > 0 && env->v7m.exception <= 3) - || env->daif & PSTATE_F) { + || env->v7m.faultmask) { return arm_to_core_mmu_idx(ARMMMUIdx_MNegPri); } @@ -2615,7 +2643,7 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, } *flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT; - if (env->v7m.exception != 0) { + if (arm_v7m_is_handler_mode(env)) { *flags |= ARM_TBFLAG_HANDLER_MASK; } |