From b6d60e82ddfed6a67be4d334841b77d9e8813c0b Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Mon, 28 Jan 2019 12:37:51 +0000 Subject: [PATCH] dev: StreamID generation in DMA device 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 Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/16749 Reviewed-by: Daniel Carvalho Maintainer: Andreas Sandberg Tested-by: kokoro --- src/dev/Device.py | 7 +++++++ src/dev/dma_device.cc | 29 ++++++++++++++++++++--------- src/dev/dma_device.hh | 35 +++++++++++++++++++++++++++++++---- 3 files changed, 58 insertions(+), 13 deletions(-) diff --git a/src/dev/Device.py b/src/dev/Device.py index cb990104d..0023f97a2 100644 --- a/src/dev/Device.py +++ b/src/dev/Device.py @@ -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' diff --git a/src/dev/dma_device.cc b/src/dev/dma_device.cc index 327c92436..1f8f0beb7 100644 --- a/src/dev/dma_device.cc +++ b/src/dev/dma_device.cc @@ -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 @@ -54,11 +54,14 @@ #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( 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, diff --git a/src/dev/dma_device.hh b/src/dev/dma_device.hh index 4ea062654..8c2b6e26d 100644 --- a/src/dev/dma_device.hh +++ b/src/dev/dma_device.hh @@ -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) { -- 2.30.2