53 #include "debug/DMACopyEngine.hh" 54 #include "debug/Drain.hh" 57 #include "params/CopyEngine.hh" 72 fatal(
"CopyEngine interface doesn't support more than 64 DMA engines\n");
82 : cePort(_ce, _ce->
sys),
83 ce(_ce), channelId(cid), busy(false), underReset(false),
84 refreshNext(false), latBeforeBegin(
ce->
params()->latBeforeBegin),
85 latAfterCompletion(
ce->
params()->latAfterCompletion),
86 completionDataReg(0), nextState(Idle),
105 for (
int x = 0;
x <
chan.size();
x++) {
119 if (if_name !=
"dma") {
123 if (idx >= static_cast<int>(
chan.size())) {
124 panic(
"CopyEngine::getPort: unknown index %d\n", idx);
127 return chan[idx]->getPort();
164 panic(
"Resume, Abort, and Suspend are not supported\n");
175 panic(
"Invalid PCI memory access to unmapped memory.\n");
181 if (size !=
sizeof(uint64_t) && size !=
sizeof(uint32_t) &&
182 size !=
sizeof(uint16_t) && size !=
sizeof(uint8_t)) {
183 panic(
"Unknown size for MMIO access: %d\n", pkt->
getSize());
186 DPRINTF(DMACopyEngine,
"Read device register %#X size: %d\n", daddr, size);
203 assert(size ==
sizeof(uint8_t));
213 panic(
"Read request to unknown register number: %#x\n", daddr);
223 while (daddr >= 0x80) {
229 panic(
"Access to channel %d (device only configured for %d channels)",
235 chan[chanid]->channelRead(pkt, daddr, size);
246 assert(size ==
sizeof(uint16_t));
251 assert(size ==
sizeof(uint64_t));
255 assert(size ==
sizeof(uint64_t) || size ==
sizeof(uint32_t));
256 if (size ==
sizeof(uint64_t))
262 assert(size ==
sizeof(uint32_t));
266 assert(size ==
sizeof(uint8_t));
270 assert(size ==
sizeof(uint64_t) || size ==
sizeof(uint32_t));
271 if (size ==
sizeof(uint64_t))
277 assert(size ==
sizeof(uint32_t));
281 assert(size ==
sizeof(uint32_t));
285 panic(
"Read request to unknown channel register number: (%d)%#x\n",
299 panic(
"Invalid PCI memory access to unmapped memory.\n");
310 if (size ==
sizeof(uint64_t)) {
312 DPRINTF(DMACopyEngine,
"Wrote device register %#X value %#X\n",
314 }
else if (size ==
sizeof(uint32_t)) {
316 DPRINTF(DMACopyEngine,
"Wrote device register %#X value %#X\n",
318 }
else if (size ==
sizeof(uint16_t)) {
320 DPRINTF(DMACopyEngine,
"Wrote device register %#X value %#X\n",
322 }
else if (size ==
sizeof(uint8_t)) {
324 DPRINTF(DMACopyEngine,
"Wrote device register %#X value %#X\n",
327 panic(
"Unknown size for MMIO access: %d\n", size);
335 DPRINTF(DMACopyEngine,
"Warning, ignorning write to register %x\n",
342 panic(
"Read request to unknown register number: %#x\n", daddr);
351 while (daddr >= 0x80) {
357 panic(
"Access to channel %d (device only configured for %d channels)",
363 chan[chanid]->channelWrite(pkt, daddr, size);
374 assert(size ==
sizeof(uint16_t));
376 old_int_disable =
cr.
ctrl.interrupt_disable();
378 if (
cr.
ctrl.interrupt_disable())
379 cr.
ctrl.interrupt_disable(0);
381 cr.
ctrl.interrupt_disable(old_int_disable);
384 assert(size ==
sizeof(uint64_t));
385 DPRINTF(DMACopyEngine,
"Warning, ignorning write to register %x\n",
389 assert(size ==
sizeof(uint64_t) || size ==
sizeof(uint32_t));
390 if (size ==
sizeof(uint64_t))
398 assert(size ==
sizeof(uint32_t));
404 assert(size ==
sizeof(uint8_t));
409 assert(size ==
sizeof(uint64_t) || size ==
sizeof(uint32_t));
410 if (size ==
sizeof(uint64_t))
417 assert(size ==
sizeof(uint32_t));
422 assert(size ==
sizeof(uint32_t));
426 panic(
"Read request to unknown channel register number: (%d)%#x\n",
436 using namespace Stats;
440 .
desc(
"Number of bytes copied by each engine")
446 .
desc(
"Number of copies processed by each engine")
456 DPRINTF(DMACopyEngine,
"Reading descriptor from at memory location %#x(%#x)\n",
461 DPRINTF(DMACopyEngine,
"dmaAction: %#x, %d bytes, to addr %#x\n",
473 DPRINTF(DMACopyEngine,
"Read of descriptor complete\n");
476 DPRINTF(DMACopyEngine,
"Got NULL descriptor, skipping\n");
479 panic(
"Shouldn't be able to get here\n");
494 panic(
"Descriptor has flag other that completion status set\n");
505 DPRINTF(DMACopyEngine,
"Reading %d bytes from buffer to memory location %#x(%#x)\n",
515 DPRINTF(DMACopyEngine,
"Read of bytes to copy complete\n");
526 DPRINTF(DMACopyEngine,
"Writing %d bytes from buffer to memory location %#x(%#x)\n",
540 DPRINTF(DMACopyEngine,
"Write of bytes to copy complete user1: %#x\n",
594 anBegin(
"WriteCompletionStatus");
595 DPRINTF(DMACopyEngine,
"Writing completion status %#x to address %#x(%#x)\n",
608 DPRINTF(DMACopyEngine,
"Writing completion status complete\n");
616 DPRINTF(DMACopyEngine,
"Fetching next address...\n");
627 DPRINTF(DMACopyEngine,
"Fetching next address complete: %#x\n",
630 DPRINTF(DMACopyEngine,
"Got NULL descriptor, nothing more to do\n");
648 DPRINTF(Drain,
"CopyEngine done draining, processing drain event\n");
661 DPRINTF(Drain,
"CopyEngineChannel not drained\n");
671 for (
int x =0;
x <
chan.size();
x++)
680 for (
int x = 0;
x <
chan.size();
x++)
742 panic(
"Unknown state for CopyEngineChannel\n");
749 DPRINTF(DMACopyEngine,
"Restarting state machine at state %d\n",
nextState);
754 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 serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
void fetchDescriptor(Addr address)
DrainState
Object drain/handover states.
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
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
const uint32_t CHAN_STATUS
void channelWrite(PacketPtr pkt, Addr daddr, int size)
DrainState drainState() const
Return the current drain state of an object.
void signalDrainDone() const
Signal that an object is drained.
void anQ(const char *s, uint64_t id, int size=1)
virtual void regStats()
Callback to set stat parameters.
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.
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.
const uint32_t GEN_XFERCAP
void writeCopyBytesComplete()
#define UNSERIALIZE_SCALAR(scalar)
void continueProcessing()
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
#define SERIALIZE_ARRAY(member, size)
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
Draining buffers pending serialization/handover.
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...
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.
#define UNSERIALIZE_ARRAY(member, size)
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
uint64_t completionDataReg
EventFunctionWrapper writeCompleteEvent
Declaration of the Packet class.
std::ostream CheckpointOut
const uint32_t GEN_CHANCOUNT
void readCopyBytesComplete()
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.
static const int NumArgumentRegs M5_VAR_USED
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 unserialize(CheckpointIn &cp) override
Unserialize an object.