51 #include "debug/DMA.hh" 52 #include "debug/Drain.hh" 58 uint32_t sid, uint32_t ssid)
60 device(dev), sys(s), masterId(s->getMasterId(dev)),
77 DPRINTF(
DMA,
"Received response %s for addr: %#x size: %d nb: %d," \
78 " tot: %d sched %d\n",
80 state->numBytes, state->totBytes,
81 state->completionEvent ?
82 state->completionEvent->scheduled() : 0);
89 state->numBytes += pkt->
req->getSize();
90 assert(state->totBytes >= state->numBytes);
94 if (state->totBytes == state->numBytes) {
95 if (state->completionEvent) {
96 delay += state->delay;
114 assert(pkt->
req->isUncacheable() ||
130 panic(
"DMA port of %s not connected to anything!",
name());
137 if (pendingCount == 0) {
140 DPRINTF(Drain,
"DmaPort not drained\n");
148 assert(transmitList.size());
154 uint8_t *
data, uint32_t sid, uint32_t ssid,
Tick delay,
168 DPRINTF(
DMA,
"Starting DMA for addr: %#x size: %d sched: %d\n", addr, size,
171 !gen.
done(); gen.next()) {
173 req = std::make_shared<Request>(
174 gen.addr(), gen.size(), flag, masterId);
176 req->setStreamId(sid);
177 req->setSubStreamId(ssid);
188 DPRINTF(
DMA,
"--Queuing DMA for addr: %#x size: %d\n", gen.addr(),
205 return dmaAction(cmd, addr, size, event, data,
206 defaultSid, defaultSSid, delay, flag);
212 transmitList.push_back(pkt);
229 inRetry = !sendTimingReq(pkt);
231 transmitList.pop_front();
234 if (!transmitList.empty())
241 DPRINTF(
DMA,
"-- Failed, waiting for retry\n");
244 DPRINTF(
DMA,
"TransmitList: %d, inRetry: %d\n",
245 transmitList.size(), inRetry);
254 assert(transmitList.size());
260 DPRINTF(
DMA,
"Can't send immediately, waiting to send\n");
267 while (!transmitList.empty()) {
269 transmitList.pop_front();
271 DPRINTF(
DMA,
"Sending DMA for addr: %#x size: %d\n",
272 pkt->
req->getPaddr(), pkt->
req->getSize());
273 Tick lat = sendAtomic(pkt);
275 handleResp(pkt, lat);
278 panic(
"Unknown memory mode.");
284 if (if_name ==
"dma") {
291 unsigned max_req_size,
292 unsigned max_pending,
294 : maxReqSize(max_req_size), fifoSize(size),
295 reqFlags(flags), port(_port),
297 nextAddr(0), endAddr(0)
354 const bool success(
tryGet(dst, len));
355 panic_if(!success,
"Buffer underrun in DmaReadFifo::get()\n");
405 if (fifo_space >= kvm_watermark ||
buffer.
capacity() < kvm_watermark) {
407 const size_t xfer_size = std::min(fifo_space, block_remaining);
411 DPRINTF(
DMA,
"KVM Bypassing startAddr=%#x xfer_size=%#x " \
412 "fifo_space=%#x block_remaining=%#x\n",
413 nextAddr, xfer_size, fifo_space, block_remaining);
417 nextAddr += xfer_size;
424 size_t size_pending(0);
426 size_pending +=
e->requestSize();
437 event->reset(req_size);
441 size_pending += req_size;
443 pendingRequests.emplace_back(std::move(event));
467 if (!event->canceled())
487 : parent(_parent), _done(false), _canceled(false), _data(max_size, 0)
507 assert(size <=
_data.size());
A MasterPort is a specialisation of a BaseMasterPort, which implements the default protocol for the t...
#define panic(...)
This implements a cprintf based panic() function.
void write(InputIterator in, size_t len)
Ports are used to interface objects to each other.
void queueDma(PacketPtr pkt)
std::unique_ptr< DmaDoneEvent > DmaDoneEventUPtr
Cycles is a wrapper class for representing cycle counts, i.e.
const std::string & name()
void serialize(CheckpointOut &cp) const override
Serialize an object.
DmaPort(ClockedObject *dev, System *s, uint32_t sid=0, uint32_t ssid=0)
Buffered DMA engine helper class.
void startFill(Addr start, size_t size)
Start filling the FIFO.
DrainState
Object drain/handover states.
ClockedObject *const device
The device that owns this port.
std::shared_ptr< Request > RequestPtr
bool recvTimingResp(PacketPtr pkt) override
Receive a timing response from the peer.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
bool cacheResponding() const
DrainState drainState() const
Return the current drain state of an object.
void signalDrainDone() const
Signal that an object is drained.
void trySendTimingReq()
Take the first packet of the transmit list and attempt to send it as a timing request.
uint32_t pendingCount
Number of outstanding packets the dma port has.
bool isConnected() const
Is this port currently connected to a peer?
void handleResp(PacketPtr pkt, Tick delay=0)
Handle a response packet by updating the corresponding DMA request state to reflect the bytes receive...
void handlePending()
Handle pending requests that have been flagged as done.
const Request::Flags reqFlags
Request flags.
std::deque< DmaDoneEventUPtr > freeRequests
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
static const FlagsType AutoDelete
RequestPtr req
A pointer to the original request.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
PortProxy physProxy
Port to physical memory used for writing object files into ram at boot.
#define UNSERIALIZE_SCALAR(scalar)
#define SERIALIZE_CONTAINER(member)
PortProxy Object Declaration.
bool isAtomicMode() const
Is the system in atomic mode?
Tick curTick()
The current simulated tick.
void sendDma()
For timing, attempt to send the first item on the transmit list, and if it is successful and there ar...
DmaDoneEvent(DmaReadFifo *_parent, size_t max_size)
DmaDevice(const Params *p)
bool scheduled() const
Determine if the current event is scheduled.
void stopFill()
Stop the DMA engine.
void dmaDone()
DMA request done, handle incoming data and issue new request.
uint64_t Tick
Tick count type.
void recvReqRetry() override
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
This class takes an arbitrary memory region (address/length pair) and generates a series of appropria...
ClockedObject declaration and implementation.
const Addr maxReqSize
Maximum request size in bytes.
std::vector< uint8_t > _data
virtual void onIdle()
Last response received callback.
const size_t fifoSize
Maximum FIFO size in bytes.
void setFlags(Flags _flags)
Accessor for flags.
This device is the base class which all devices senstive to an address range inherit from...
#define UNSERIALIZE_CONTAINER(member)
virtual void onEndOfBlock()
End of block callback.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
DrainState drain() override
Notify an object that it needs to drain its state.
Draining buffers pending serialization/handover.
virtual const std::string name() const
bool done() const
Are we done? That is, did the last call to next() advance past the end of the region?
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
System *const sys
The system that device/port are in.
void resumeFillFunctional()
Try to bypass DMA requests in KVM execution mode.
void readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
RequestPtr dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
DrainState drain() override
Notify an object that it needs to drain its state.
void sendEvent(ThreadContext *tc)
Send an event (SEV) to a specific PE if there isn't already a pending event.
#define SERIALIZE_SCALAR(scalar)
void unserialize(CheckpointIn &cp) override
Unserialize an object.
std::deque< DmaDoneEventUPtr > pendingRequests
bool isActive() const
Is the DMA engine active (i.e., are there still in-flight accesses)?
const uint32_t defaultSSid
Default substreamId.
void resumeFill()
Try to issue new DMA requests or bypass DMA requests.
const uint32_t defaultSid
Default streamId.
std::ostream CheckpointOut
SenderState * senderState
This packet's sender state.
bool bypassCaches() const
Should caches be bypassed?
void schedule(Event &event, Tick when)
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
void resumeFillTiming()
Try to issue new DMA requests during normal execution.
bool tryGet(uint8_t *dst, size_t len)
Try to read data from the FIFO.
bool atEndOfBlock() const
Has the DMA engine sent out the last request for the active block?
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
DmaReadFifo(DmaPort &port, size_t size, unsigned max_req_size, unsigned max_pending, Request::Flags flags=0)
size_t size() const
Get the amount of data stored in the FIFO.
Declaration and inline definition of ChunkGenerator object.
Command
List of all commands associated with a packet.
bool isTimingMode() const
Is the system in timing mode?
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
bool inRetry
If the port is currently waiting for a retry before it can send whatever it is that it's sending...
void read(OutputIterator out, size_t len)
ProbePointArg< PacketInfo > Packet
Packet probe point.
unsigned int cacheLineSize() const
Get the cache line size of the system.