summaryrefslogtreecommitdiff
path: root/src/arch/arm/table_walker.hh
diff options
context:
space:
mode:
authorAli Saidi <Ali.Saidi@ARM.com>2010-11-08 13:58:24 -0600
committerAli Saidi <Ali.Saidi@ARM.com>2010-11-08 13:58:24 -0600
commite6c31ceb2bf62da1241fe6cfcfbd67fd055ce8cd (patch)
tree84e831a6f5b211e0298a6d8266bd7d623a6dc1e0 /src/arch/arm/table_walker.hh
parent5fcf442f4f0d85c5f3fcf6bfd4ecbf37a1f3f4c9 (diff)
downloadgem5-e6c31ceb2bf62da1241fe6cfcfbd67fd055ce8cd.tar.xz
ARM: Don't return the result of a table walk the same cycle it's completed.
The L1 cache may have been accessed to provide this data, which confuses it, if it ends up being accesses twice in one cycle. Instead wait 1 tick which will force the timing simple CPU to forward to its next clock cycle when the translation completes. Also prevent multiple outstanding table walks from occuring at once.
Diffstat (limited to 'src/arch/arm/table_walker.hh')
-rw-r--r--src/arch/arm/table_walker.hh12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh
index dc801dde8..fde553ff4 100644
--- a/src/arch/arm/table_walker.hh
+++ b/src/arch/arm/table_walker.hh
@@ -320,6 +320,11 @@ class TableWalker : public MemObject
* require an additional level. */
std::list<WalkerState *> stateQueueL2;
+ /** Queue of requests that have passed are waiting because the walker is
+ * currently busy. */
+ std::list<WalkerState *> pendingQueue;;
+
+
/** Port to issue translation requests from */
DmaPort *port;
@@ -331,6 +336,9 @@ class TableWalker : public MemObject
WalkerState *currState;
+ /** If a timing translation is currently in progress */
+ bool pending;
+
public:
typedef ArmTableWalkerParams Params;
TableWalker(const Params *p);
@@ -362,7 +370,11 @@ class TableWalker : public MemObject
void doL2DescriptorWrapper();
EventWrapper<TableWalker, &TableWalker::doL2DescriptorWrapper> doL2DescEvent;
+ Fault processWalk();
+ void processWalkWrapper();
+ EventWrapper<TableWalker, &TableWalker::processWalkWrapper> doProcessEvent;
+ void nextWalk(ThreadContext *tc);
};