diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/arm/faults.cc | 65 | ||||
-rw-r--r-- | src/arch/arm/faults.hh | 6 | ||||
-rw-r--r-- | src/arch/arm/isa.cc | 2 |
3 files changed, 54 insertions, 19 deletions
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index 310545bc3..a1952d664 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -1032,13 +1032,13 @@ AbortFault<T>::invoke(ThreadContext *tc, const StaticInstPtr &inst) } // Get effective fault source encoding CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); - FSR fsr = getFsr(tc); // source must be determined BEFORE invoking generic routines which will // try to set hsr etc. and are based upon source! ArmFaultVals<T>::invoke(tc, inst); if (!this->to64) { // AArch32 + FSR fsr = getFsr(tc); if (cpsr.mode == MODE_HYP) { tc->setMiscReg(T::HFarIndex, faultAddr); } else if (stage2) { @@ -1068,33 +1068,64 @@ AbortFault<T>::invoke(ThreadContext *tc, const StaticInstPtr &inst) } template<class T> -FSR -AbortFault<T>::getFsr(ThreadContext *tc) +void +AbortFault<T>::setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg) { - FSR fsr = 0; + srcEncoded = getFaultStatusCode(tc); + if (srcEncoded == ArmFault::FaultSourceInvalid) { + panic("Invalid fault source\n"); + } + ArmFault::setSyndrome(tc, syndrome_reg); +} - if (((CPSR) tc->readMiscRegNoEffect(MISCREG_CPSR)).width) { +template<class T> +uint8_t +AbortFault<T>::getFaultStatusCode(ThreadContext *tc) const +{ + + panic_if(!this->faultUpdated, + "Trying to use un-updated ArmFault internal variables\n"); + + uint8_t fsc = 0; + + if (!this->to64) { // AArch32 assert(tranMethod != ArmFault::UnknownTran); if (tranMethod == ArmFault::LpaeTran) { - srcEncoded = ArmFault::longDescFaultSources[source]; - fsr.status = srcEncoded; - fsr.lpae = 1; + fsc = ArmFault::longDescFaultSources[source]; } else { - srcEncoded = ArmFault::shortDescFaultSources[source]; - fsr.fsLow = bits(srcEncoded, 3, 0); - fsr.fsHigh = bits(srcEncoded, 4); - fsr.domain = static_cast<uint8_t>(domain); + fsc = ArmFault::shortDescFaultSources[source]; } - fsr.wnr = (write ? 1 : 0); - fsr.ext = 0; } else { // AArch64 - srcEncoded = ArmFault::aarch64FaultSources[source]; + fsc = ArmFault::aarch64FaultSources[source]; } - if (srcEncoded == ArmFault::FaultSourceInvalid) { - panic("Invalid fault source\n"); + + return fsc; +} + +template<class T> +FSR +AbortFault<T>::getFsr(ThreadContext *tc) const +{ + FSR fsr = 0; + + auto fsc = getFaultStatusCode(tc); + + // AArch32 + assert(tranMethod != ArmFault::UnknownTran); + if (tranMethod == ArmFault::LpaeTran) { + fsr.status = fsc; + fsr.lpae = 1; + } else { + fsr.fsLow = bits(fsc, 3, 0); + fsr.fsHigh = bits(fsc, 4); + fsr.domain = static_cast<uint8_t>(domain); } + + fsr.wnr = (write ? 1 : 0); + fsr.ext = 0; + return fsr; } diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh index f663b5cfc..132c07cae 100644 --- a/src/arch/arm/faults.hh +++ b/src/arch/arm/faults.hh @@ -228,7 +228,7 @@ class ArmFault : public FaultBase virtual ExceptionClass ec(ThreadContext *tc) const = 0; virtual uint32_t iss() const = 0; virtual bool isStage2() const { return false; } - virtual FSR getFsr(ThreadContext *tc) { return 0; } + virtual FSR getFsr(ThreadContext *tc) const { return 0; } virtual void setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg); }; @@ -431,11 +431,13 @@ class AbortFault : public ArmFaultVals<T> void invoke(ThreadContext *tc, const StaticInstPtr &inst = StaticInst::nullStaticInstPtr) override; - FSR getFsr(ThreadContext *tc) override; + FSR getFsr(ThreadContext *tc) const override; + uint8_t getFaultStatusCode(ThreadContext *tc) const; bool abortDisable(ThreadContext *tc) override; uint32_t iss() const override; bool isStage2() const override { return stage2; } void annotate(ArmFault::AnnotationIDs id, uint64_t val) override; + void setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg) override; bool isMMUFault() const; }; diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index f6677323e..d6992dc44 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -1477,6 +1477,7 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) val, newVal); } else { ArmFault *armFault = static_cast<ArmFault *>(fault.get()); + armFault->update(tc); // Set fault bit and FSR FSR fsr = armFault->getFsr(tc); @@ -1726,6 +1727,7 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) val, newVal); } else { ArmFault *armFault = static_cast<ArmFault *>(fault.get()); + armFault->update(tc); // Set fault bit and FSR FSR fsr = armFault->getFsr(tc); |