diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index 310545bc33..a1952d664c 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -1032,13 +1032,13 @@ AbortFault::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::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::invoke(ThreadContext *tc, const StaticInstPtr &inst) } template -FSR -AbortFault::getFsr(ThreadContext *tc) +void +AbortFault::setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg) { - FSR fsr = 0; - - if (((CPSR) tc->readMiscRegNoEffect(MISCREG_CPSR)).width) { - // AArch32 - assert(tranMethod != ArmFault::UnknownTran); - if (tranMethod == ArmFault::LpaeTran) { - srcEncoded = ArmFault::longDescFaultSources[source]; - fsr.status = srcEncoded; - fsr.lpae = 1; - } else { - srcEncoded = ArmFault::shortDescFaultSources[source]; - fsr.fsLow = bits(srcEncoded, 3, 0); - fsr.fsHigh = bits(srcEncoded, 4); - fsr.domain = static_cast(domain); - } - fsr.wnr = (write ? 1 : 0); - fsr.ext = 0; - } else { - // AArch64 - srcEncoded = ArmFault::aarch64FaultSources[source]; - } + srcEncoded = getFaultStatusCode(tc); if (srcEncoded == ArmFault::FaultSourceInvalid) { panic("Invalid fault source\n"); } + ArmFault::setSyndrome(tc, syndrome_reg); +} + +template +uint8_t +AbortFault::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) { + fsc = ArmFault::longDescFaultSources[source]; + } else { + fsc = ArmFault::shortDescFaultSources[source]; + } + } else { + // AArch64 + fsc = ArmFault::aarch64FaultSources[source]; + } + + return fsc; +} + +template +FSR +AbortFault::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(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 f663b5cfc6..132c07cae7 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 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 f6677323e0..d6992dc44e 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(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(fault.get()); + armFault->update(tc); // Set fault bit and FSR FSR fsr = armFault->getFsr(tc);