51 #include "debug/DMA.hh"
52 #include "debug/Drain.hh"
58 device(dev), sys(s), masterId(s->getMasterId(dev->
name())),
59 sendEvent(this), pendingCount(0), inRetry(false)
72 DPRINTF(
DMA,
"Received response %s for addr: %#x size: %d nb: %d," \
73 " tot: %d sched %d\n",
75 state->numBytes, state->totBytes,
76 state->completionEvent ?
77 state->completionEvent->scheduled() : 0);
85 assert(state->totBytes >= state->numBytes);
89 if (state->totBytes == state->numBytes) {
90 if (state->completionEvent) {
91 delay += state->delay;
126 panic(
"DMA port of %s not connected to anything!",
name());
136 DPRINTF(Drain,
"DmaPort not drained\n");
163 DPRINTF(
DMA,
"Starting DMA for addr: %#x size: %d sched: %d\n", addr, size,
166 !gen.
done(); gen.next()) {
177 DPRINTF(
DMA,
"--Queuing DMA for addr: %#x size: %d\n", gen.addr(),
222 DPRINTF(
DMA,
"-- Failed, waiting for retry\n");
225 DPRINTF(
DMA,
"TransmitList: %d, inRetry: %d\n",
241 DPRINTF(
DMA,
"Can't send immediately, waiting to send\n");
252 DPRINTF(
DMA,
"Sending DMA for addr: %#x size: %d\n",
259 panic(
"Unknown memory mode.");
265 if (if_name ==
"dma") {
276 unsigned max_req_size,
277 unsigned max_pending,
279 : maxReqSize(max_req_size), fifoSize(size),
280 reqFlags(flags), port(_port),
282 nextAddr(0), endAddr(0)
339 const bool success(
tryGet(dst, len));
340 panic_if(!success,
"Buffer underrun in DmaReadFifo::get()\n");
390 if (fifo_space >= kvm_watermark ||
buffer.
capacity() < kvm_watermark) {
392 const size_t xfer_size = std::min(fifo_space, block_remaining);
396 DPRINTF(
DMA,
"KVM Bypassing startAddr=%#x xfer_size=%#x " \
397 "fifo_space=%#x block_remaining=%#x\n",
398 nextAddr, xfer_size, fifo_space, block_remaining);
402 nextAddr += xfer_size;
409 size_t size_pending(0);
411 size_pending +=
e->requestSize();
422 event->reset(req_size);
426 size_pending += req_size;
428 pendingRequests.emplace_back(std::move(event));
452 if (!event->canceled())
472 : parent(_parent), _done(false), _canceled(false), _data(max_size, 0)
480 setFlags(AutoDelete);
492 assert(size <= _data.size());
A MasterPort is a specialisation of a BaseMasterPort, which implements the default protocol for the t...
void write(InputIterator in, size_t len)
bool isUncacheable() const
Accessor functions for flags.
size_t size() const
Get the amount of data stored in the FIFO.
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.
Buffered DMA engine helper class.
void startFill(Addr start, size_t size)
Start filling the FIFO.
DrainState
Object drain/handover states.
::Flags< FlagsType > Flags
bool atEndOfBlock() const
Has the DMA engine sent out the last request for the active block?
bool bypassCaches() const
Should caches be bypassed?
bool recvTimingResp(PacketPtr pkt) override
Receive a timing response from the slave port.
panic_if(!root,"Invalid expression\n")
bool scheduled() const
Determine if the current event is scheduled.
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 sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the slave port by calling its corresponding receive function...
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
unsigned int cacheLineSize() const
Get the cache line size of the system.
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
const MasterID masterId
Id for all requests.
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)
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...
#define SERIALIZE_CONTAINER(member)
PortProxy Object Declaration.
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)
void stopFill()
Stop the DMA engine.
bool isActive() const
Is the DMA engine active (i.e., are there still in-flight accesses)?
void dmaDone()
DMA request done, handle incoming data and issue new request.
uint64_t Tick
Tick count type.
void recvReqRetry() override
Called by the slave port if sendTimingReq was called on this master port (causing recvTimingReq to be...
EventWrapper< DmaPort,&DmaPort::sendDma > sendEvent
Event used to schedule a future sending from the transmit list.
This class takes an arbitrary memory region (address/length pair) and generates a series of appropria...
const Addr maxReqSize
Maximum request size in bytes.
const RequestPtr req
A pointer to the original request.
virtual void onIdle()
Last response received callback.
const size_t fifoSize
Maximum FIFO size in bytes.
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.
BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a master 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.
bool cacheResponding() const
Draining buffers pending serialization/handover.
bool isAtomicMode() const
Is the system in atomic mode?
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.
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.
#define SERIALIZE_SCALAR(scalar)
void unserialize(CheckpointIn &cp) override
Unserialize an object.
virtual void readBlob(Addr addr, uint8_t *p, int size) const
Read size bytes memory at address and store in p.
std::deque< DmaDoneEventUPtr > pendingRequests
virtual void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
void resumeFill()
Try to issue new DMA requests or bypass DMA requests.
virtual const std::string name() const
std::ostream CheckpointOut
bool done() const
Are we done? That is, did the last call to next() advance past the end of the region?
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
SenderState * senderState
This packet's sender state.
The MemObject class extends the ClockedObject with accessor functions to get its master and slave por...
A BaseMasterPort is a protocol-agnostic master port, responsible only for the structural connection t...
void signalDrainDone() const
Signal that an object is drained.
void schedule(Event &event, Tick when)
void resumeFillTiming()
Try to issue new DMA requests during normal execution.
DrainState drainState() const
Return the current drain state of an object.
DmaPort(MemObject *dev, System *s)
bool tryGet(uint8_t *dst, size_t len)
Try to read data from the FIFO.
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)
Declaration and inline definition of ChunkGenerator object.
Command
List of all commands associated with a packet.
Tick sendAtomic(PacketPtr pkt)
Send an atomic request packet, where the data is moved and the state is updated in zero time...
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)
virtual BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a master port with a given name and index.
MemObject *const device
The device that owns this port.
std::deque< PacketPtr > transmitList
Use a deque as we never do any insertion or removal in the middle.
ProbePointArg< PacketInfo > Packet
Packet probe point.
bool isTimingMode() const
Is the system in timing mode?