diff options
author | Gedare Bloom <gedare@rtems.org> | 2013-05-21 11:40:11 -0500 |
---|---|---|
committer | Gedare Bloom <gedare@rtems.org> | 2013-05-21 11:40:11 -0500 |
commit | 22b60c57e697289baa205f11b164f356363c2bee (patch) | |
tree | 4206562aae3cdb8b82a3ec8e873f15444502c678 /src/arch/x86/pagetable_walker.cc | |
parent | 30fe807316ebc4b6c37ca522b3cfd6c592ca9003 (diff) | |
download | gem5-22b60c57e697289baa205f11b164f356363c2bee.tar.xz |
x86: Squash outstanding walks when instructions are squashed.
This is the x86 version of the ARM changeset baa17ba80e06. In case an
instruction has been squashed by the o3 cpu, this patch allows page
table walker to avoid carrying out a pending translation that the
instruction requested for.
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() { |