diff options
author | Giacomo Travaglini <giacomo.travaglini@arm.com> | 2018-01-03 11:02:00 +0000 |
---|---|---|
committer | Giacomo Travaglini <giacomo.travaglini@arm.com> | 2018-02-07 15:06:50 +0000 |
commit | 78024e6b026fecc780e503aa246beeb10dcc26d9 (patch) | |
tree | 297b14853c7b0fa0b8c59c0f475ff1aaa908a519 | |
parent | 465705e18087a22caec9cacc2c538a86014aff19 (diff) | |
download | gem5-78024e6b026fecc780e503aa246beeb10dcc26d9.tar.xz |
arch-arm: Correct Illegal Exception Return detection
Fixed Illegal Exception Return detection, which was not
covering all the documented cases.
Change-Id: If08ddc1490d1c0a1fccee1489d116384770ce0a5
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/7223
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
-rw-r--r-- | src/arch/arm/insts/static_inst.cc | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index eeda3ad4f..61f31e5db 100644 --- a/src/arch/arm/insts/static_inst.cc +++ b/src/arch/arm/insts/static_inst.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2014, 2016-2017 ARM Limited + * Copyright (c) 2010-2014, 2016-2018 ARM Limited * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved * @@ -897,27 +897,40 @@ illegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr) const OperatingMode cur_mode = (OperatingMode) (uint8_t)cpsr.mode; const ExceptionLevel target_el = opModeToEL(mode); + + HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2)); + SCR scr = ((SCR)tc->readMiscReg(MISCREG_SCR_EL3)); + if (target_el > opModeToEL(cur_mode)) return true; - if (target_el == EL3 && !ArmSystem::haveSecurity(tc)) + if (!ArmSystem::haveEL(tc, target_el)) + return true; + + if (target_el == EL1 && ArmSystem::haveEL(tc, EL2) && scr.ns && hcr.tge) return true; - if (target_el == EL2 && !ArmSystem::haveVirtualization(tc)) + if (target_el == EL2 && ArmSystem::haveEL(tc, EL3) && !scr.ns) + return true; + + bool spsr_mode_is_aarch32 = (spsr.width == 1); + bool known, target_el_is_aarch32; + std::tie(known, target_el_is_aarch32) = ELUsingAArch32K(tc, target_el); + assert(known || (target_el == EL0 && ELIs64(tc, EL1))); + + if (known && (spsr_mode_is_aarch32 != target_el_is_aarch32)) return true; if (!spsr.width) { // aarch64 if (!ArmSystem::highestELIs64(tc)) return true; - if (spsr & 0x2) return true; if (target_el == EL0 && spsr.sp) return true; - if (target_el == EL2 && !((SCR)tc->readMiscReg(MISCREG_SCR_EL3)).ns) - return false; } else { + // aarch32 return badMode32(mode); } |