summaryrefslogtreecommitdiffstats
path: root/target/arm/helper.c
diff options
context:
space:
mode:
authorPeter Maydell2018-10-24 08:50:18 +0200
committerPeter Maydell2018-10-24 08:51:36 +0200
commit2ed08180db096ea5e44573529b85e09b1ed10b08 (patch)
tree362f56c4e983d26ab6cc83ff2577ec41950392bd /target/arm/helper.c
parenttarget/arm: New utility function to extract EC from syndrome (diff)
downloadqemu-2ed08180db096ea5e44573529b85e09b1ed10b08.tar.gz
qemu-2ed08180db096ea5e44573529b85e09b1ed10b08.tar.xz
qemu-2ed08180db096ea5e44573529b85e09b1ed10b08.zip
target/arm: Get IL bit correct for v7 syndrome values
For the v7 version of the Arm architecture, the IL bit in syndrome register values where the field is not valid was defined to be UNK/SBZP. In v8 this is RES1, which is what QEMU currently implements. Handle the desired v7 behaviour by squashing the IL bit for the affected cases: * EC == EC_UNCATEGORIZED * prefetch aborts * data aborts where ISV is 0 (The fourth case listed in the v8 Arm ARM DDI 0487C.a in section G7.2.70, "illegal state exception", can't happen on a v7 CPU.) This deals with a corner case noted in a comment. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20181012144235.19646-10-peter.maydell@linaro.org
Diffstat (limited to 'target/arm/helper.c')
-rw-r--r--target/arm/helper.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 87f66b818c..e4e231de19 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8302,6 +8302,19 @@ static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
}
if (cs->exception_index != EXCP_IRQ && cs->exception_index != EXCP_FIQ) {
+ if (!arm_feature(env, ARM_FEATURE_V8)) {
+ /*
+ * QEMU syndrome values are v8-style. v7 has the IL bit
+ * UNK/SBZP for "field not valid" cases, where v8 uses RES1.
+ * If this is a v7 CPU, squash the IL bit in those cases.
+ */
+ if (cs->exception_index == EXCP_PREFETCH_ABORT ||
+ (cs->exception_index == EXCP_DATA_ABORT &&
+ !(env->exception.syndrome & ARM_EL_ISV)) ||
+ syn_get_ec(env->exception.syndrome) == EC_UNCATEGORIZED) {
+ env->exception.syndrome &= ~ARM_EL_IL;
+ }
+ }
env->cp15.esr_el[2] = env->exception.syndrome;
}