summaryrefslogtreecommitdiff
path: root/src/arch/arm/utility.cc
diff options
context:
space:
mode:
authorGiacomo Travaglini <giacomo.travaglini@arm.com>2018-01-03 11:01:17 +0000
committerGiacomo Travaglini <giacomo.travaglini@arm.com>2018-02-07 15:06:50 +0000
commit465705e18087a22caec9cacc2c538a86014aff19 (patch)
treebc8616b6f6680cf8a8f48afc244faeb4740508ce /src/arch/arm/utility.cc
parentd7062b1273dfcfac0690dff88470c4ebf28f09c1 (diff)
downloadgem5-465705e18087a22caec9cacc2c538a86014aff19.tar.xz
arch-arm: ELUsingAArch32K from armarm pseudocode
This patch implements the ELUsingAArch32K pseudocode, which is returning true if the provided Exception Level is using A32 ISA, but it is not panicking (quitting simulation) if the information is unknown (see documentation). The panicking is the current behaviour of the ELIs32 utility in gem5. Change-Id: Iad7b56077d7e0f8ee223b5b9593cb8097f26bb29 Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com> Reviewed-on: https://gem5-review.googlesource.com/7222 Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Diffstat (limited to 'src/arch/arm/utility.cc')
-rw-r--r--src/arch/arm/utility.cc37
1 files changed, 26 insertions, 11 deletions
diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc
index a49f82971..4e99d980e 100644
--- a/src/arch/arm/utility.cc
+++ b/src/arch/arm/utility.cc
@@ -243,20 +243,31 @@ ELIs64(ThreadContext *tc, ExceptionLevel el)
bool
ELIs32(ThreadContext *tc, ExceptionLevel el)
{
- // Return true if the specified EL is in aarch32 state.
+ bool known, aarch32;
+ std::tie(known, aarch32) = ELUsingAArch32K(tc, el);
+ panic_if(!known, "EL state is UNKNOWN");
+ return aarch32;
+}
+std::pair<bool, bool>
+ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el)
+{
+ // Return true if the specified EL is in aarch32 state.
const bool have_el3 = ArmSystem::haveSecurity(tc);
const bool have_el2 = ArmSystem::haveVirtualization(tc);
panic_if(el == EL2 && !have_el2, "Asking for EL2 when it doesn't exist");
panic_if(el == EL3 && !have_el3, "Asking for EL3 when it doesn't exist");
- if (ArmSystem::highestELIs64(tc)
- && ArmSystem::highestEL(tc) == el) {
- return false;
+ bool known, aarch32;
+ known = aarch32 = false;
+ if (ArmSystem::highestELIs64(tc) && ArmSystem::highestEL(tc) == el) {
+ // Target EL is the highest one in a system where
+ // the highest is using AArch64.
+ known = true; aarch32 = false;
} else if (!ArmSystem::highestELIs64(tc)) {
- // All levels are using AArch32
- return true;
+ // All ELs are using AArch32:
+ known = true; aarch32 = true;
} else {
SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
bool aarch32_below_el3 = (have_el3 && scr.rw == 0);
@@ -268,15 +279,19 @@ ELIs32(ThreadContext *tc, ExceptionLevel el)
// Only know if EL0 using AArch32 from PSTATE
if (el == EL0 && !aarch32_at_el1) {
- CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
- panic_if(cpsr.el != EL0, "EL0 state is UNKNOWN");
// EL0 controlled by PSTATE
- return cpsr.width != 0;
+ CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
+
+ known = (cpsr.el == EL0);
+ aarch32 = (cpsr.width == 1);
} else {
- return (aarch32_below_el3 && el != EL3)
- || (aarch32_at_el1 && (el == EL0 || el == EL1) );
+ known = true;
+ aarch32 = (aarch32_below_el3 && el != EL3)
+ || (aarch32_at_el1 && (el == EL0 || el == EL1) );
}
}
+
+ return std::make_pair(known, aarch32);
}
bool