ARM: Squash outstanding walks when instructions are squashed.
This commit is contained in:
parent
29acf859eb
commit
0c99d21ad7
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -269,6 +269,14 @@ class TimingSimpleCPU : public BaseSimpleCPU
|
|||
void completeDataAccess(PacketPtr pkt);
|
||||
void advanceInst(Fault fault);
|
||||
|
||||
/** This function is used by the page table walker to determine if it could
|
||||
* translate the a pending request or if the underlying request has been
|
||||
* squashed. This always returns false for the simple timing CPU as it never
|
||||
* executes any instructions speculatively.
|
||||
* @ return Is the current instruction squashed?
|
||||
*/
|
||||
bool isSquashed() const { return false; }
|
||||
|
||||
/**
|
||||
* Print state of address in memory system via PrintReq (for
|
||||
* debugging).
|
||||
|
|
|
@ -259,6 +259,12 @@ class DataTranslation : public BaseTLB::Translation
|
|||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool
|
||||
squashed() const
|
||||
{
|
||||
return xc->isSquashed();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __CPU_TRANSLATION_HH__
|
||||
|
|
|
@ -94,6 +94,13 @@ class BaseTLB : public SimObject
|
|||
*/
|
||||
virtual void finish(Fault fault, RequestPtr req, ThreadContext *tc,
|
||||
Mode mode) = 0;
|
||||
|
||||
/** This function is used by the page table walker to determine if it
|
||||
* should translate the a pending request or if the underlying request
|
||||
* has been squashed.
|
||||
* @ return Is the instruction that requested this translation squashed?
|
||||
*/
|
||||
virtual bool squashed() const { return false; }
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue