summaryrefslogtreecommitdiff
path: root/src/arch/arm
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
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')
-rw-r--r--src/arch/arm/utility.cc37
-rw-r--r--src/arch/arm/utility.hh18
2 files changed, 44 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
diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh
index 6e4e76b75..8efe4ad10 100644
--- a/src/arch/arm/utility.hh
+++ b/src/arch/arm/utility.hh
@@ -157,6 +157,24 @@ currEL(ThreadContext *tc)
return (ExceptionLevel) (uint8_t) cpsr.el;
}
+/**
+ * This function checks whether selected EL provided as an argument
+ * is using the AArch32 ISA. This information might be unavailable
+ * at the current EL status: it hence returns a pair of boolean values:
+ * a first boolean, true if information is available (known),
+ * and a second one, true if EL is using AArch32, false for AArch64.
+ *
+ * @param tc The thread context.
+ * @param el The target exception level.
+ * @retval known is FALSE for EL0 if the current Exception level
+ * is not EL0 and EL1 is using AArch64, since it cannot
+ * determine the state of EL0; TRUE otherwise.
+ * @retval aarch32 is TRUE if the specified Exception level is using AArch32;
+ * FALSE otherwise.
+ */
+std::pair<bool, bool>
+ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el);
+
bool ELIs32(ThreadContext *tc, ExceptionLevel el);
bool ELIs64(ThreadContext *tc, ExceptionLevel el);