summaryrefslogtreecommitdiff
path: root/src/arch/x86/pagetable_walker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86/pagetable_walker.cc')
-rw-r--r--src/arch/x86/pagetable_walker.cc37
1 files changed, 32 insertions, 5 deletions
diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc
index 853e062e7..45f902999 100644
--- a/src/arch/x86/pagetable_walker.cc
+++ b/src/arch/x86/pagetable_walker.cc
@@ -139,11 +139,8 @@ Walker::recvTimingResp(PacketPtr pkt)
delete senderWalk;
// Since we block requests when another is outstanding, we
// need to check if there is a waiting request to be serviced
- if (currStates.size()) {
- WalkerState * newState = currStates.front();
- if (!newState->wasStarted())
- newState->startWalk();
- }
+ if (currStates.size())
+ startWalkWrapper();
}
return true;
}
@@ -192,6 +189,36 @@ Walker::WalkerState::initState(ThreadContext * _tc,
timing = _isTiming;
}
+void
+Walker::startWalkWrapper()
+{
+ unsigned num_squashed = 0;
+ WalkerState *currState = currStates.front();
+ while ((num_squashed < numSquashable) && currState &&
+ currState->translation->squashed()) {
+ currStates.pop_front();
+ num_squashed++;
+
+ DPRINTF(PageTableWalker, "Squashing table walk for address %#x\n",
+ currState->req->getVaddr());
+
+ // finish the translation which will delete the translation object
+ currState->translation->finish(new UnimpFault("Squashed Inst"),
+ currState->req, currState->tc, currState->mode);
+
+ // delete the current request
+ delete currState;
+
+ // check the next translation request, if it exists
+ if (currStates.size())
+ currState = currStates.front();
+ else
+ currState = NULL;
+ }
+ if (currState && !currState->wasStarted())
+ currState->startWalk();
+}
+
Fault
Walker::WalkerState::startWalk()
{