diff options
Diffstat (limited to 'src/arch/x86/pagetable_walker.cc')
-rw-r--r-- | src/arch/x86/pagetable_walker.cc | 37 |
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() { |