}
// 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) {
}
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;
}
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);
};
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;
};