summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAli Saidi <Ali.Saidi@ARM.com>2012-09-25 11:49:40 -0500
committerAli Saidi <Ali.Saidi@ARM.com>2012-09-25 11:49:40 -0500
commit0c99d21ad748371e801508a8c3652e07e2e56f93 (patch)
treea2a52170a8a88ce919cecb4309428999e5380cfd /src
parent29acf859ebde2cf219ae636f60d8a46db7a1bb94 (diff)
downloadgem5-0c99d21ad748371e801508a8c3652e07e2e56f93.tar.xz
ARM: Squash outstanding walks when instructions are squashed.
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/ArmTLB.py2
-rw-r--r--src/arch/arm/table_walker.cc44
-rw-r--r--src/arch/arm/table_walker.hh4
-rw-r--r--src/cpu/simple/timing.hh8
-rw-r--r--src/cpu/translation.hh6
-rw-r--r--src/sim/tlb.hh7
6 files changed, 68 insertions, 3 deletions
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);
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index 19a4f818e..a2570abe6 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -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).
diff --git a/src/cpu/translation.hh b/src/cpu/translation.hh
index b6bc2182c..90fffa03d 100644
--- a/src/cpu/translation.hh
+++ b/src/cpu/translation.hh
@@ -259,6 +259,12 @@ class DataTranslation : public BaseTLB::Translation
}
delete this;
}
+
+ bool
+ squashed() const
+ {
+ return xc->isSquashed();
+ }
};
#endif // __CPU_TRANSLATION_HH__
diff --git a/src/sim/tlb.hh b/src/sim/tlb.hh
index 379cdd343..0b89c9bd0 100644
--- a/src/sim/tlb.hh
+++ b/src/sim/tlb.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; }
};
};