mirror of https://gitee.com/openkylin/qemu.git
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
This commit is contained in:
parent
64b91e3f89
commit
2ed08180db
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -286,11 +286,8 @@ static inline uint32_t syn_get_ec(uint32_t syn)
|
|||
/* Utility functions for constructing various kinds of syndrome value.
|
||||
* Note that in general we follow the AArch64 syndrome values; in a
|
||||
* few cases the value in HSR for exceptions taken to AArch32 Hyp
|
||||
* mode differs slightly, so if we ever implemented Hyp mode then the
|
||||
* syndrome value would need some massaging on exception entry.
|
||||
* (One example of this is that AArch64 defaults to IL bit set for
|
||||
* exceptions which don't specifically indicate information about the
|
||||
* trapping instruction, whereas AArch32 defaults to IL bit clear.)
|
||||
* mode differs slightly, and we fix this up when populating HSR in
|
||||
* arm_cpu_do_interrupt_aarch32_hyp().
|
||||
*/
|
||||
static inline uint32_t syn_uncategorized(void)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue