aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/arm/cpu.c14
-rw-r--r--target/arm/helper.c45
2 files changed, 36 insertions, 23 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 258ba6dcaa..b5e61cc177 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -199,8 +199,18 @@ static void arm_cpu_reset(CPUState *s)
env->cp15.c15_cpar = 1;
}
#else
- /* SVC mode with interrupts disabled. */
- env->uncached_cpsr = ARM_CPU_MODE_SVC;
+
+ /*
+ * If the highest available EL is EL2, AArch32 will start in Hyp
+ * mode; otherwise it starts in SVC. Note that if we start in
+ * AArch64 then these values in the uncached_cpsr will be ignored.
+ */
+ if (arm_feature(env, ARM_FEATURE_EL2) &&
+ !arm_feature(env, ARM_FEATURE_EL3)) {
+ env->uncached_cpsr = ARM_CPU_MODE_HYP;
+ } else {
+ env->uncached_cpsr = ARM_CPU_MODE_SVC;
+ }
env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F;
if (arm_feature(env, ARM_FEATURE_M)) {
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 088f452716..64b1564594 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -12587,36 +12587,39 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
uint32_t flags;
if (is_a64(env)) {
- int sve_el = sve_exception_el(env);
- uint32_t zcr_len;
-
*pc = env->pc;
flags = ARM_TBFLAG_AARCH64_STATE_MASK;
/* Get control bits for tagged addresses */
flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
- flags |= sve_el << ARM_TBFLAG_SVEEXC_EL_SHIFT;
- /* If SVE is disabled, but FP is enabled,
- then the effective len is 0. */
- if (sve_el != 0 && fp_el == 0) {
- zcr_len = 0;
- } else {
- int current_el = arm_current_el(env);
- ARMCPU *cpu = arm_env_get_cpu(env);
+ if (arm_feature(env, ARM_FEATURE_SVE)) {
+ int sve_el = sve_exception_el(env);
+ uint32_t zcr_len;
- zcr_len = cpu->sve_max_vq - 1;
- if (current_el <= 1) {
- zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[1]);
- }
- if (current_el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
- zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
- }
- if (current_el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
- zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
+ /* If SVE is disabled, but FP is enabled,
+ * then the effective len is 0.
+ */
+ if (sve_el != 0 && fp_el == 0) {
+ zcr_len = 0;
+ } else {
+ int current_el = arm_current_el(env);
+ ARMCPU *cpu = arm_env_get_cpu(env);
+
+ zcr_len = cpu->sve_max_vq - 1;
+ if (current_el <= 1) {
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[1]);
+ }
+ if (current_el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
+ }
+ if (current_el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
+ }
}
+ flags |= sve_el << ARM_TBFLAG_SVEEXC_EL_SHIFT;
+ flags |= zcr_len << ARM_TBFLAG_ZCR_LEN_SHIFT;
}
- flags |= zcr_len << ARM_TBFLAG_ZCR_LEN_SHIFT;
} else {
*pc = env->regs[15];
flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)