*/
#include "arch/arm/faults.hh"
+
+#include "arch/arm/insts/static_inst.hh"
#include "arch/arm/system.hh"
#include "arch/arm/utility.hh"
-#include "arch/arm/insts/static_inst.hh"
#include "base/compiler.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
assert(ArmSystem::haveSecurity(tc));
vbar = tc->readMiscReg(MISCREG_VBAR_EL3);
break;
- // @todo: uncomment this to enable Virtualization
- // case EL2:
- // assert(ArmSystem::haveVirtualization(tc));
- // vbar = tc->readMiscReg(MISCREG_VBAR_EL2);
- // break;
+ case EL2:
+ assert(ArmSystem::haveVirtualization(tc));
+ vbar = tc->readMiscReg(MISCREG_VBAR_EL2);
+ break;
case EL1:
vbar = tc->readMiscReg(MISCREG_VBAR_EL1);
break;
// Determine target exception level
if (ArmSystem::haveSecurity(tc) && routeToMonitor(tc))
toEL = EL3;
+ else if (ArmSystem::haveVirtualization(tc) && routeToHyp(tc))
+ toEL = EL2;
else
toEL = opModeToEL(nextMode());
if (fromEL > toEL)
elr_idx = MISCREG_ELR_EL1;
spsr_idx = MISCREG_SPSR_EL1;
break;
- // @todo: uncomment this to enable Virtualization
- // case EL2:
- // assert(ArmSystem::haveVirtualization());
- // elr_idx = MISCREG_ELR_EL2;
- // spsr_idx = MISCREG_SPSR_EL2;
- // break;
+ case EL2:
+ assert(ArmSystem::haveVirtualization(tc));
+ elr_idx = MISCREG_ELR_EL2;
+ spsr_idx = MISCREG_SPSR_EL2;
+ break;
case EL3:
assert(ArmSystem::haveSecurity(tc));
elr_idx = MISCREG_ELR_EL3;
callNum = tc->readIntReg(INTREG_X8);
else
callNum = tc->readIntReg(INTREG_R7);
- tc->syscall(callNum);
+ Fault fault;
+ tc->syscall(callNum, &fault);
// Advance the PC since that won't happen automatically.
PCState pc = tc->pcState();
ArmFaultVals<HypervisorCall>(_machInst, _imm)
{}
+ExceptionClass
+HypervisorCall::ec(ThreadContext *tc) const
+{
+ return from64 ? EC_HVC_64 : vals.ec;
+}
+
ExceptionClass
HypervisorTrap::ec(ThreadContext *tc) const
{
} else { // AArch64
// Set the FAR register. Nothing else to do if we are in AArch64 state
// because the syndrome register has already been set inside invoke64()
- tc->setMiscReg(AbortFault<T>::getFaultAddrReg64(), faultAddr);
+ if (stage2) {
+ // stage 2 fault, set HPFAR_EL2 to the faulting IPA
+ // and FAR_EL2 to the Original VA
+ tc->setMiscReg(AbortFault<T>::getFaultAddrReg64(), OVAddr);
+ tc->setMiscReg(MISCREG_HPFAR_EL2, bits(faultAddr, 47, 12) << 4);
+
+ DPRINTF(Faults, "Abort Fault (Stage 2) VA: 0x%x IPA: 0x%x\n",
+ OVAddr, faultAddr);
+ } else {
+ tc->setMiscReg(AbortFault<T>::getFaultAddrReg64(), faultAddr);
+ }
}
}
toHyp |= (stage2 ||
( (source == DebugEvent) && hdcr.tde && (cpsr.mode != MODE_HYP)) ||
( (source == SynchronousExternalAbort) && hcr.tge && (cpsr.mode == MODE_USER))
- ) && !inSecureState(scr, cpsr);
+ ) && !inSecureState(tc);
return toHyp;
}
((source == AlignmentFault) ||
(source == SynchronousExternalAbort))
)
- ) && !inSecureState(scr, cpsr);
+ ) && !inSecureState(tc);
return toHyp;
}
HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR);
CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
// Determine whether IRQs are routed to Hyp mode.
- toHyp = (!scr.irq && hcr.imo && !inSecureState(scr, cpsr)) ||
+ toHyp = (!scr.irq && hcr.imo && !inSecureState(tc)) ||
(cpsr.mode == MODE_HYP);
return toHyp;
}
HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR);
CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
// Determine whether IRQs are routed to Hyp mode.
- toHyp = (!scr.fiq && hcr.fmo && !inSecureState(scr, cpsr)) ||
+ toHyp = (!scr.fiq && hcr.fmo && !inSecureState(tc)) ||
(cpsr.mode == MODE_HYP);
return toHyp;
}
SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR);
- CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
- toHyp = (!scr.ea && hcr.amo && !inSecureState(scr, cpsr)) ||
- (!scr.ea && !scr.rw && !hcr.amo && !inSecureState(scr,cpsr));
+ toHyp = (!scr.ea && hcr.amo && !inSecureState(tc)) ||
+ (!scr.ea && !scr.rw && !hcr.amo && !inSecureState(tc));
return toHyp;
}