From 0c99d21ad748371e801508a8c3652e07e2e56f93 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 25 Sep 2012 11:49:40 -0500 Subject: ARM: Squash outstanding walks when instructions are squashed. --- src/arch/arm/ArmTLB.py | 2 ++ src/arch/arm/table_walker.cc | 44 +++++++++++++++++++++++++++++++++++++++++--- src/arch/arm/table_walker.hh | 4 ++++ 3 files changed, 47 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/ArmTLB.py b/src/arch/arm/ArmTLB.py index 9572d2091..0a931b7e5 100644 --- a/src/arch/arm/ArmTLB.py +++ b/src/arch/arm/ArmTLB.py @@ -47,6 +47,8 @@ class ArmTableWalker(MemObject): cxx_class = 'ArmISA::TableWalker' port = MasterPort("Port for TableWalker to do walk the translation with") sys = Param.System(Parent.any, "system object parameter") + num_squash_per_cycle = Param.Unsigned(2, + "Number of outstanding walks that can be squashed per cycle") class ArmTLB(SimObject): type = 'ArmTLB' diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc index 77cc662b3..dbd4211d5 100644 --- a/src/arch/arm/table_walker.cc +++ b/src/arch/arm/table_walker.cc @@ -54,6 +54,7 @@ TableWalker::TableWalker(const Params *p) : MemObject(p), port(this, params()->sys), drainEvent(NULL), tlb(NULL), currState(NULL), pending(false), masterId(p->sys->getMasterId(name())), + numSquashable(p->num_squash_per_cycle), doL1DescEvent(this), doL2DescEvent(this), doProcessEvent(this) { sctlr = 0; @@ -184,9 +185,46 @@ TableWalker::processWalkWrapper() assert(!currState); assert(pendingQueue.size()); currState = pendingQueue.front(); - pendingQueue.pop_front(); - pending = true; - processWalk(); + + + if (!currState->transState->squashed()) { + // We've got a valid request, lets process it + pending = true; + pendingQueue.pop_front(); + processWalk(); + return; + } + + + // If the instruction that we were translating for has been + // squashed we shouldn't bother. + unsigned num_squashed = 0; + ThreadContext *tc = currState->tc; + assert(currState->transState->squashed()); + while ((num_squashed < numSquashable) && currState && + currState->transState->squashed()) { + pendingQueue.pop_front(); + num_squashed++; + + DPRINTF(TLB, "Squashing table walk for address %#x\n", currState->vaddr); + + // finish the translation which will delete the translation object + currState->transState->finish(new UnimpFault("Squashed Inst"), + currState->req, currState->tc, currState->mode); + + // delete the current request + delete currState; + + // peak at the next one + if (pendingQueue.size()) + currState = pendingQueue.front(); + else + currState = NULL; + } + + // if we've still got pending translations schedule more work + nextWalk(tc); + currState = NULL; } Fault diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh index b6fee66ff..509b24339 100644 --- a/src/arch/arm/table_walker.hh +++ b/src/arch/arm/table_walker.hh @@ -380,6 +380,10 @@ class TableWalker : public MemObject /** Request id for requests generated by this walker */ MasterID masterId; + /** The number of walks belonging to squashed instructions that can be + * removed from the pendingQueue per cycle. */ + unsigned numSquashable; + public: typedef ArmTableWalkerParams Params; TableWalker(const Params *p); -- cgit v1.2.3