dev: StreamID generation in DMA device
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Mon, 28 Jan 2019 12:37:51 +0000 (12:37 +0000)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Fri, 3 May 2019 08:38:12 +0000 (08:38 +0000)
This patch is adding a StreamID tag to any DMA Packet. StreamIDs are
tags which are used by IOMMUs to distinguish between different
devices/functions.

For PCI devices for example, the RID (Pci Bus number, Pci Device
number, Pci Function number) could be stored in the Packet streamID
field.

For the DmaDevice base class, a simple pair of (Sub)StreamIDs has been
provided.  This is basically attaching a fixed (decided at python config
time) streamID per device.  If a derived device wants to implement a
more elaborate packet tagger (for example if it wants to have more than
one streamID), it needs to pass a different StreamID and SubstreamID to
the DmaPort interface (like dmaAction).

Change-Id: Ia17cf00437f7d3eb79211c1374134b174f90de59
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/16749
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/dev/Device.py
src/dev/dma_device.cc
src/dev/dma_device.hh

index cb990104df00f984e39da84e6f4dab2d20df91e6..0023f97a2ddfc9a279aebd553e02f6ee291f3157 100644 (file)
@@ -84,6 +84,13 @@ class DmaDevice(PioDevice):
     abstract = True
     dma = MasterPort("DMA port")
 
+    sid = Param.Unsigned(0,
+        "Stream identifier used by an IOMMU to distinguish amongst "
+        "several devices attached to it")
+    ssid = Param.Unsigned(0,
+        "Substream identifier used by an IOMMU to distinguish amongst "
+        "several devices attached to it")
+
 
 class IsaFake(BasicPioDevice):
     type = 'IsaFake'
index 327c92436c95060d723d0b14a7303c870485fd92..1f8f0beb79490a7d80e1de3efe627d70cce7028c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, 2017 ARM Limited
+ * Copyright (c) 2012, 2015, 2017, 2019 ARM Limited
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
 #include "sim/clocked_object.hh"
 #include "sim/system.hh"
 
-DmaPort::DmaPort(ClockedObject *dev, System *s)
+DmaPort::DmaPort(ClockedObject *dev, System *s,
+                 uint32_t sid, uint32_t ssid)
     : MasterPort(dev->name() + ".dma", dev),
       device(dev), sys(s), masterId(s->getMasterId(dev)),
       sendEvent([this]{ sendDma(); }, dev->name()),
-      pendingCount(0), inRetry(false)
+      pendingCount(0), inRetry(false),
+      defaultSid(sid),
+      defaultSSid(ssid)
 { }
 
 void
@@ -117,7 +120,7 @@ DmaPort::recvTimingResp(PacketPtr pkt)
 }
 
 DmaDevice::DmaDevice(const Params *p)
-    : PioDevice(p), dmaPort(this, sys)
+    : PioDevice(p), dmaPort(this, sys, p->sid, p->ssid)
 { }
 
 void
@@ -148,7 +151,8 @@ DmaPort::recvReqRetry()
 
 RequestPtr
 DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
-                   uint8_t *data, Tick delay, Request::Flags flag)
+                   uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay,
+                   Request::Flags flag)
 {
     // one DMA request sender state for every action, that is then
     // split into many requests and packets based on the block size,
@@ -169,6 +173,9 @@ DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
         req = std::make_shared<Request>(
             gen.addr(), gen.size(), flag, masterId);
 
+        req->setStreamId(sid);
+        req->setSubStreamId(ssid);
+
         req->taskId(ContextSwitchTaskId::DMA);
         PacketPtr pkt = new Packet(req, cmd);
 
@@ -191,6 +198,14 @@ DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
     return req;
 }
 
+RequestPtr
+DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
+                   uint8_t *data, Tick delay, Request::Flags flag)
+{
+    return dmaAction(cmd, addr, size, event, data,
+                     defaultSid, defaultSSid, delay, flag);
+}
+
 void
 DmaPort::queueDma(PacketPtr pkt)
 {
@@ -272,10 +287,6 @@ DmaDevice::getPort(const std::string &if_name, PortID idx)
     return PioDevice::getPort(if_name, idx);
 }
 
-
-
-
-
 DmaReadFifo::DmaReadFifo(DmaPort &_port, size_t size,
                          unsigned max_req_size,
                          unsigned max_pending,
index 4ea0626544090f267fda7bfd23c319a26fd71f9f..8c2b6e26dbda9a7f62a097f5f986709a16d26d09 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, 2015, 2017 ARM Limited
+ * Copyright (c) 2012-2013, 2015, 2017, 2019 ARM Limited
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
@@ -134,6 +134,12 @@ class DmaPort : public MasterPort, public Drainable
      * send whatever it is that it's sending. */
     bool inRetry;
 
+    /** Default streamId */
+    const uint32_t defaultSid;
+
+    /** Default substreamId */
+    const uint32_t defaultSSid;
+
   protected:
 
     bool recvTimingResp(PacketPtr pkt) override;
@@ -143,10 +149,17 @@ class DmaPort : public MasterPort, public Drainable
 
   public:
 
-    DmaPort(ClockedObject *dev, System *s);
+    DmaPort(ClockedObject *dev, System *s,
+            uint32_t sid = 0, uint32_t ssid = 0);
+
+    RequestPtr
+    dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
+              uint8_t *data, Tick delay, Request::Flags flag = 0);
 
-    RequestPtr dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
-                         uint8_t *data, Tick delay, Request::Flags flag = 0);
+    RequestPtr
+    dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
+              uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay,
+              Request::Flags flag = 0);
 
     bool dmaPending() const { return pendingCount > 0; }
 
@@ -163,12 +176,26 @@ class DmaDevice : public PioDevice
     DmaDevice(const Params *p);
     virtual ~DmaDevice() { }
 
+    void dmaWrite(Addr addr, int size, Event *event, uint8_t *data,
+                  uint32_t sid, uint32_t ssid, Tick delay = 0)
+    {
+        dmaPort.dmaAction(MemCmd::WriteReq, addr, size, event, data,
+                          sid, ssid, delay);
+    }
+
     void dmaWrite(Addr addr, int size, Event *event, uint8_t *data,
                   Tick delay = 0)
     {
         dmaPort.dmaAction(MemCmd::WriteReq, addr, size, event, data, delay);
     }
 
+    void dmaRead(Addr addr, int size, Event *event, uint8_t *data,
+                 uint32_t sid, uint32_t ssid, Tick delay = 0)
+    {
+        dmaPort.dmaAction(MemCmd::ReadReq, addr, size, event, data,
+                          sid, ssid, delay);
+    }
+
     void dmaRead(Addr addr, int size, Event *event, uint8_t *data,
                  Tick delay = 0)
     {