summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/faults.cc65
-rw-r--r--src/arch/arm/faults.hh6
-rw-r--r--src/arch/arm/isa.cc2
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);