33 #include "debug/RubyDma.hh"
34 #include "debug/RubyStats.hh"
35 #include "mem/protocol/SequencerMsg.hh"
36 #include "mem/protocol/SequencerRequestType.hh"
40 int bytes_completed,
int bytes_issued, uint8_t *
data,
42 : start_paddr(start_paddr), len(len), write(write),
43 bytes_completed(bytes_completed), bytes_issued(bytes_issued), data(data),
49 :
RubyPort(p), m_outstanding_count(0),
50 m_max_outstanding_requests(p->max_outstanding_requests)
61 s_port->sendRangeChange();
68 return RequestStatus_BufferFull;
80 std::forward_as_tuple(line_addr),
81 std::forward_as_tuple(paddr, len, write, 0,
83 DMARequest& active_request = emplace_pair.first->second;
88 if (!emplace_pair.second) {
89 DPRINTF(RubyDma,
"DMA aliased: addr %p, len %d\n", line_addr, len);
90 return RequestStatus_Aliased;
93 DPRINTF(RubyDma,
"DMA req created: addr %p, len %d\n", line_addr, len);
95 std::shared_ptr<SequencerMsg> msg =
96 std::make_shared<SequencerMsg>(
clockEdge());
97 msg->getPhysicalAddress() = paddr;
98 msg->getLineAddress() = line_addr;
99 msg->getType() = write ? SequencerRequestType_ST : SequencerRequestType_LD;
105 if (write && (data != NULL)) {
106 if (active_request.
data != NULL) {
107 msg->getDataBlk().setData(data, offset, msg->getLen());
117 return RequestStatus_Issued;
129 active_request.bytes_completed = active_request.bytes_issued;
130 if (active_request.len == active_request.bytes_completed) {
131 DPRINTF(RubyDma,
"DMA request completed: addr %p, size %d\n",
132 address, active_request.len);
140 std::shared_ptr<SequencerMsg> msg =
141 std::make_shared<SequencerMsg>(
clockEdge());
142 msg->getPhysicalAddress() = active_request.start_paddr +
143 active_request.bytes_completed;
148 msg->getType() = (active_request.write ? SequencerRequestType_ST :
149 SequencerRequestType_LD);
152 (active_request.len -
154 active_request.len - active_request.bytes_completed :
157 if (active_request.write) {
159 setData(&active_request.data[active_request.bytes_completed],
165 active_request.bytes_issued += msg->getLen();
167 "DMA request bytes issued %d, bytes completed %d, total len %d\n",
168 active_request.bytes_issued, active_request.bytes_completed,
180 int len = active_request.bytes_issued - active_request.bytes_completed;
182 if (active_request.bytes_completed == 0)
184 assert(!active_request.write);
185 if (active_request.data != NULL) {
186 memcpy(&active_request.data[active_request.bytes_completed],
202 DPRINTF(RubyStats,
"Recorded statistic: %s\n",
203 DMASequencerRequestType_to_string(requestType));
207 DMASequencerParams::create()
std::vector< MemSlavePort * > slave_ports
Cycles is a wrapper class for representing cycle counts, i.e.
Tick cyclesToTicks(Cycles c) const
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
RequestStatus makeRequest(PacketPtr pkt) override
DMASequencer(const Params *)
void recordRequestType(DMASequencerRequestType requestType)
T * getPtr()
get a pointer to the data ptr.
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...
uint64_t m_data_block_mask
void dataCallback(const DataBlock &dblk, const Addr &addr)
RequestTable m_RequestTable
void issueNext(const Addr &addr)
void ruby_hit_callback(PacketPtr pkt)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Addr makeLineAddress(Addr addr)
DMARequest(uint64_t start_paddr, int len, bool write, int bytes_completed, int bytes_issued, uint8_t *data, PacketPtr pkt)
MessageBuffer * m_mandatory_q_ptr
const uint8_t * getData(int offset, int len) const
void ackCallback(const Addr &addr)
int m_max_outstanding_requests
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
static uint32_t getBlockSizeBits()
static uint32_t getBlockSizeBytes()
void enqueue(MsgPtr message, Tick curTime, Tick delta)