changeset 4f8c1bd6fdb8 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=4f8c1bd6fdb8
description:
        arm: Share a port for the two table walker objects

        This patch changes how the MMU and table walkers are created such that
        a single port is used to connect the MMU and the TLBs to the memory
        system. Previously two ports were needed as there are two table walker
        objects (stage one and stage two), and they both had a port. Now the
        port itself is moved to the Stage2MMU, and each TableWalker is simply
        using the port from the parent.

        By using the same port we also remove the need for having an
        additional crossbar joining the two ports before the walker cache or
        the L2. This simplifies the creation of the CPU cache topology in
        BaseCPU.py considerably. Moreover, for naming and symmetry reasons,
        the TLB walker port is connected through the stage-one table walker
        thus making the naming identical to x86. Along the same line, we use
        the stage-one table walker to generate the master id that is used by
        all TLB-related requests.

diffstat:

 src/arch/arm/ArmTLB.py       |  22 ++++++++++---
 src/arch/arm/stage2_mmu.cc   |  43 +++++++++++++++-----------
 src/arch/arm/stage2_mmu.hh   |  58 ++++++++++++++++++++++++++++++++---
 src/arch/arm/table_walker.cc |  72 +++++++++++++++++++++++++++----------------
 src/arch/arm/table_walker.hh |  63 +++++++-------------------------------
 src/arch/arm/tlb.cc          |  12 +-----
 src/arch/arm/tlb.hh          |  13 +------
 src/cpu/BaseCPU.py           |  26 +--------------
 8 files changed, 161 insertions(+), 148 deletions(-)

diffs (truncated from 674 to 300 lines):

diff -r 4408a83f7881 -r 4f8c1bd6fdb8 src/arch/arm/ArmTLB.py
--- a/src/arch/arm/ArmTLB.py    Mon Mar 02 04:00:41 2015 -0500
+++ b/src/arch/arm/ArmTLB.py    Mon Mar 02 04:00:42 2015 -0500
@@ -1,6 +1,6 @@
 # -*- mode:python -*-
 
-# Copyright (c) 2009, 2013 ARM Limited
+# Copyright (c) 2009, 2013, 2015 ARM Limited
 # All rights reserved.
 #
 # The license below extends only to copyright in the software and shall
@@ -48,11 +48,17 @@
     cxx_class = 'ArmISA::TableWalker'
     cxx_header = "arch/arm/table_walker.hh"
     is_stage2 =  Param.Bool(False, "Is this object for stage 2 translation?")
-    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")
 
+    # The port to the memory system. This port is ultimately belonging
+    # to the Stage2MMU, and shared by the two table walkers, but we
+    # access it through the ITB and DTB walked objects in the CPU for
+    # symmetry with the other ISAs.
+    port = MasterPort("Port used by the two table walkers")
+
+    sys = Param.System(Parent.any, "system object parameter")
+
 class ArmTLB(SimObject):
     type = 'ArmTLB'
     cxx_class = 'ArmISA::TLB'
@@ -77,10 +83,16 @@
     tlb = Param.ArmTLB("Stage 1 TLB")
     stage2_tlb = Param.ArmTLB("Stage 2 TLB")
 
+    sys = Param.System(Parent.any, "system object parameter")
+
 class ArmStage2IMMU(ArmStage2MMU):
+    # We rely on the itb being a parameter of the CPU, and get the
+    # appropriate object that way
     tlb = Parent.itb
-    stage2_tlb = ArmStage2TLB(walker = ArmStage2TableWalker())
+    stage2_tlb = ArmStage2TLB()
 
 class ArmStage2DMMU(ArmStage2MMU):
+    # We rely on the dtb being a parameter of the CPU, and get the
+    # appropriate object that way
     tlb = Parent.dtb
-    stage2_tlb = ArmStage2TLB(walker = ArmStage2TableWalker())
+    stage2_tlb = ArmStage2TLB()
diff -r 4408a83f7881 -r 4f8c1bd6fdb8 src/arch/arm/stage2_mmu.cc
--- a/src/arch/arm/stage2_mmu.cc        Mon Mar 02 04:00:41 2015 -0500
+++ b/src/arch/arm/stage2_mmu.cc        Mon Mar 02 04:00:42 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 ARM Limited
+ * Copyright (c) 2012-2013, 2015 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -37,29 +37,31 @@
  * Authors: Thomas Grocutt
  */
 
+#include "arch/arm/stage2_mmu.hh"
 #include "arch/arm/faults.hh"
-#include "arch/arm/stage2_mmu.hh"
 #include "arch/arm/system.hh"
+#include "arch/arm/table_walker.hh"
 #include "arch/arm/tlb.hh"
 #include "cpu/base.hh"
 #include "cpu/thread_context.hh"
-#include "debug/Checkpoint.hh"
-#include "debug/TLB.hh"
-#include "debug/TLBVerbose.hh"
 
 using namespace ArmISA;
 
 Stage2MMU::Stage2MMU(const Params *p)
-    : SimObject(p), _stage1Tlb(p->tlb), _stage2Tlb(p->stage2_tlb)
+    : SimObject(p), _stage1Tlb(p->tlb), _stage2Tlb(p->stage2_tlb),
+      port(_stage1Tlb->getTableWalker(), p->sys),
+      masterId(p->sys->getMasterId(_stage1Tlb->getTableWalker()->name()))
 {
-    stage1Tlb()->setMMU(this);
-    stage2Tlb()->setMMU(this);
+    // we use the stage-one table walker as the parent of the port,
+    // and to get our master id, this is done to keep things
+    // symmetrical with other ISAs in terms of naming and stats
+    stage1Tlb()->setMMU(this, masterId);
+    stage2Tlb()->setMMU(this, masterId);
 }
 
 Fault
 Stage2MMU::readDataUntimed(ThreadContext *tc, Addr oVAddr, Addr descAddr,
-    uint8_t *data, int numBytes, Request::Flags flags, int masterId,
-    bool isFunctional)
+    uint8_t *data, int numBytes, Request::Flags flags, bool isFunctional)
 {
     Fault fault;
 
@@ -77,9 +79,9 @@
         Packet pkt = Packet(&req, MemCmd::ReadReq);
         pkt.dataStatic(data);
         if (isFunctional) {
-            stage1Tlb()->getWalkerPort().sendFunctional(&pkt);
+            port.sendFunctional(&pkt);
         } else {
-            stage1Tlb()->getWalkerPort().sendAtomic(&pkt);
+            port.sendAtomic(&pkt);
         }
         assert(!pkt.isError());
     }
@@ -96,8 +98,8 @@
 
 Fault
 Stage2MMU::readDataTimed(ThreadContext *tc, Addr descAddr,
-    Stage2Translation *translation, int numBytes, Request::Flags flags,
-    int masterId)
+                         Stage2Translation *translation, int numBytes,
+                         Request::Flags flags)
 {
     Fault fault;
     // translate to physical address using the second stage MMU
@@ -128,10 +130,9 @@
     }
 
     if (_fault == NoFault && !req->getFlags().isSet(Request::NO_ACCESS)) {
-        DmaPort& port = parent.stage1Tlb()->getWalkerPort();
-        port.dmaAction(MemCmd::ReadReq, req->getPaddr(), numBytes,
-                       event, data, tc->getCpuPtr()->clockPeriod(),
-                       req->getFlags());
+        parent.getPort().dmaAction(MemCmd::ReadReq, req->getPaddr(), numBytes,
+                                   event, data, tc->getCpuPtr()->clockPeriod(),
+                                   req->getFlags());
     } else {
         // We can't do the DMA access as there's been a problem, so tell the
         // event we're done
@@ -139,6 +140,12 @@
     }
 }
 
+unsigned int
+Stage2MMU::drain(DrainManager *dm)
+{
+    return port.drain(dm);
+}
+
 ArmISA::Stage2MMU *
 ArmStage2MMUParams::create()
 {
diff -r 4408a83f7881 -r 4f8c1bd6fdb8 src/arch/arm/stage2_mmu.hh
--- a/src/arch/arm/stage2_mmu.hh        Mon Mar 02 04:00:41 2015 -0500
+++ b/src/arch/arm/stage2_mmu.hh        Mon Mar 02 04:00:42 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 ARM Limited
+ * Copyright (c) 2012-2013, 2015 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -55,6 +55,46 @@
     /** The TLB that will cache the stage 2 look ups. */
     TLB *_stage2Tlb;
 
+  protected:
+
+    /**
+     * A snooping DMA port that currently does nothing besides
+     * extending the DMA port to accept snoops without
+     * complaining. Currently we take no action on any snoops.
+     */
+    class SnoopingDmaPort : public DmaPort
+    {
+
+      protected:
+
+        virtual void recvTimingSnoopReq(PacketPtr pkt)
+        { }
+
+        virtual Tick recvAtomicSnoop(PacketPtr pkt)
+        { return 0; }
+
+        virtual void recvFunctionalSnoop(PacketPtr pkt)
+        { }
+
+        virtual bool isSnooping() const { return true; }
+
+      public:
+
+        /**
+         * A snooping DMA port merely calls the construtor of the DMA
+         * port.
+         */
+        SnoopingDmaPort(MemObject *dev, System *s) :
+            DmaPort(dev, s)
+        { }
+    };
+
+    /** Port to issue translation requests from */
+    SnoopingDmaPort port;
+
+    /** Request id for requests generated by this MMU */
+    MasterID masterId;
+
   public:
     /** This translation class is used to trigger the data fetch once a timing
         translation returns the translated physical address */
@@ -96,12 +136,20 @@
     typedef ArmStage2MMUParams Params;
     Stage2MMU(const Params *p);
 
+    /**
+     * Get the port that ultimately belongs to the stage-two MMU, but
+     * is used by the two table walkers, and is exposed externally and
+     * connected through the stage-one table walker.
+     */
+    DmaPort& getPort() { return port; }
+
+    unsigned int drain(DrainManager *dm);
+
     Fault readDataUntimed(ThreadContext *tc, Addr oVAddr, Addr descAddr,
-        uint8_t *data, int numBytes, Request::Flags flags, int masterId,
-        bool isFunctional);
+        uint8_t *data, int numBytes, Request::Flags flags, bool isFunctional);
     Fault readDataTimed(ThreadContext *tc, Addr descAddr,
-        Stage2Translation *translation, int numBytes, Request::Flags flags,
-        int masterId);
+                        Stage2Translation *translation, int numBytes,
+                        Request::Flags flags);
 
     TLB* stage1Tlb() const { return _stage1Tlb; }
     TLB* stage2Tlb() const { return _stage2Tlb; }
diff -r 4408a83f7881 -r 4f8c1bd6fdb8 src/arch/arm/table_walker.cc
--- a/src/arch/arm/table_walker.cc      Mon Mar 02 04:00:41 2015 -0500
+++ b/src/arch/arm/table_walker.cc      Mon Mar 02 04:00:42 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012-2014 ARM Limited
+ * Copyright (c) 2010, 2012-2015 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -56,9 +56,10 @@
 using namespace ArmISA;
 
 TableWalker::TableWalker(const Params *p)
-    : MemObject(p), port(this, p->sys), drainManager(NULL),
-      stage2Mmu(NULL), isStage2(p->is_stage2), tlb(NULL),
-      currState(NULL), pending(false), masterId(p->sys->getMasterId(name())),
+    : MemObject(p), drainManager(NULL),
+      stage2Mmu(NULL), port(NULL), masterId(Request::invldMasterId),
+      isStage2(p->is_stage2), tlb(NULL),
+      currState(NULL), pending(false),
       numSquashable(p->num_squash_per_cycle),
       pendingReqs(0),
       pendingChangeTick(curTick()),
@@ -71,7 +72,7 @@
 
     // Cache system-level properties
     if (FullSystem) {
-        armSys = dynamic_cast<ArmSystem *>(p->sys);
+        ArmSystem *armSys = dynamic_cast<ArmSystem *>(p->sys);
         assert(armSys);
         haveSecurity = armSys->haveSecurity();
         _haveLPAE = armSys->haveLPAE();
@@ -79,7 +80,6 @@
         physAddrRange = armSys->physAddrRange();
         _haveLargeAsid64 = armSys->haveLargeAsid64();
     } else {
-        armSys = NULL;
         haveSecurity = _haveLPAE = _haveVirtualization = false;
         _haveLargeAsid64 = false;
         physAddrRange = 32;
@@ -92,6 +92,35 @@
     ;
 }
 
+void
+TableWalker::setMMU(Stage2MMU *m, MasterID master_id)
+{
+    stage2Mmu = m;
+    port = &m->getPort();
+    masterId = master_id;
+}
+
+void
+TableWalker::init()
+{
+    fatal_if(!stage2Mmu, "Table walker must have a valid stage-2 MMU\n");
+    fatal_if(!port, "Table walker must have a valid port\n");
+    fatal_if(!tlb, "Table walker must have a valid TLB\n");
+}
+
+BaseMasterPort&
+TableWalker::getMasterPort(const std::string &if_name, PortID idx)
+{
+    if (if_name == "port") {
+        if (!isStage2) {
+            return *port;
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to