summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/faults.cc31
-rw-r--r--src/arch/arm/faults.hh14
2 files changed, 31 insertions, 14 deletions
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
index 27894e0c1..e3488f428 100644
--- a/src/arch/arm/faults.cc
+++ b/src/arch/arm/faults.cc
@@ -350,7 +350,7 @@ ArmFault::getVector64(ThreadContext *tc)
panic("Invalid target exception level");
break;
}
- return vbar + offset64();
+ return vbar + offset64(tc);
}
MiscRegIndex
@@ -654,6 +654,8 @@ ArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst)
ret_addr += spsr.t ? thumbPcElrOffset() : armPcElrOffset();
tc->setMiscReg(elr_idx, ret_addr);
+ Addr vec_address = getVector64(tc);
+
// Update process state
OperatingMode64 mode = 0;
mode.spX = 1;
@@ -666,7 +668,7 @@ ArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst)
tc->setMiscReg(MISCREG_CPSR, cpsr);
// Set PC to start of exception handler
- Addr new_pc = purifyTaggedAddr(getVector64(tc), tc, toEL);
+ Addr new_pc = purifyTaggedAddr(vec_address, tc, toEL);
DPRINTF(Faults, "Invoking Fault (AArch64 target EL):%s cpsr:%#x PC:%#x "
"elr:%#x newVec: %#x\n", name(), cpsr, curr_pc, ret_addr, new_pc);
PCState pc(new_pc);
@@ -893,6 +895,31 @@ ArmFaultVals<T>::offset(ThreadContext *tc)
return isHypTrap ? 0x14 : vals.offset;
}
+template<class T>
+FaultOffset
+ArmFaultVals<T>::offset64(ThreadContext *tc)
+{
+ if (toEL == fromEL) {
+ if (opModeIsT(fromMode))
+ return vals.currELTOffset;
+ return vals.currELHOffset;
+ } else {
+ bool lower_32 = false;
+ if (toEL == EL3) {
+ if (!inSecureState(tc) && ArmSystem::haveEL(tc, EL2))
+ lower_32 = ELIs32(tc, EL2);
+ else
+ lower_32 = ELIs32(tc, EL1);
+ } else {
+ lower_32 = ELIs32(tc, static_cast<ExceptionLevel>(toEL - 1));
+ }
+
+ if (lower_32)
+ return vals.lowerEL32Offset;
+ return vals.lowerEL64Offset;
+ }
+}
+
// void
// SupervisorCall::setSyndrome64(ThreadContext *tc, MiscRegIndex esr_idx)
// {
diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh
index bec2c0e8f..6ae4c067e 100644
--- a/src/arch/arm/faults.hh
+++ b/src/arch/arm/faults.hh
@@ -191,7 +191,7 @@ class ArmFault : public FaultBase
virtual void annotate(AnnotationIDs id, uint64_t val) {}
virtual FaultStat& countStat() = 0;
virtual FaultOffset offset(ThreadContext *tc) = 0;
- virtual FaultOffset offset64() = 0;
+ virtual FaultOffset offset64(ThreadContext *tc) = 0;
virtual OperatingMode nextMode() = 0;
virtual bool routeToMonitor(ThreadContext *tc) const = 0;
virtual bool routeToHyp(ThreadContext *tc) const { return false; }
@@ -221,17 +221,7 @@ class ArmFaultVals : public ArmFault
FaultStat & countStat() override { return vals.count; }
FaultOffset offset(ThreadContext *tc) override;
- FaultOffset offset64() override {
- if (toEL == fromEL) {
- if (opModeIsT(fromMode))
- return vals.currELTOffset;
- return vals.currELHOffset;
- } else {
- if (from64)
- return vals.lowerEL64Offset;
- return vals.lowerEL32Offset;
- }
- }
+ FaultOffset offset64(ThreadContext *tc) override;
OperatingMode nextMode() override { return vals.nextMode; }
virtual bool routeToMonitor(ThreadContext *tc) const override {