Go to the documentation of this file.
50 #include "debug/DMA.hh"
51 #include "debug/Drain.hh"
59 uint32_t sid, uint32_t ssid)
61 device(dev), sys(
s), requestorId(
s->getRequestorId(dev)),
63 defaultSid(sid), defaultSSid(ssid), cacheLineSize(
s->cacheLineSize())
87 DPRINTF(
DMA,
"Received response %s for addr: %#x size: %d nb: %d," \
88 " tot: %d sched %d\n",
91 state->completionEvent ?
92 state->completionEvent->scheduled() : 0);
96 state->numBytes += size;
99 bool all_bytes = (
state->totBytes ==
state->numBytes);
100 if (
state->aborted) {
107 if (
state->abortEvent) {
112 }
else if (all_bytes) {
115 if (
state->completionEvent) {
116 delay +=
state->delay;
132 req->setStreamId(
sid);
133 req->setSubstreamId(
ssid);
149 assert(pkt->
req->isUncacheable() ||
165 "DMA port of %s not connected to anything!",
name());
175 DPRINTF(Drain,
"DmaPort not drained\n");
190 uint8_t *
data, uint32_t sid, uint32_t ssid,
Tick delay,
193 DPRINTF(
DMA,
"Starting DMA for addr: %#x size: %d sched: %d\n",
addr, size,
227 if (
state->numBytes !=
state->gen.complete()) {
233 state->aborted =
true;
240 if (
state->abortEvent)
268 bool last =
state->gen.last();
289 DPRINTF(
DMA,
"-- Failed, waiting for retry\n");
292 DPRINTF(
DMA,
"TransmitList: %d, retryPending: %d\n",
300 DPRINTF(
DMA,
"Sending DMA for addr: %#x size: %d\n",
306 bool done = !
state->gen.next();
322 DPRINTF(
DMA,
"Sending DMA for addr: %#x size: %d\n",
331 auto callback = [
this](
const MemBackdoor &backdoor) {
334 if (it->second == &backdoor) {
339 panic(
"Got invalidation for unknown memory backdoor.");
341 bd->addInvalidationCallback(callback);
345 done = !
state->gen.next();
349 DPRINTF(
DMA,
"Handling DMA for addr: %#x size %d through backdoor\n",
352 const auto *
bd = bd_it->second;
361 const Addr handled = std::min(remaining, available);
365 uint8_t *bd_data =
bd->ptr() +
offset;
366 uint8_t *state_data =
state->data +
state->gen.complete();
368 memcpy(state_data, bd_data, handled);
370 memcpy(bd_data, state_data, handled);
374 state->gen.setNext(
state->gen.addr() + handled);
377 done = !
state->gen.next();
395 DPRINTF(
DMA,
"Can't send immediately, waiting to send\n");
408 bool done =
state->gen.done();
413 panic(
"Unknown memory mode.");
420 if (if_name ==
"dma") {
427 unsigned max_req_size,
428 unsigned max_pending,
430 : maxReqSize(max_req_size), fifoSize(size),
431 reqFlags(
flags), port(_port), cacheLineSize(port.sys->cacheLineSize()),
540 const size_t xfer_size = std::min(fifo_space, block_remaining);
544 DPRINTF(
DMA,
"Direct bypass startAddr=%#x xfer_size=%#x " \
545 "fifo_space=%#x block_remaining=%#x\n",
546 nextAddr, xfer_size, fifo_space, block_remaining);
559 size_t size_pending(0);
561 size_pending +=
e->requestSize();
572 event->reset(req_size);
576 size_pending += req_size;
602 if (!
event->canceled())
622 : parent(_parent), _data(max_size, 0)
630 setFlags(AutoDelete);
642 assert(
size <= _data.size());
Tick curTick()
The universal simulation clock.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
void unserialize(CheckpointIn &cp) override
Unserialize an object.
EventFunctionWrapper sendEvent
Event used to schedule a future sending from the transmit list.
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
ClockedObject *const device
The device that owns this port.
bool tryGet(uint8_t *dst, size_t len)
Try to read data from the FIFO.
This device is the base class which all devices senstive to an address range inherit from.
#define UNSERIALIZE_SCALAR(scalar)
DrainState drainState() const
Return the current drain state of an object.
void startFill(Addr start, size_t size)
Start filling the FIFO.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
#define UNSERIALIZE_CONTAINER(member)
const Request::Flags flags
The flags to use for requests.
Addr complete() const
Number of bytes we have already chunked up.
bool isActive() const
Is the DMA engine active (i.e., are there still in-flight accesses)?
RequestPtr req
A pointer to the original request.
Buffered DMA engine helper class.
virtual void onEndOfBlock()
End of block callback.
Tick sendAtomic(PacketPtr pkt)
Send an atomic request packet, where the data is moved and the state is updated in zero time,...
bool isAtomicMode() const
Is the system in atomic mode?
void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
bool bypassCaches() const
Should caches be bypassed?
bool cacheResponding() const
Command
List of all commands associated with a packet.
PacketPtr inRetry
The packet (if any) waiting for a retry to send.
void serialize(CheckpointOut &cp) const override
Serialize an object.
void schedule(Event &event, Tick when)
ChunkGenerator gen
Object to track what chunks of bytes to send at a time.
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
Cycles is a wrapper class for representing cycle counts, i.e.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Addr size() const
Return size in bytes of current chunk.
Tick sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor)
Send an atomic request packet like above, but also request a backdoor to the data being accessed.
size_t size() const
Get the amount of data stored in the FIFO.
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
uint32_t pendingCount
Number of outstanding packets the dma port has.
DrainState
Object drain/handover states.
std::deque< DmaReqState * > transmitList
Use a deque as we never do any insertion or removal in the middle.
DmaDoneEvent(DmaReadFifo *_parent, size_t max_size)
virtual void onIdle()
Last response received callback.
std::deque< DmaDoneEventUPtr > freeRequests
virtual std::string name() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void sendDma()
For timing, attempt to send the first item on the transmit list, and if it is successful and there ar...
ProbePointArg< PacketInfo > Packet
Packet probe point.
uint64_t Tick
Tick count type.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
std::shared_ptr< Request > RequestPtr
AddrRangeMap< MemBackdoorPtr, 1 > memBackdoors
const Packet::Command cmd
Command for the request.
void resumeFill()
Try to issue new DMA requests or bypass DMA requests.
uint8_t *const data
Pointer to a buffer for the data.
const Request::Flags reqFlags
Request flags.
void dmaDone()
DMA request done, handle incoming data and issue new request.
bool isConnected() const
Is this port currently connected to a peer?
bool retryPending
Whether the other side expects us to wait for a retry.
@ Drained
Buffers drained, ready for serialization/handover.
bool isTimingMode() const
Is the system in timing mode?
void stopFill()
Stop the DMA engine.
void resumeFillTiming()
Try to issue new DMA requests during normal execution.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
void handleResp(DmaReqState *state, Addr addr, Addr size, Tick delay=0)
SenderState * senderState
This packet's sender state.
const std::string & name()
#define SERIALIZE_SCALAR(scalar)
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
const Addr maxReqSize
Maximum request size in bytes.
const size_t fifoSize
Maximum FIFO size in bytes.
bool atEndOfBlock() const
Has the DMA engine sent out the last request for the active block?
void deschedule(Event &event)
const std::string & toString() const
Return the string to a cmd given by idx.
void signalDrainDone() const
Signal that an object is drained.
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
bool sendAtomicReq(DmaReqState *state)
Send the next packet from a DMA request in atomic mode.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Ports are used to interface objects to each other.
void handleRespPacket(PacketPtr pkt, Tick delay=0)
Handle a response packet by updating the corresponding DMA request state to reflect the bytes receive...
void recvReqRetry() override
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
Addr addr() const
Return starting address of current chunk.
#define SERIALIZE_CONTAINER(member)
void sendEvent(ThreadContext *tc)
Send an event (SEV) to a specific PE if there isn't already a pending event.
bool recvTimingResp(PacketPtr pkt) override
Receive a timing response from the peer.
const RequestorID requestorId
Id for all requests.
void trySendTimingReq()
Take the first request on the transmit list and attempt to send a timing packet from it.
DmaDevice(const Params &p)
void write(InputIterator in, size_t len)
std::unique_ptr< DmaDoneEvent > DmaDoneEventUPtr
std::ostream CheckpointOut
DmaPort(ClockedObject *dev, System *s, uint32_t sid=0, uint32_t ssid=0)
DmaReadFifo(DmaPort &port, size_t size, unsigned max_req_size, unsigned max_pending, Request::Flags flags=0)
const uint32_t defaultSSid
Default substreamId.
bool sendAtomicBdReq(DmaReqState *state)
Send the next packet from a DMA request in atomic mode, and request and/or use memory backdoors if po...
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
const uint32_t sid
Stream IDs.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
System *const sys
The system that device/port are in.
std::deque< DmaDoneEventUPtr > pendingRequests
void read(OutputIterator out, size_t len)
void handlePending()
Handle pending requests that have been flagged as done.
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
@ Draining
Draining buffers pending serialization/handover.
void resumeFillBypass()
Try to bypass DMA requests in non-caching mode.
bool scheduled() const
Determine if the current event is scheduled.
#define panic(...)
This implements a cprintf based panic() function.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
const uint32_t defaultSid
Default streamId.
Generated on Sun Jul 30 2023 01:56:55 for gem5 by doxygen 1.8.17