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'
|
cxx_class = 'ArmISA::TableWalker'
|
||||||
port = MasterPort("Port for TableWalker to do walk the translation with")
|
port = MasterPort("Port for TableWalker to do walk the translation with")
|
||||||
sys = Param.System(Parent.any, "system object parameter")
|
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):
|
class ArmTLB(SimObject):
|
||||||
type = 'ArmTLB'
|
type = 'ArmTLB'
|
||||||
|
|
|
@ -54,6 +54,7 @@ TableWalker::TableWalker(const Params *p)
|
||||||
: MemObject(p), port(this, params()->sys), drainEvent(NULL),
|
: MemObject(p), port(this, params()->sys), drainEvent(NULL),
|
||||||
tlb(NULL), currState(NULL), pending(false),
|
tlb(NULL), currState(NULL), pending(false),
|
||||||
masterId(p->sys->getMasterId(name())),
|
masterId(p->sys->getMasterId(name())),
|
||||||
|
numSquashable(p->num_squash_per_cycle),
|
||||||
doL1DescEvent(this), doL2DescEvent(this), doProcessEvent(this)
|
doL1DescEvent(this), doL2DescEvent(this), doProcessEvent(this)
|
||||||
{
|
{
|
||||||
sctlr = 0;
|
sctlr = 0;
|
||||||
|
@ -184,9 +185,46 @@ TableWalker::processWalkWrapper()
|
||||||
assert(!currState);
|
assert(!currState);
|
||||||
assert(pendingQueue.size());
|
assert(pendingQueue.size());
|
||||||
currState = pendingQueue.front();
|
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
|
Fault
|
||||||
|
|
|
@ -380,6 +380,10 @@ class TableWalker : public MemObject
|
||||||
/** Request id for requests generated by this walker */
|
/** Request id for requests generated by this walker */
|
||||||
MasterID masterId;
|
MasterID masterId;
|
||||||
|
|
||||||
|
/** The number of walks belonging to squashed instructions that can be
|
||||||
|
* removed from the pendingQueue per cycle. */
|
||||||
|
unsigned numSquashable;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef ArmTableWalkerParams Params;
|
typedef ArmTableWalkerParams Params;
|
||||||
TableWalker(const Params *p);
|
TableWalker(const Params *p);
|
||||||
|
|
|
@ -269,6 +269,14 @@ class TimingSimpleCPU : public BaseSimpleCPU
|
||||||
void completeDataAccess(PacketPtr pkt);
|
void completeDataAccess(PacketPtr pkt);
|
||||||
void advanceInst(Fault fault);
|
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
|
* Print state of address in memory system via PrintReq (for
|
||||||
* debugging).
|
* debugging).
|
||||||
|
|
|
@ -259,6 +259,12 @@ class DataTranslation : public BaseTLB::Translation
|
||||||
}
|
}
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
squashed() const
|
||||||
|
{
|
||||||
|
return xc->isSquashed();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __CPU_TRANSLATION_HH__
|
#endif // __CPU_TRANSLATION_HH__
|
||||||
|
|
|
@ -94,6 +94,13 @@ class BaseTLB : public SimObject
|
||||||
*/
|
*/
|
||||||
virtual void finish(Fault fault, RequestPtr req, ThreadContext *tc,
|
virtual void finish(Fault fault, RequestPtr req, ThreadContext *tc,
|
||||||
Mode mode) = 0;
|
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