51 #include "debug/DMACopyEngine.hh" 52 #include "debug/Drain.hh" 55 #include "params/CopyEngine.hh" 70 fatal(
"CopyEngine interface doesn't support more than 64 DMA engines\n");
80 : cePort(_ce, _ce->
sys),
81 ce(_ce), channelId(cid), busy(false), underReset(false),
82 refreshNext(false), latBeforeBegin(
ce->
params()->latBeforeBegin),
83 latAfterCompletion(
ce->
params()->latAfterCompletion),
84 completionDataReg(0), nextState(Idle),
103 for (
int x = 0;
x <
chan.size();
x++) {
117 if (if_name !=
"dma") {
121 if (idx >= static_cast<int>(
chan.size())) {
122 panic(
"CopyEngine::getPort: unknown index %d\n", idx);
125 return chan[idx]->getPort();
162 panic(
"Resume, Abort, and Suspend are not supported\n");
173 panic(
"Invalid PCI memory access to unmapped memory.\n");
179 if (size !=
sizeof(uint64_t) && size !=
sizeof(uint32_t) &&
180 size !=
sizeof(uint16_t) && size !=
sizeof(uint8_t)) {
181 panic(
"Unknown size for MMIO access: %d\n", pkt->
getSize());
184 DPRINTF(DMACopyEngine,
"Read device register %#X size: %d\n", daddr, size);
201 assert(size ==
sizeof(uint8_t));
211 panic(
"Read request to unknown register number: %#x\n", daddr);
221 while (daddr >= 0x80) {
227 panic(
"Access to channel %d (device only configured for %d channels)",
233 chan[chanid]->channelRead(pkt, daddr, size);
244 assert(size ==
sizeof(uint16_t));
249 assert(size ==
sizeof(uint64_t));
253 assert(size ==
sizeof(uint64_t) || size ==
sizeof(uint32_t));
254 if (size ==
sizeof(uint64_t))
260 assert(size ==
sizeof(uint32_t));
264 assert(size ==
sizeof(uint8_t));
268 assert(size ==
sizeof(uint64_t) || size ==
sizeof(uint32_t));
269 if (size ==
sizeof(uint64_t))
275 assert(size ==
sizeof(uint32_t));
279 assert(size ==
sizeof(uint32_t));
283 panic(
"Read request to unknown channel register number: (%d)%#x\n",
297 panic(
"Invalid PCI memory access to unmapped memory.\n");
308 if (size ==
sizeof(uint64_t)) {
309 uint64_t
val M5_VAR_USED = pkt->
getLE<uint64_t>();
310 DPRINTF(DMACopyEngine,
"Wrote device register %#X value %#X\n",
312 }
else if (size ==
sizeof(uint32_t)) {
313 uint32_t
val M5_VAR_USED = pkt->
getLE<uint32_t>();
314 DPRINTF(DMACopyEngine,
"Wrote device register %#X value %#X\n",
316 }
else if (size ==
sizeof(uint16_t)) {
317 uint16_t
val M5_VAR_USED = pkt->
getLE<uint16_t>();
318 DPRINTF(DMACopyEngine,
"Wrote device register %#X value %#X\n",
320 }
else if (size ==
sizeof(uint8_t)) {
321 uint8_t
val M5_VAR_USED = pkt->
getLE<uint8_t>();
322 DPRINTF(DMACopyEngine,
"Wrote device register %#X value %#X\n",
325 panic(
"Unknown size for MMIO access: %d\n", size);
333 DPRINTF(DMACopyEngine,
"Warning, ignorning write to register %x\n",
340 panic(
"Read request to unknown register number: %#x\n", daddr);
349 while (daddr >= 0x80) {
355 panic(
"Access to channel %d (device only configured for %d channels)",
361 chan[chanid]->channelWrite(pkt, daddr, size);
372 assert(size ==
sizeof(uint16_t));
374 old_int_disable =
cr.
ctrl.interrupt_disable();
376 if (
cr.
ctrl.interrupt_disable())
377 cr.
ctrl.interrupt_disable(0);
379 cr.
ctrl.interrupt_disable(old_int_disable);
382 assert(size ==
sizeof(uint64_t));
383 DPRINTF(DMACopyEngine,
"Warning, ignorning write to register %x\n",
387 assert(size ==
sizeof(uint64_t) || size ==
sizeof(uint32_t));
388 if (size ==
sizeof(uint64_t))
396 assert(size ==
sizeof(uint32_t));
402 assert(size ==
sizeof(uint8_t));
407 assert(size ==
sizeof(uint64_t) || size ==
sizeof(uint32_t));
408 if (size ==
sizeof(uint64_t))
415 assert(size ==
sizeof(uint32_t));
420 assert(size ==
sizeof(uint32_t));
424 panic(
"Read request to unknown channel register number: (%d)%#x\n",
434 using namespace Stats;
438 .
desc(
"Number of bytes copied by each engine")
444 .
desc(
"Number of copies processed by each engine")
454 DPRINTF(DMACopyEngine,
"Reading descriptor from at memory location %#x(%#x)\n",
459 DPRINTF(DMACopyEngine,
"dmaAction: %#x, %d bytes, to addr %#x\n",
471 DPRINTF(DMACopyEngine,
"Read of descriptor complete\n");
474 DPRINTF(DMACopyEngine,
"Got NULL descriptor, skipping\n");
477 panic(
"Shouldn't be able to get here\n");
492 panic(
"Descriptor has flag other that completion status set\n");
503 DPRINTF(DMACopyEngine,
"Reading %d bytes from buffer to memory location %#x(%#x)\n",
513 DPRINTF(DMACopyEngine,
"Read of bytes to copy complete\n");
524 DPRINTF(DMACopyEngine,
"Writing %d bytes from buffer to memory location %#x(%#x)\n",
538 DPRINTF(DMACopyEngine,
"Write of bytes to copy complete user1: %#x\n",
592 anBegin(
"WriteCompletionStatus");
593 DPRINTF(DMACopyEngine,
"Writing completion status %#x to address %#x(%#x)\n",
606 DPRINTF(DMACopyEngine,
"Writing completion status complete\n");
614 DPRINTF(DMACopyEngine,
"Fetching next address...\n");
625 DPRINTF(DMACopyEngine,
"Fetching next address complete: %#x\n",
628 DPRINTF(DMACopyEngine,
"Got NULL descriptor, nothing more to do\n");
646 DPRINTF(Drain,
"CopyEngine done draining, processing drain event\n");
659 DPRINTF(Drain,
"CopyEngineChannel not drained\n");
669 for (
int x =0;
x <
chan.size();
x++)
678 for (
int x = 0;
x <
chan.size();
x++)
740 panic(
"Unknown state for CopyEngineChannel\n");
747 DPRINTF(DMACopyEngine,
"Restarting state machine at state %d\n",
nextState);
752 CopyEngineParams::create()
#define panic(...)
This implements a cprintf based panic() function.
EventFunctionWrapper fetchCompleteEvent
void anBegin(const char *s)
Ports are used to interface objects to each other.
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
const uint32_t CHAN_CHAINADDR_HIGH
#define fatal(...)
This implements a cprintf based fatal() function.
EventFunctionWrapper statusCompleteEvent
const uint32_t CHAN_CHAINADDR
Addr pciToDma(Addr pci_addr) const
void fetchDescriptor(Addr address)
void unserialize(CheckpointIn &cp) override
Unserialize an object.
const uint32_t DESC_CTRL_CP_STS
PCI device, base implementation is only config space.
const uint32_t CHAN_CMPLNADDR_HIGH
const uint32_t CHAN_STATUS
void channelWrite(PacketPtr pkt, Addr daddr, int size)
void anQ(const char *s, uint64_t id, int size=1)
EventFunctionWrapper readCompleteEvent
void serialize(CheckpointOut &cp) const override
Serialize an object.
void serialize(CheckpointOut &cp) const override
Serialize an object.
void serialize(CheckpointOut &cp) const override
Serialize an object.
void writeCompletionStatus()
void restartStateMachine()
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
DrainState
Object drain/handover states.
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Derived & init(size_type size)
Set this vector to have the given size.
void setLE(T v)
Set the value in the data pointer to v as little endian.
DrainState drainState() const
Return the current drain state of an object.
const uint32_t GEN_XFERCAP
void writeCopyBytesComplete()
#define UNSERIALIZE_SCALAR(scalar)
void continueProcessing()
Draining buffers pending serialization/handover.
Stats::Vector copiesProcessed
std::string csprintf(const char *format, const Args &...args)
void serialize(CheckpointOut &cp) const override
Serialize an object.
void makeAtomicResponse()
uint64_t Tick
Tick count type.
const uint32_t CHAN_CONTROL
void channelRead(PacketPtr pkt, Addr daddr, int size)
int getBAR(Addr addr)
Which base address register (if any) maps the given address?
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
void arrayParamOut(CheckpointOut &cp, const std::string &name, const CircleBuf< T > ¶m)
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
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.
std::vector< CopyEngineChannel * > chan
CopyEngineReg::ChanRegs cr
const uint32_t DESC_CTRL_NULL
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
#define SERIALIZE_ARRAY(member, size)
CopyEngineReg::DmaDesc * curDmaDesc
void regStats() override
Callback to set stat parameters.
void writeStatusComplete()
const FlagsType total
Print the total.
RequestPtr dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
const uint32_t CHAN_COMMAND
CopyEngineChannel(CopyEngine *_ce, int cid)
#define SERIALIZE_SCALAR(scalar)
const uint32_t GEN_ATTNSTATUS
void drainResume() override
Resume execution after a successful drain.
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
uint64_t completionDataReg
#define UNSERIALIZE_ARRAY(member, size)
EventFunctionWrapper writeCompleteEvent
Declaration of the Packet class.
std::ostream CheckpointOut
const uint32_t GEN_CHANCOUNT
void readCopyBytesComplete()
void signalDrainDone() const
Signal that an object is drained.
Stats::Vector bytesCopied
const uint32_t CHAN_ERROR
int findMsbSet(uint64_t val)
Returns the bit position of the MSB that is set in the input.
const uint32_t GEN_INTRCTRL
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
void arrayParamIn(CheckpointIn &cp, const std::string &name, CircleBuf< T > ¶m)
EventFunctionWrapper addrCompleteEvent
virtual ~CopyEngineChannel()
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
virtual void regStats()
Callback to set stat parameters.
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
CopyEngine(const Params *params)
const uint32_t CHAN_CMPLNADDR
void unserialize(CheckpointIn &cp) override
Unserialize an object.
DrainState drain() override
Notify an object that it needs to drain its state.
const Params * params() const
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
void fetchNextAddr(Addr address)
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
void unserialize(CheckpointIn &cp) override
Unserialize an object.