Giacomo Travaglini has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/45599 )

Change subject: arch-arm: Stop using the DmaPort in the TableWalker
......................................................................

arch-arm: Stop using the DmaPort in the TableWalker

Using a custom TableWalker port instead

Signed-off-by: Giacomo Travaglini <[email protected]>
Change-Id: I9e77324569ef0f74f6c8a3941f90bc988abf3c57
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/45599
Reviewed-by: Andreas Sandberg <[email protected]>
Reviewed-by: Daniel Carvalho <[email protected]>
Maintainer: Andreas Sandberg <[email protected]>
Tested-by: kokoro <[email protected]>
---
M src/arch/arm/stage2_mmu.cc
M src/arch/arm/stage2_mmu.hh
M src/arch/arm/table_walker.cc
M src/arch/arm/table_walker.hh
M src/arch/arm/tlb.cc
5 files changed, 173 insertions(+), 35 deletions(-)

Approvals:
  Andreas Sandberg: Looks good to me, approved; Looks good to me, approved
  Daniel Carvalho: Looks good to me, but someone else must approve
  kokoro: Regressions pass



diff --git a/src/arch/arm/stage2_mmu.cc b/src/arch/arm/stage2_mmu.cc
index a741537..0071bd8 100644
--- a/src/arch/arm/stage2_mmu.cc
+++ b/src/arch/arm/stage2_mmu.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, 2015 ARM Limited
+ * Copyright (c) 2012-2013, 2015, 2021 Arm Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -48,8 +48,8 @@

 Stage2MMU::Stage2MMU(const Params &p)
     : SimObject(p), _stage1Tlb(p.tlb), _stage2Tlb(p.stage2_tlb),
-      port(_stage1Tlb->getTableWalker(), p.sys),
-      requestorId(p.sys->getRequestorId(_stage1Tlb->getTableWalker()))
+      requestorId(p.sys->getRequestorId(_stage1Tlb->getTableWalker())),
+      port(_stage1Tlb->getTableWalker(), requestorId)
 {
     // we use the stage-one table walker as the parent of the port,
     // and to get our requestor id, this is done to keep things
@@ -131,9 +131,10 @@
     }

     if (_fault == NoFault && !req->getFlags().isSet(Request::NO_ACCESS)) {
-        parent.getDMAPort().dmaAction(
-            MemCmd::ReadReq, req->getPaddr(), numBytes, event, data,
-            tc->getCpuPtr()->clockPeriod(), req->getFlags());
+        TableWalker::Port &port = parent.getTableWalkerPort();
+        port.sendTimingReq(
+            req->getPaddr(), numBytes, data, req->getFlags(),
+            tc->getCpuPtr()->clockPeriod(), event);
     } else {
// We can't do the DMA access as there's been a problem, so tell the
         // event we're done
diff --git a/src/arch/arm/stage2_mmu.hh b/src/arch/arm/stage2_mmu.hh
index c416b15..ebf6820 100644
--- a/src/arch/arm/stage2_mmu.hh
+++ b/src/arch/arm/stage2_mmu.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, 2015 ARM Limited
+ * Copyright (c) 2012-2013, 2015, 2021 Arm Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -39,8 +39,8 @@
 #define __ARCH_ARM_STAGE2_MMU_HH__

 #include "arch/arm/faults.hh"
+#include "arch/arm/table_walker.hh"
 #include "arch/arm/tlb.hh"
-#include "dev/dma_device.hh"
 #include "mem/request.hh"
 #include "params/ArmStage2MMU.hh"
 #include "sim/eventq.hh"
@@ -55,13 +55,12 @@
     TLB *_stage2Tlb;

   protected:
-
-    /** Port to issue translation requests from */
-    DmaPort port;
-
     /** Request id for requests generated by this MMU */
     RequestorID requestorId;

+    /** Port to issue translation requests from */
+    TableWalker::Port port;
+
   public:
/** This translation class is used to trigger the data fetch once a timing
         translation returns the translated physical address */
@@ -109,7 +108,7 @@
      * is used by the two table walkers, and is exposed externally and
      * connected through the stage-one table walker.
      */
-    DmaPort& getDMAPort() { return port; }
+    TableWalker::Port& getTableWalkerPort() { return port; }

     Fault readDataUntimed(ThreadContext *tc, Addr oVAddr, Addr descAddr,
uint8_t *data, int numBytes, Request::Flags flags, bool isFunctional);
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index 2452ebc..e135cb8 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012-2019 ARM Limited
+ * Copyright (c) 2010, 2012-2019, 2021 Arm Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -36,6 +36,7 @@
  */
 #include "arch/arm/table_walker.hh"

+#include <cassert>
 #include <memory>

 #include "arch/arm/faults.hh"
@@ -50,7 +51,6 @@
 #include "debug/PageTableWalker.hh"
 #include "debug/TLB.hh"
 #include "debug/TLBVerbose.hh"
-#include "dev/dma_device.hh"
 #include "sim/system.hh"

 using namespace ArmISA;
@@ -102,7 +102,7 @@
 TableWalker::setMMU(Stage2MMU *m, RequestorID requestor_id)
 {
     stage2Mmu = m;
-    port = &m->getDMAPort();
+    port = &m->getTableWalkerPort();
     requestorId = requestor_id;
 }

@@ -143,6 +143,107 @@
 {
 }

+TableWalker::Port::Port(TableWalker *_walker, RequestorID id)
+  : QueuedRequestPort(_walker->name() + ".port", _walker,
+        reqQueue, snoopRespQueue),
+    reqQueue(*_walker, *this), snoopRespQueue(*_walker, *this),
+    requestorId(id)
+{
+}
+
+PacketPtr
+TableWalker::Port::createPacket(
+    Addr desc_addr, int size,
+    uint8_t *data, Request::Flags flags, Tick delay,
+    Event *event)
+{
+    RequestPtr req = std::make_shared<Request>(
+        desc_addr, size, flags, requestorId);
+    req->taskId(ContextSwitchTaskId::DMA);
+
+    PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
+    pkt->dataStatic(data);
+
+    auto state = new TableWalkerState;
+    state->event = event;
+    state->delay = delay;
+
+    pkt->senderState = state;
+    return pkt;
+}
+
+void
+TableWalker::Port::sendFunctionalReq(
+    Addr desc_addr, int size,
+    uint8_t *data, Request::Flags flags)
+{
+    auto pkt = createPacket(desc_addr, size, data, flags, 0, nullptr);
+
+    sendFunctional(pkt);
+
+    handleRespPacket(pkt);
+}
+
+void
+TableWalker::Port::sendAtomicReq(
+    Addr desc_addr, int size,
+    uint8_t *data, Request::Flags flags, Tick delay)
+{
+    auto pkt = createPacket(desc_addr, size, data, flags, delay, nullptr);
+
+    Tick lat = sendAtomic(pkt);
+
+    handleRespPacket(pkt, lat);
+}
+
+void
+TableWalker::Port::sendTimingReq(
+    Addr desc_addr, int size,
+    uint8_t *data, Request::Flags flags, Tick delay,
+    Event *event)
+{
+    auto pkt = createPacket(desc_addr, size, data, flags, delay, event);
+
+    schedTimingReq(pkt, curTick());
+}
+
+bool
+TableWalker::Port::recvTimingResp(PacketPtr pkt)
+{
+    // We shouldn't ever get a cacheable block in Modified state.
+    assert(pkt->req->isUncacheable() ||
+           !(pkt->cacheResponding() && !pkt->hasSharers()));
+
+    handleRespPacket(pkt);
+
+    return true;
+}
+
+void
+TableWalker::Port::handleRespPacket(PacketPtr pkt, Tick delay)
+{
+    // Should always see a response with a sender state.
+    assert(pkt->isResponse());
+
+    // Get the DMA sender state.
+    auto *state = dynamic_cast<TableWalkerState*>(pkt->senderState);
+    assert(state);
+
+    handleResp(state, pkt->getAddr(), pkt->req->getSize(), delay);
+
+    delete pkt;
+}
+
+void
+TableWalker::Port::handleResp(TableWalkerState *state, Addr addr,
+                              Addr size, Tick delay)
+{
+    if (state->event) {
+        owner.schedule(state->event, curTick() + delay);
+    }
+    delete state;
+}
+
 void
 TableWalker::completeDrain()
 {
@@ -2158,8 +2259,9 @@
         }
     } else {
         if (isTiming) {
- port->dmaAction(MemCmd::ReadReq, descAddr, numBytes, event, data, - currState->tc->getCpuPtr()->clockPeriod(),flags);
+            port->sendTimingReq(descAddr, numBytes, data, flags,
+                currState->tc->getCpuPtr()->clockPeriod(), event);
+
             if (queueIndex >= 0) {
                 DPRINTF(PageTableWalker, "Adding to walker fifo: "
                         "queue size before adding: %d\n",
@@ -2168,19 +2270,13 @@
                 currState = NULL;
             }
         } else if (!currState->functional) {
- port->dmaAction(MemCmd::ReadReq, descAddr, numBytes, NULL, data, - currState->tc->getCpuPtr()->clockPeriod(), flags);
+            port->sendAtomicReq(descAddr, numBytes, data, flags,
+                currState->tc->getCpuPtr()->clockPeriod());
+
             (this->*doDescriptor)();
         } else {
-            RequestPtr req = std::make_shared<Request>(
-                descAddr, numBytes, flags, requestorId);
-
-            req->taskId(ContextSwitchTaskId::DMA);
-            PacketPtr  pkt = new Packet(req, MemCmd::ReadReq);
-            pkt->dataStatic(data);
-            port->sendFunctional(pkt);
+            port->sendFunctionalReq(descAddr, numBytes, data, flags);
             (this->*doDescriptor)();
-            delete pkt;
         }
     }
     return (isTiming);
diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh
index 7788747..4b52be6 100644
--- a/src/arch/arm/table_walker.hh
+++ b/src/arch/arm/table_walker.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2016, 2019 ARM Limited
+ * Copyright (c) 2010-2016, 2019, 2021 Arm Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -45,6 +45,8 @@
 #include "arch/arm/system.hh"
 #include "arch/arm/tlb.hh"
 #include "arch/arm/types.hh"
+#include "mem/packet_queue.hh"
+#include "mem/qport.hh"
 #include "mem/request.hh"
 #include "params/ArmTableWalker.hh"
 #include "sim/clocked_object.hh"
@@ -52,8 +54,6 @@

 class ThreadContext;

-class DmaPort;
-
 namespace ArmISA {
 class Translation;
 class TLB;
@@ -855,6 +855,48 @@
         std::string name() const { return tableWalker->name(); }
     };

+    class TableWalkerState : public Packet::SenderState
+    {
+      public:
+        Tick delay = 0;
+        Event *event = nullptr;
+    };
+
+    class Port : public QueuedRequestPort
+    {
+      public:
+        Port(TableWalker* _walker, RequestorID id);
+
+        void sendFunctionalReq(Addr desc_addr, int size,
+            uint8_t *data, Request::Flags flag);
+        void sendAtomicReq(Addr desc_addr, int size,
+            uint8_t *data, Request::Flags flag, Tick delay);
+        void sendTimingReq(Addr desc_addr, int size,
+            uint8_t *data, Request::Flags flag, Tick delay,
+            Event *event);
+
+        bool recvTimingResp(PacketPtr pkt) override;
+
+      private:
+        void handleRespPacket(PacketPtr pkt, Tick delay=0);
+        void handleResp(TableWalkerState *state, Addr addr,
+                        Addr size, Tick delay=0);
+
+        PacketPtr createPacket(Addr desc_addr, int size,
+                               uint8_t *data, Request::Flags flag,
+                               Tick delay, Event *event);
+
+      private:
+        /** Packet queue used to store outgoing requests. */
+        ReqPacketQueue reqQueue;
+
+        /** Packet queue used to store outgoing snoop responses. */
+        SnoopRespPacketQueue snoopRespQueue;
+
+        /** Cached requestorId of the table walker */
+        RequestorID requestorId;
+    };
+
   protected:

     /** Queues of requests for all the different lookup levels */
@@ -868,7 +910,7 @@
     Stage2MMU *stage2Mmu;

     /** Port shared by the two table walkers. */
-    DmaPort* port;
+    Port* port;

     /** Requestor id assigned by the MMU. */
     RequestorID requestorId;
@@ -938,8 +980,8 @@
     DrainState drain() override;
     void drainResume() override;

-    Port &getPort(const std::string &if_name,
-                  PortID idx=InvalidPortID) override;
+    ::Port &getPort(const std::string &if_name,
+                    PortID idx=InvalidPortID) override;

     Fault walk(const RequestPtr &req, ThreadContext *tc,
                uint16_t asid, vmid_t _vmid,
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index 2571eaf..cd8155c 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -1374,7 +1374,7 @@
 Port *
 TLB::getTableWalkerPort()
 {
-    return &stage2Mmu->getDMAPort();
+    return &stage2Mmu->getTableWalkerPort();
 }

 vmid_t

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/45599
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I9e77324569ef0f74f6c8a3941f90bc988abf3c57
Gerrit-Change-Number: 45599
Gerrit-PatchSet: 6
Gerrit-Owner: Giacomo Travaglini <[email protected]>
Gerrit-Reviewer: Andreas Sandberg <[email protected]>
Gerrit-Reviewer: Daniel Carvalho <[email protected]>
Gerrit-Reviewer: Giacomo Travaglini <[email protected]>
Gerrit-Reviewer: kokoro <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to