summaryrefslogtreecommitdiff
path: root/src/arch/arm
diff options
context:
space:
mode:
authorGiacomo Travaglini <giacomo.travaglini@arm.com>2017-12-19 10:18:13 +0000
committerGiacomo Travaglini <giacomo.travaglini@arm.com>2018-02-08 09:48:02 +0000
commitad36e61ce400deaddfb07e71b13aea8a74b52550 (patch)
tree5268efd73e5369b1f98bdf492125424199bc1922 /src/arch/arm
parentb885dc68a26e0c7a401ca4b338d997ac577847a8 (diff)
downloadgem5-ad36e61ce400deaddfb07e71b13aea8a74b52550.tar.xz
arch-arm: Don't change PSTATE in Illegal Exception return
This patch fixes the Illegal Exception return handler. According to the armarm documentation, when PSTATE.IL is set to one because of an illegal exception return, PSTATE.{EL, nRW, SP} are unchanged. This means the Exception level, Execution state, and stack pointer selection do not change as a result of the return. Change-Id: I35f2fe68fb2822a54fc4a21930871eab7a1aaab4 Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/8021 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Diffstat (limited to 'src/arch/arm')
-rw-r--r--src/arch/arm/insts/static_inst.cc10
-rw-r--r--src/arch/arm/isa.cc2
2 files changed, 11 insertions, 1 deletions
diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc
index aace1de2b..a7ba91e03 100644
--- a/src/arch/arm/insts/static_inst.cc
+++ b/src/arch/arm/insts/static_inst.cc
@@ -1018,7 +1018,17 @@ ArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr) const
new_cpsr.ss = 0;
if (illegalExceptionReturn(tc, cpsr, spsr)) {
+ // If the SPSR specifies an illegal exception return,
+ // then PSTATE.{M, nRW, EL, SP} are unchanged and PSTATE.IL
+ // is set to 1.
new_cpsr.il = 1;
+ if (cpsr.width) {
+ new_cpsr.mode = cpsr.mode;
+ } else {
+ new_cpsr.width = cpsr.width;
+ new_cpsr.el = cpsr.el;
+ new_cpsr.sp = cpsr.sp;
+ }
} else {
new_cpsr.il = spsr.il;
if (spsr.width && badMode32((OperatingMode)(uint8_t)spsr.mode)) {
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index c917abacf..5d34e188a 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -726,7 +726,7 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
CPSR old_cpsr = miscRegs[MISCREG_CPSR];
int old_mode = old_cpsr.mode;
CPSR cpsr = val;
- if (old_mode != cpsr.mode) {
+ if (old_mode != cpsr.mode || cpsr.il != old_cpsr.il) {
getITBPtr(tc)->invalidateMiscReg();
getDTBPtr(tc)->invalidateMiscReg();
}