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 <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>
This commit is contained in:
@@ -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'
|
||||
|
||||
@@ -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<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,
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user