cxx_header = 'arch/x86/pagetable_walker.hh'
port = MasterPort("Port for the hardware table walker")
system = Param.System(Parent.any, "system object")
+ num_squash_per_cycle = Param.Unsigned(4,
+ "Number of outstanding walks that can be squashed per cycle")
class X86TLB(BaseTLB):
type = 'X86TLB'
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;
}
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()
{
// State to track each walk of the page table
class WalkerState
{
+ friend class Walker;
private:
enum State {
Ready,
System * sys;
MasterID masterId;
+ // The number of outstanding walks that can be squashed per cycle.
+ unsigned numSquashable;
+
+ // Wrapper for checking for squashes before starting a translation.
+ void startWalkWrapper();
+
// Functions for dealing with packets.
bool recvTimingResp(PacketPtr pkt);
void recvRetry();
Walker(const Params *params) :
MemObject(params), port(name() + ".port", this),
funcState(this, NULL, NULL, true), tlb(NULL), sys(params->system),
- masterId(sys->getMasterId(name()))
+ masterId(sys->getMasterId(name())),
+ numSquashable(params->num_squash_per_cycle)
{
}
};