changeset 32cbf6ab7730 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=32cbf6ab7730
description:
        arm: refactor page table walking

        Introduce and use a lookup table.

        Using fetchDescriptor() rather than DMA cleanly handles nested paging.

        Change-Id: I69ec762f176bd752ba1040890e731826b58d15a6

diffstat:

 src/arch/arm/table_walker.cc |  54 +++++++++++--------------------------------
 src/arch/arm/table_walker.hh |   1 +
 2 files changed, 15 insertions(+), 40 deletions(-)

diffs (111 lines):

diff -r b7c4aa85db2a -r 32cbf6ab7730 src/arch/arm/table_walker.cc
--- a/src/arch/arm/table_walker.cc      Tue Aug 02 10:38:03 2016 +0100
+++ b/src/arch/arm/table_walker.cc      Tue Aug 02 10:38:03 2016 +0100
@@ -65,8 +65,10 @@
       pendingReqs(0),
       pendingChangeTick(curTick()),
       doL1DescEvent(this), doL2DescEvent(this),
-      doL0LongDescEvent(this), doL1LongDescEvent(this), 
doL2LongDescEvent(this),
-      doL3LongDescEvent(this),
+      doL0LongDescEvent(this), doL1LongDescEvent(this),
+      doL2LongDescEvent(this), doL3LongDescEvent(this),
+      LongDescEventByLevel { &doL0LongDescEvent, &doL1LongDescEvent,
+                             &doL2LongDescEvent, &doL3LongDescEvent },
       doProcessEvent(this)
 {
     sctlr = 0;
@@ -138,7 +140,8 @@
 TableWalker::completeDrain()
 {
     if (drainState() == DrainState::Draining &&
-        stateQueues[L1].empty() && stateQueues[L2].empty() &&
+        stateQueues[L0].empty() && stateQueues[L1].empty() &&
+        stateQueues[L2].empty() && stateQueues[L3].empty() &&
         pendingQueue.empty()) {
 
         DPRINTF(Drain, "TableWalker done draining, processing drain event\n");
@@ -697,12 +700,10 @@
     currState->longDesc.aarch64 = false;
     currState->longDesc.grainSize = Grain4KB;
 
-    Event *event = start_lookup_level == L1 ? (Event *) &doL1LongDescEvent
-                                            : (Event *) &doL2LongDescEvent;
-
     bool delayed = fetchDescriptor(desc_addr, 
(uint8_t*)&currState->longDesc.data,
                                    sizeof(uint64_t), flag, start_lookup_level,
-                                   event, &TableWalker::doLongDescriptor);
+                                   LongDescEventByLevel[start_lookup_level],
+                                   &TableWalker::doLongDescriptor);
     if (!delayed) {
         f = currState->fault;
     }
@@ -967,32 +968,9 @@
     currState->longDesc.grainSize = tg;
 
     if (currState->timing) {
-        Event *event;
-        switch (start_lookup_level) {
-          case L0:
-            event = (Event *) &doL0LongDescEvent;
-            break;
-          case L1:
-            event = (Event *) &doL1LongDescEvent;
-            break;
-          case L2:
-            event = (Event *) &doL2LongDescEvent;
-            break;
-          case L3:
-            event = (Event *) &doL3LongDescEvent;
-            break;
-          default:
-            panic("Invalid table lookup level");
-            break;
-        }
-        port->dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t),
-                       event, (uint8_t*) &currState->longDesc.data,
-                       currState->tc->getCpuPtr()->clockPeriod(), flag);
-        DPRINTF(TLBVerbose,
-                "Adding to walker fifo: queue size before adding: %d\n",
-                stateQueues[start_lookup_level].size());
-        stateQueues[start_lookup_level].push_back(currState);
-        currState = NULL;
+        fetchDescriptor(desc_addr, (uint8_t*) &currState->longDesc.data,
+                        sizeof(uint64_t), flag, start_lookup_level,
+                        LongDescEventByLevel[start_lookup_level], NULL);
     } else {
         fetchDescriptor(desc_addr, (uint8_t*)&currState->longDesc.data,
                         sizeof(uint64_t), flag, -1, NULL,
@@ -1672,19 +1650,15 @@
             if (currState->secureLookup)
                 flag.set(Request::SECURE);
 
-            currState->longDesc.lookupLevel =
+            LookupLevel L = currState->longDesc.lookupLevel =
                 (LookupLevel) (currState->longDesc.lookupLevel + 1);
             Event *event = NULL;
-            switch (currState->longDesc.lookupLevel) {
+            switch (L) {
               case L1:
                 assert(currState->aarch64);
-                event = &doL1LongDescEvent;
-                break;
               case L2:
-                event = &doL2LongDescEvent;
-                break;
               case L3:
-                event = &doL3LongDescEvent;
+                event = LongDescEventByLevel[L];
                 break;
               default:
                 panic("Wrong lookup level in table walk\n");
diff -r b7c4aa85db2a -r 32cbf6ab7730 src/arch/arm/table_walker.hh
--- a/src/arch/arm/table_walker.hh      Tue Aug 02 10:38:03 2016 +0100
+++ b/src/arch/arm/table_walker.hh      Tue Aug 02 10:38:03 2016 +0100
@@ -944,6 +944,7 @@
                  &TableWalker::doL3LongDescriptorWrapper> doL3LongDescEvent;
 
     void doLongDescriptorWrapper(LookupLevel curr_lookup_level);
+    Event* LongDescEventByLevel[4];
 
     bool fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes,
         Request::Flags flags, int queueIndex, Event *event,
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to