diff options
Diffstat (limited to 'src/arch/arm')
-rw-r--r-- | src/arch/arm/faults.cc | 31 | ||||
-rw-r--r-- | src/arch/arm/faults.hh | 14 |
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 { |