From 78024e6b026fecc780e503aa246beeb10dcc26d9 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Wed, 3 Jan 2018 11:02:00 +0000 Subject: 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 Reviewed-by: Nikos Nikoleris Reviewed-on: https://gem5-review.googlesource.com/7223 Maintainer: Andreas Sandberg --- src/arch/arm/insts/static_inst.cc | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'src/arch/arm/insts') 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); } -- cgit v1.2.3