Giacomo Travaglini has submitted this change and it was merged. (
https://gem5-review.googlesource.com/8362 )
Change subject: arch-arm: Fix FSC generation in AbortFault
......................................................................
arch-arm: Fix FSC generation in AbortFault
The fault status code generated by a Prefetch/Data Fault was containing
a wrong value when the fault was triggered in aarch32 but handled in
aarch64. This because the encoding differs between the two ISAs and the
encoder was just checking the starting ISA rather than the the ending
one. In this case the getFsr must be called after we know which is the
ending ISA, which happens only after ArmFault::invoke gets called. The
fsc update hence happens before writing into the Syndrome register.
Change-Id: I725f12b6dcc0178f608233bd3d15e466d1cd1ffc
Signed-off-by: Giacomo Travaglini <[email protected]>
Reviewed-by: Andreas Sandberg <[email protected]>
Reviewed-on: https://gem5-review.googlesource.com/8362
Maintainer: Andreas Sandberg <[email protected]>
---
M src/arch/arm/faults.cc
M src/arch/arm/faults.hh
M src/arch/arm/isa.cc
3 files changed, 61 insertions(+), 26 deletions(-)
Approvals:
Andreas Sandberg: Looks good to me, approved; Looks good to me, approved
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
index 310545b..a1952d6 100644
--- a/src/arch/arm/faults.cc
+++ b/src/arch/arm/faults.cc
@@ -1032,13 +1032,13 @@
}
// 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 @@
}
template<class T>
-FSR
-AbortFault<T>::getFsr(ThreadContext *tc)
+void
+AbortFault<T>::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<uint8_t>(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<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) {
+ fsc = ArmFault::longDescFaultSources[source];
+ } else {
+ fsc = ArmFault::shortDescFaultSources[source];
+ }
+ } else {
+ // AArch64
+ fsc = ArmFault::aarch64FaultSources[source];
+ }
+
+ 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 f663b5c..132c07c 100644
--- a/src/arch/arm/faults.hh
+++ b/src/arch/arm/faults.hh
@@ -228,7 +228,7 @@
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 @@
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 f667732..d6992dc 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -1477,6 +1477,7 @@
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 @@
val, newVal);
} else {
ArmFault *armFault = static_cast<ArmFault
*>(fault.get());
+ armFault->update(tc);
// Set fault bit and FSR
FSR fsr = armFault->getFsr(tc);
--
To view, visit https://gem5-review.googlesource.com/8362
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I725f12b6dcc0178f608233bd3d15e466d1cd1ffc
Gerrit-Change-Number: 8362
Gerrit-PatchSet: 3
Gerrit-Owner: Giacomo Travaglini <[email protected]>
Gerrit-Reviewer: Andreas Sandberg <[email protected]>
Gerrit-Reviewer: Giacomo Travaglini <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev