summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Saidi <Ali.Saidi@ARM.com>2011-04-04 11:42:27 -0500
committerAli Saidi <Ali.Saidi@ARM.com>2011-04-04 11:42:27 -0500
commit55920a5ca73ded58762f1b7ae25c8cfe8c9e407d (patch)
treeb0bd2754e8b06b0080d0b9d22dbf4c721b209622
parent5962fecc1d2eaf956f0aab10eee1e0666a461706 (diff)
downloadgem5-55920a5ca73ded58762f1b7ae25c8cfe8c9e407d.tar.xz
ARM: Fix table walk going on while ASID changes error
-rw-r--r--src/arch/arm/faults.cc14
-rw-r--r--src/arch/arm/faults.hh10
-rw-r--r--src/arch/arm/table_walker.cc12
-rw-r--r--src/arch/arm/tlb.cc6
4 files changed, 38 insertions, 4 deletions
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
index 9ce2e2da4..9fdd58da0 100644
--- a/src/arch/arm/faults.cc
+++ b/src/arch/arm/faults.cc
@@ -74,6 +74,9 @@ template<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals =
template<> ArmFault::FaultVals ArmFaultVals<FlushPipe>::vals =
{"Pipe Flush", 0x00, MODE_SVC, 0, 0, true, true}; // some dummy values
+template<> ArmFault::FaultVals ArmFaultVals<ReExec>::vals =
+ {"ReExec Flush", 0x00, MODE_SVC, 0, 0, true, true}; // some dummy values
+
Addr
ArmFault::getVector(ThreadContext *tc)
{
@@ -225,6 +228,17 @@ FlushPipe::invoke(ThreadContext *tc, StaticInstPtr inst) {
tc->pcState(pc);
}
+void
+ReExec::invoke(ThreadContext *tc, StaticInstPtr inst) {
+ DPRINTF(Faults, "Invoking ReExec Fault\n");
+
+ // Set the PC to then the faulting instruction.
+ // Net effect is simply squashing all instructions including this
+ // instruction and refetching/rexecuting current instruction
+ PCState pc = tc->pcState();
+ tc->pcState(pc);
+}
+
template void AbortFault<PrefetchAbort>::invoke(ThreadContext *tc,
StaticInstPtr inst);
template void AbortFault<DataAbort>::invoke(ThreadContext *tc,
diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh
index 633e74eae..8df8d0abf 100644
--- a/src/arch/arm/faults.hh
+++ b/src/arch/arm/faults.hh
@@ -242,6 +242,16 @@ class FlushPipe : public ArmFaultVals<FlushPipe>
StaticInstPtr inst = StaticInst::nullStaticInstPtr);
};
+// A fault that flushes the pipe, including the faulting instructions
+class ReExec : public ArmFaultVals<ReExec>
+{
+ public:
+ ReExec() {}
+ void invoke(ThreadContext *tc,
+ StaticInstPtr inst = StaticInst::nullStaticInstPtr);
+};
+
+
static inline Fault genMachineCheckFault()
{
return new Reset();
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index e2207e26b..2d0e323f6 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -114,8 +114,16 @@ TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint8_t _cid, TLB::Mode _
currState = new WalkerState();
currState->tableWalker = this;
- }
- else if (_timing) {
+ } else if (_timing) {
+ // This is a translation that was completed and then faulted again
+ // because some underlying parameters that affect the translation
+ // changed out from under us (e.g. asid). It will either be a
+ // misprediction, in which case nothing will happen or we'll use
+ // this fault to re-execute the faulting instruction which should clean
+ // up everything.
+ if (currState->vaddr == _req->getVaddr()) {
+ return new ReExec;
+ }
panic("currState should always be empty in timing mode!\n");
}
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index f1c8ae41a..ccbca3d9c 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -446,8 +446,10 @@ Fault
TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
Translation *translation, bool &delay, bool timing)
{
- if (!miscRegValid)
+ if (!miscRegValid) {
updateMiscReg(tc);
+ DPRINTF(TLBVerbose, "TLB variables changed!\n");
+ }
Addr vaddr = req->getVaddr();
uint32_t flags = req->getFlags();
@@ -456,7 +458,7 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
bool is_write = (mode == Write);
bool is_priv = isPriv && !(flags & UserMode);
- DPRINTF(TLBVerbose, "CPSR is user:%d UserMode:%d\n",
+ DPRINTF(TLBVerbose, "CPSR is priv:%d UserMode:%d\n",
isPriv, flags & UserMode);
// If this is a clrex instruction, provide a PA of 0 with no fault
// This will force the monitor to set the tracked address to 0