uint32_t value;
uint32_t exc_class = (uint32_t) ec(tc);
uint32_t issVal = iss();
+
assert(!from64 || ArmSystem::highestELIs64(tc));
value = exc_class << 26;
from64 = true;
// Determine target exception level
- if (ArmSystem::haveSecurity(tc) && routeToMonitor(tc))
+ if (ArmSystem::haveSecurity(tc) && routeToMonitor(tc)) {
toEL = EL3;
- else if (ArmSystem::haveVirtualization(tc) && routeToHyp(tc))
+ } else if (ArmSystem::haveVirtualization(tc) && routeToHyp(tc)) {
toEL = EL2;
- else
+ hypRouted = true;
+ } else {
toEL = opModeToEL(nextMode());
+ }
+
if (fromEL > toEL)
toEL = fromEL;
armInst->annotateFault(this);
}
- if (have_security && routeToMonitor(tc))
+ if (have_security && routeToMonitor(tc)) {
cpsr.mode = MODE_MON;
- else if (have_virtualization && routeToHyp(tc))
+ } else if (have_virtualization && routeToHyp(tc)) {
cpsr.mode = MODE_HYP;
- else
+ hypRouted = true;
+ } else {
cpsr.mode = nextMode();
+ }
// Ensure Secure state if initially in Monitor mode
if (have_security && saved_cpsr.mode == MODE_MON) {
uint32_t
UndefinedInstruction::iss() const
{
+
+ // If UndefinedInstruction is routed to hypervisor, iss field is 0.
+ if (hypRouted) {
+ return 0;
+ }
+
if (overrideEc == EC_INVALID)
return issRaw;
ExceptionClass
UndefinedInstruction::ec(ThreadContext *tc) const
{
- return (overrideEc != EC_INVALID) ? overrideEc : vals.ec;
+ // If UndefinedInstruction is routed to hypervisor,
+ // HSR.EC field is 0.
+ if (hypRouted)
+ return EC_UNKNOWN;
+ else
+ return (overrideEc != EC_INVALID) ? overrideEc : vals.ec;
}
ExceptionLevel toEL; // Target exception level
OperatingMode fromMode; // Source operating mode
+ bool hypRouted; // True if the fault has been routed to Hypervisor
+
Addr getVector(ThreadContext *tc);
Addr getVector64(ThreadContext *tc);
ArmFault(ExtMachInst _machInst = 0, uint32_t _iss = 0) :
machInst(_machInst), issRaw(_iss), from64(false), to64(false),
- fromEL(EL0), toEL(EL0), fromMode(MODE_UNDEFINED) {}
+ fromEL(EL0), toEL(EL0), fromMode(MODE_UNDEFINED), hypRouted(false) {}
// Returns the actual syndrome register to use based on the target
// exception level