gem5  [DEVELOP-FOR-23.0]
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
dma_device.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, 2015, 2017, 2019 ARM Limited
3  * All rights reserved.
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2006 The Regents of The University of Michigan
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 #include "dev/dma_device.hh"
42 
43 #include <algorithm>
44 #include <cassert>
45 #include <cstring>
46 #include <utility>
47 
48 #include "base/logging.hh"
49 #include "base/trace.hh"
50 #include "debug/DMA.hh"
51 #include "debug/Drain.hh"
52 #include "sim/clocked_object.hh"
53 #include "sim/system.hh"
54 
55 namespace gem5
56 {
57 
59  uint32_t sid, uint32_t ssid)
60  : RequestPort(dev->name() + ".dma"),
61  device(dev), sys(s), requestorId(s->getRequestorId(dev)),
62  sendEvent([this]{ sendDma(); }, dev->name()),
63  defaultSid(sid), defaultSSid(ssid), cacheLineSize(s->cacheLineSize())
64 { }
65 
66 void
68 {
69  // Should always see a response with a sender state.
70  assert(pkt->isResponse());
71  warn_if(pkt->isError(), "Response pkt error.");
72 
73  // Get the DMA sender state.
74  auto *state = dynamic_cast<DmaReqState*>(pkt->senderState);
75  assert(state);
76 
77  handleResp(state, pkt->getAddr(), pkt->req->getSize(), delay);
78 
79  delete pkt;
80 }
81 
82 void
84 {
85  assert(pendingCount != 0);
86  pendingCount--;
87  DPRINTF(DMA, "Received response %s for addr: %#x size: %d nb: %d," \
88  " tot: %d sched %d\n",
89  MemCmd(state->cmd).toString(), addr, size,
90  state->numBytes, state->totBytes,
91  state->completionEvent ?
92  state->completionEvent->scheduled() : 0);
93 
94  // Update the number of bytes received based on the request rather
95  // than the packet as the latter could be rounded up to line sizes.
96  state->numBytes += size;
97  assert(state->totBytes >= state->numBytes);
98 
99  bool all_bytes = (state->totBytes == state->numBytes);
100  if (state->aborted) {
101  // If this request was aborted, check to see if its in flight accesses
102  // have finished. There may be packets for more than one request in
103  // flight at a time, so check for finished requests, or no more
104  // packets.
105  if (all_bytes || pendingCount == 0) {
106  // If yes, signal its abort event (if any) and delete the state.
107  if (state->abortEvent) {
108  device->schedule(state->abortEvent, curTick());
109  }
110  delete state;
111  }
112  } else if (all_bytes) {
113  // If we have reached the end of this DMA request, then signal the
114  // completion and delete the sate.
115  if (state->completionEvent) {
116  delay += state->delay;
117  device->schedule(state->completionEvent, curTick() + delay);
118  }
119  delete state;
120  }
121 
122  // We might be drained at this point, if so signal the drain event.
123  if (pendingCount == 0)
124  signalDrainDone();
125 }
126 
127 PacketPtr
129 {
130  RequestPtr req = std::make_shared<Request>(
131  gen.addr(), gen.size(), flags, id);
132  req->setStreamId(sid);
133  req->setSubstreamId(ssid);
134  req->taskId(context_switch_task_id::DMA);
135 
136  PacketPtr pkt = new Packet(req, cmd);
137 
138  if (data)
139  pkt->dataStatic(data + gen.complete());
140 
141  pkt->senderState = this;
142  return pkt;
143 }
144 
145 bool
147 {
148  // We shouldn't ever get a cacheable block in Modified state.
149  assert(pkt->req->isUncacheable() ||
150  !(pkt->cacheResponding() && !pkt->hasSharers()));
151 
152  handleRespPacket(pkt);
153 
154  return true;
155 }
156 
158  : PioDevice(p), dmaPort(this, sys, p.sid, p.ssid)
159 { }
160 
161 void
163 {
165  "DMA port of %s not connected to anything!", name());
166  PioDevice::init();
167 }
168 
171 {
172  if (pendingCount == 0) {
173  return DrainState::Drained;
174  } else {
175  DPRINTF(Drain, "DmaPort not drained\n");
176  return DrainState::Draining;
177  }
178 }
179 
180 void
182 {
183  retryPending = false;
184  if (transmitList.size())
186 }
187 
188 void
190  uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay,
191  Request::Flags flag)
192 {
193  DPRINTF(DMA, "Starting DMA for addr: %#x size: %d sched: %d\n", addr, size,
194  event ? event->scheduled() : -1);
195 
196  // One DMA request sender state for every action, that is then
197  // split into many requests and packets based on the block size,
198  // i.e. cache line size.
199  transmitList.push_back(
200  new DmaReqState(cmd, addr, cacheLineSize, size,
201  data, flag, requestorId, sid, ssid, event, delay));
202 
203  // In zero time, also initiate the sending of the packets for the request
204  // we have just created. For atomic this involves actually completing all
205  // the requests.
206  sendDma();
207 }
208 
209 void
211  uint8_t *data, Tick delay, Request::Flags flag)
212 {
213  dmaAction(cmd, addr, size, event, data,
214  defaultSid, defaultSSid, delay, flag);
215 }
216 
217 void
219 {
220  if (inRetry) {
221  delete inRetry;
222  inRetry = nullptr;
223  }
224 
225  if (pendingCount && !transmitList.empty()) {
226  auto *state = transmitList.front();
227  if (state->numBytes != state->gen.complete()) {
228  // In flight packets refer to the transmission at the front of the
229  // list, and not a transmission whose packets have all been sent
230  // but not completed. Preserve the state so the packets don't have
231  // dangling pointers.
232  transmitList.pop_front();
233  state->aborted = true;
234  }
235  }
236 
237  // Get rid of requests that haven't started yet.
238  while (!transmitList.empty()) {
239  auto *state = transmitList.front();
240  if (state->abortEvent)
241  device->schedule(state->abortEvent, curTick());
242  delete state;
243  transmitList.pop_front();
244  }
245 
246  if (sendEvent.scheduled())
248 
249  if (pendingCount == 0)
250  signalDrainDone();
251 }
252 
253 void
255 {
256  // Send the next packet for the first DMA request on the transmit list,
257  // and schedule the following send if it is successful
258  DmaReqState *state = transmitList.front();
259 
260  PacketPtr pkt = inRetry ? inRetry : state->createPacket();
261  inRetry = nullptr;
262 
263  DPRINTF(DMA, "Trying to send %s addr %#x\n", pkt->cmdString(),
264  pkt->getAddr());
265 
266  // Check if this was the last packet now, since hypothetically the packet
267  // response may come immediately, and state may be deleted.
268  bool last = state->gen.last();
269  if (sendTimingReq(pkt)) {
270  pendingCount++;
271  } else {
272  retryPending = true;
273  inRetry = pkt;
274  }
275  if (!retryPending) {
276  state->gen.next();
277  // If that was the last packet from this request, pop it from the list.
278  if (last)
279  transmitList.pop_front();
280  DPRINTF(DMA, "-- Done\n");
281  // If there is more to do, then do so.
282  if (!transmitList.empty()) {
283  // This should ultimately wait for as many cycles as the device
284  // needs to send the packet, but currently the port does not have
285  // any known width so simply wait a single cycle.
287  }
288  } else {
289  DPRINTF(DMA, "-- Failed, waiting for retry\n");
290  }
291 
292  DPRINTF(DMA, "TransmitList: %d, retryPending: %d\n",
293  transmitList.size(), retryPending ? 1 : 0);
294 }
295 
296 bool
298 {
299  PacketPtr pkt = state->createPacket();
300  DPRINTF(DMA, "Sending DMA for addr: %#x size: %d\n",
301  state->gen.addr(), state->gen.size());
302  pendingCount++;
303  Tick lat = sendAtomic(pkt);
304 
305  // Check if we're done, since handleResp may delete state.
306  bool done = !state->gen.next();
307  handleRespPacket(pkt, lat);
308  return done;
309 }
310 
311 bool
313 {
314  bool done = false;
315  pendingCount++;
316 
317  auto bd_it = memBackdoors.contains(state->gen.addr());
318  if (bd_it == memBackdoors.end()) {
319  // We don't have a backdoor for this address, so use a packet.
320 
321  PacketPtr pkt = state->createPacket();
322  DPRINTF(DMA, "Sending DMA for addr: %#x size: %d\n",
323  state->gen.addr(), state->gen.size());
324 
325  MemBackdoorPtr bd = nullptr;
326  Tick lat = sendAtomicBackdoor(pkt, bd);
327 
328  // If we got a backdoor, record it.
329  if (bd && memBackdoors.insert(bd->range(), bd) != memBackdoors.end()) {
330  // Invalidation callback which finds this backdoor and removes it.
331  auto callback = [this](const MemBackdoor &backdoor) {
332  for (auto it = memBackdoors.begin();
333  it != memBackdoors.end(); it++) {
334  if (it->second == &backdoor) {
335  memBackdoors.erase(it);
336  return;
337  }
338  }
339  panic("Got invalidation for unknown memory backdoor.");
340  };
341  bd->addInvalidationCallback(callback);
342  }
343 
344  // Check if we're done now, since handleResp may delete state.
345  done = !state->gen.next();
346  handleRespPacket(pkt, lat);
347  } else {
348  // We have a backdoor that can at least partially satisfy this request.
349  DPRINTF(DMA, "Handling DMA for addr: %#x size %d through backdoor\n",
350  state->gen.addr(), state->gen.size());
351 
352  const auto *bd = bd_it->second;
353  // Offset of this access into the backdoor.
354  const Addr offset = state->gen.addr() - bd->range().start();
355  // How many bytes we still need.
356  const Addr remaining = state->totBytes - state->gen.complete();
357  // How many bytes this backdoor can provide, starting from offset.
358  const Addr available = bd->range().size() - offset;
359 
360  // How many bytes we're going to handle through this backdoor.
361  const Addr handled = std::min(remaining, available);
362 
363  // If there's a buffer for data, read/write it.
364  if (state->data) {
365  uint8_t *bd_data = bd->ptr() + offset;
366  uint8_t *state_data = state->data + state->gen.complete();
367  if (MemCmd(state->cmd).isRead())
368  memcpy(state_data, bd_data, handled);
369  else
370  memcpy(bd_data, state_data, handled);
371  }
372 
373  // Advance the chunk generator past this region of memory.
374  state->gen.setNext(state->gen.addr() + handled);
375 
376  // Check if we're done now, since handleResp may delete state.
377  done = !state->gen.next();
378  handleResp(state, state->gen.addr(), handled);
379  }
380 
381  return done;
382 }
383 
384 void
386 {
387  // Some kind of selection between access methods. More work is going to
388  // have to be done to make switching actually work.
389  assert(transmitList.size());
390 
391  if (sys->isTimingMode()) {
392  // If we are either waiting for a retry or are still waiting after
393  // sending the last packet, then do not proceed.
394  if (retryPending || sendEvent.scheduled()) {
395  DPRINTF(DMA, "Can't send immediately, waiting to send\n");
396  return;
397  }
398 
400  } else if (sys->isAtomicMode()) {
401  const bool bypass = sys->bypassCaches();
402 
403  // Send everything there is to send in zero time.
404  while (!transmitList.empty()) {
405  DmaReqState *state = transmitList.front();
406  transmitList.pop_front();
407 
408  bool done = state->gen.done();
409  while (!done)
410  done = bypass ? sendAtomicBdReq(state) : sendAtomicReq(state);
411  }
412  } else {
413  panic("Unknown memory mode.");
414  }
415 }
416 
417 Port &
418 DmaDevice::getPort(const std::string &if_name, PortID idx)
419 {
420  if (if_name == "dma") {
421  return dmaPort;
422  }
423  return PioDevice::getPort(if_name, idx);
424 }
425 
426 DmaReadFifo::DmaReadFifo(DmaPort &_port, size_t size,
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()),
432  buffer(size)
433 {
434  freeRequests.resize(max_pending);
435  for (auto &e : freeRequests)
436  e.reset(new DmaDoneEvent(this, max_req_size));
437 
438 }
439 
441 {
442  for (auto &p : pendingRequests) {
443  DmaDoneEvent *e(p.release());
444 
445  if (e->done()) {
446  delete e;
447  } else {
448  // We can't kill in-flight DMAs, so we'll just transfer
449  // ownership to the event queue so that they get freed
450  // when they are done.
451  e->kill();
452  }
453  }
454 }
455 
456 void
458 {
459  assert(pendingRequests.empty());
460 
464 }
465 
466 void
468 {
472 }
473 
474 bool
475 DmaReadFifo::tryGet(uint8_t *dst, size_t len)
476 {
477  if (buffer.size() >= len) {
478  buffer.read(dst, len);
479  resumeFill();
480  return true;
481  } else {
482  return false;
483  }
484 }
485 
486 void
487 DmaReadFifo::get(uint8_t *dst, size_t len)
488 {
489  panic_if(!tryGet(dst, len), "Buffer underrun in DmaReadFifo::get()");
490 }
491 
492 void
493 DmaReadFifo::startFill(Addr start, size_t size)
494 {
495  assert(atEndOfBlock());
496 
497  nextAddr = start;
498  endAddr = start + size;
499  resumeFill();
500 }
501 
502 void
504 {
505  // Prevent new DMA requests by setting the next address to the end
506  // address. Pending requests will still complete.
507  nextAddr = endAddr;
508 
509  // Flag in-flight accesses as canceled. This prevents their data
510  // from being written to the FIFO.
511  for (auto &p : pendingRequests)
512  p->cancel();
513 }
514 
515 void
517 {
518  // Don't try to fetch more data if we are draining. This ensures
519  // that the DMA engine settles down before we checkpoint it.
521  return;
522 
523  const bool old_eob(atEndOfBlock());
524 
525  if (port.sys->bypassCaches())
527  else
529 
530  if (!old_eob && atEndOfBlock())
531  onEndOfBlock();
532 }
533 
534 void
536 {
537  const size_t fifo_space = buffer.capacity() - buffer.size();
538  if (fifo_space >= cacheLineSize || buffer.capacity() < cacheLineSize) {
539  const size_t block_remaining = endAddr - nextAddr;
540  const size_t xfer_size = std::min(fifo_space, block_remaining);
541  std::vector<uint8_t> tmp_buffer(xfer_size);
542 
543  assert(pendingRequests.empty());
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);
547 
548  port.dmaAction(MemCmd::ReadReq, nextAddr, xfer_size, nullptr,
549  tmp_buffer.data(), 0, reqFlags);
550 
551  buffer.write(tmp_buffer.begin(), xfer_size);
552  nextAddr += xfer_size;
553  }
554 }
555 
556 void
558 {
559  size_t size_pending(0);
560  for (auto &e : pendingRequests)
561  size_pending += e->requestSize();
562 
563  while (!freeRequests.empty() && !atEndOfBlock()) {
564  const size_t req_size(std::min(maxReqSize, endAddr - nextAddr));
565  if (buffer.size() + size_pending + req_size > fifoSize)
566  break;
567 
568  DmaDoneEventUPtr event(std::move(freeRequests.front()));
569  freeRequests.pop_front();
570  assert(event);
571 
572  event->reset(req_size);
573  port.dmaAction(MemCmd::ReadReq, nextAddr, req_size, event.get(),
574  event->data(), 0, reqFlags);
575  nextAddr += req_size;
576  size_pending += req_size;
577 
578  pendingRequests.emplace_back(std::move(event));
579  }
580 }
581 
582 void
584 {
585  const bool old_active(isActive());
586 
587  handlePending();
588  resumeFill();
589 
590  if (old_active && !isActive())
591  onIdle();
592 }
593 
594 void
596 {
597  while (!pendingRequests.empty() && pendingRequests.front()->done()) {
598  // Get the first finished pending request
599  DmaDoneEventUPtr event(std::move(pendingRequests.front()));
600  pendingRequests.pop_front();
601 
602  if (!event->canceled())
603  buffer.write(event->data(), event->requestSize());
604 
605  // Move the event to the list of free requests
606  freeRequests.emplace_back(std::move(event));
607  }
608 
609  if (pendingRequests.empty())
610  signalDrainDone();
611 }
612 
615 {
616  return pendingRequests.empty() ?
618 }
619 
620 
622  : parent(_parent), _data(max_size, 0)
623 {
624 }
625 
626 void
628 {
629  parent = nullptr;
630  setFlags(AutoDelete);
631 }
632 
633 void
635 {
636  _canceled = true;
637 }
638 
639 void
641 {
642  assert(size <= _data.size());
643  _done = false;
644  _canceled = false;
645  _requestSize = size;
646 }
647 
648 void
650 {
651  if (!parent)
652  return;
653 
654  assert(!_done);
655  _done = true;
656  parent->dmaDone();
657 }
658 
659 } // namespace gem5
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::PortID
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:245
gem5::Packet::cmdString
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
Definition: packet.hh:588
gem5::VegaISA::s
Bitfield< 1 > s
Definition: pagetable.hh:64
gem5::DmaReadFifo::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: dma_device.cc:467
gem5::DmaPort::sendEvent
EventFunctionWrapper sendEvent
Event used to schedule a future sending from the transmit list.
Definition: dma_device.hh:171
gem5::RequestPort::sendTimingReq
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
Definition: port.hh:587
gem5::DmaPort::device
ClockedObject *const device
The device that owns this port.
Definition: dma_device.hh:157
gem5::DmaReadFifo::endAddr
Addr endAddr
Definition: dma_device.hh:580
system.hh
gem5::DmaPort::DmaReqState::ssid
const uint32_t ssid
Definition: dma_device.hh:117
data
const char data[]
Definition: circlebuf.test.cc:48
gem5::DmaReadFifo::tryGet
bool tryGet(uint8_t *dst, size_t len)
Try to read data from the FIFO.
Definition: dma_device.cc:475
gem5::PioDevice
This device is the base class which all devices senstive to an address range inherit from.
Definition: io_device.hh:102
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
gem5::Drainable::drainState
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:324
gem5::DmaReadFifo::startFill
void startFill(Addr start, size_t size)
Start filling the FIFO.
Definition: dma_device.cc:493
gem5::DmaDevice::getPort
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition: dma_device.cc:418
UNSERIALIZE_CONTAINER
#define UNSERIALIZE_CONTAINER(member)
Definition: serialize.hh:634
gem5::DmaPort::DmaReqState::flags
const Request::Flags flags
The flags to use for requests.
Definition: dma_device.hh:110
gem5::DmaReadFifo::port
DmaPort & port
Definition: dma_device.hh:527
gem5::ChunkGenerator::complete
Addr complete() const
Number of bytes we have already chunked up.
Definition: chunk_generator.hh:132
gem5::DmaReadFifo::isActive
bool isActive() const
Is the DMA engine active (i.e., are there still in-flight accesses)?
Definition: dma_device.hh:485
gem5::Packet::req
RequestPtr req
A pointer to the original request.
Definition: packet.hh:377
gem5::DmaReadFifo
Buffered DMA engine helper class.
Definition: dma_device.hh:379
gem5::DmaReadFifo::onEndOfBlock
virtual void onEndOfBlock()
End of block callback.
Definition: dma_device.hh:503
gem5::CheckpointIn
Definition: serialize.hh:68
gem5::RequestPort::sendAtomic
Tick sendAtomic(PacketPtr pkt)
Send an atomic request packet, where the data is moved and the state is updated in zero time,...
Definition: port.hh:536
gem5::MipsISA::event
Bitfield< 10, 5 > event
Definition: pra_constants.hh:300
gem5::DmaPort::abortPending
void abortPending()
Definition: dma_device.cc:218
gem5::System::isAtomicMode
bool isAtomicMode() const
Is the system in atomic mode?
Definition: system.hh:258
gem5::DmaPort::dmaAction
void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
Definition: dma_device.cc:210
gem5::System::bypassCaches
bool bypassCaches() const
Should caches be bypassed?
Definition: system.hh:279
gem5::ArmISA::e
Bitfield< 9 > e
Definition: misc_types.hh:65
gem5::Packet::cacheResponding
bool cacheResponding() const
Definition: packet.hh:659
gem5::MemCmd::Command
Command
List of all commands associated with a packet.
Definition: packet.hh:84
gem5::Packet::hasSharers
bool hasSharers() const
Definition: packet.hh:686
gem5::DmaPort::inRetry
PacketPtr inRetry
The packet (if any) waiting for a retry to send.
Definition: dma_device.hh:177
gem5::DmaReadFifo::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: dma_device.cc:457
gem5::EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1012
std::vector< uint8_t >
gem5::PowerISA::bd
Bitfield< 15, 2 > bd
Definition: types.hh:79
gem5::Fifo::size
size_t size() const
Definition: circlebuf.hh:222
gem5::DmaReadFifo::cacheLineSize
const int cacheLineSize
Definition: dma_device.hh:529
gem5::DmaPort::DmaReqState::gen
ChunkGenerator gen
Object to track what chunks of bytes to send at a time.
Definition: dma_device.hh:104
gem5::Fifo::capacity
size_t capacity() const
Definition: circlebuf.hh:223
gem5::RequestPort
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
Definition: port.hh:118
gem5::Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:78
gem5::PioDevice::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: io_device.cc:59
gem5::DmaPort::DmaReqState
Definition: dma_device.hh:82
gem5::ChunkGenerator::size
Addr size() const
Return size in bytes of current chunk.
Definition: chunk_generator.hh:125
gem5::MemCmd
Definition: packet.hh:76
gem5::RequestPort::sendAtomicBackdoor
Tick sendAtomicBackdoor(PacketPtr pkt, MemBackdoorPtr &backdoor)
Send an atomic request packet like above, but also request a backdoor to the data being accessed.
Definition: port.hh:549
gem5::DmaReadFifo::size
size_t size() const
Get the amount of data stored in the FIFO.
Definition: dma_device.hh:442
gem5::Packet::dataStatic
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
Definition: packet.hh:1175
gem5::DmaPort::pendingCount
uint32_t pendingCount
Number of outstanding packets the dma port has.
Definition: dma_device.hh:174
gem5::DmaDevice::dmaPort
DmaPort dmaPort
Definition: dma_device.hh:221
gem5::Flags< FlagsType >
gem5::DrainState
DrainState
Object drain/handover states.
Definition: drain.hh:74
gem5::DmaReadFifo::nextAddr
Addr nextAddr
Definition: dma_device.hh:579
dma_device.hh
gem5::DmaPort::transmitList
std::deque< DmaReqState * > transmitList
Use a deque as we never do any insertion or removal in the middle.
Definition: dma_device.hh:168
gem5::DmaReadFifo::DmaDoneEvent::DmaDoneEvent
DmaDoneEvent(DmaReadFifo *_parent, size_t max_size)
Definition: dma_device.cc:621
gem5::System
Definition: system.hh:74
gem5::DmaReadFifo::onIdle
virtual void onIdle()
Last response received callback.
Definition: dma_device.hh:516
gem5::DmaPort::cacheLineSize
const int cacheLineSize
Definition: dma_device.hh:190
gem5::DmaReadFifo::freeRequests
std::deque< DmaDoneEventUPtr > freeRequests
Definition: dma_device.hh:583
gem5::Named::name
virtual std::string name() const
Definition: named.hh:47
gem5::VegaISA::p
Bitfield< 54 > p
Definition: pagetable.hh:70
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:210
gem5::Event
Definition: eventq.hh:254
gem5::Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
gem5::DmaPort::sendDma
void sendDma()
For timing, attempt to send the first item on the transmit list, and if it is successful and there ar...
Definition: dma_device.cc:385
gem5::probing::Packet
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:108
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::DmaDevice::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: dma_device.cc:162
gem5::RequestPtr
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
gem5::DmaReadFifo::DmaDoneEvent::cancel
void cancel()
Definition: dma_device.cc:634
gem5::MemCmd::ReadReq
@ ReadReq
Definition: packet.hh:87
gem5::DmaPort::memBackdoors
AddrRangeMap< MemBackdoorPtr, 1 > memBackdoors
Definition: dma_device.hh:64
gem5::DmaPort::DmaReqState::cmd
const Packet::Command cmd
Command for the request.
Definition: dma_device.hh:120
len
uint16_t len
Definition: helpers.cc:62
gem5::DmaReadFifo::DmaDoneEvent::kill
void kill()
Definition: dma_device.cc:627
gem5::DmaReadFifo::resumeFill
void resumeFill()
Try to issue new DMA requests or bypass DMA requests.
Definition: dma_device.cc:516
gem5::DmaPort::DmaReqState::data
uint8_t *const data
Pointer to a buffer for the data.
Definition: dma_device.hh:107
gem5::DmaReadFifo::reqFlags
const Request::Flags reqFlags
Request flags.
Definition: dma_device.hh:525
gem5::ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:144
gem5::DmaDevice::Params
DmaDeviceParams Params
Definition: dma_device.hh:224
gem5::DmaReadFifo::dmaDone
void dmaDone()
DMA request done, handle incoming data and issue new request.
Definition: dma_device.cc:583
gem5::Port::isConnected
bool isConnected() const
Is this port currently connected to a peer?
Definition: port.hh:133
flags
uint8_t flags
Definition: helpers.cc:66
gem5::DmaPort::retryPending
bool retryPending
Whether the other side expects us to wait for a retry.
Definition: dma_device.hh:182
gem5::DrainState::Drained
@ Drained
Buffers drained, ready for serialization/handover.
gem5::System::isTimingMode
bool isTimingMode() const
Is the system in timing mode?
Definition: system.hh:270
gem5::DmaReadFifo::get
T get()
Definition: dma_device.hh:434
gem5::DmaReadFifo::stopFill
void stopFill()
Stop the DMA engine.
Definition: dma_device.cc:503
gem5::DmaReadFifo::DmaDoneEvent
Definition: dma_device.hh:532
gem5::DmaReadFifo::resumeFillTiming
void resumeFillTiming()
Try to issue new DMA requests during normal execution.
Definition: dma_device.cc:557
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::Packet::isError
bool isError() const
Definition: packet.hh:622
gem5::DmaPort::handleResp
void handleResp(DmaReqState *state, Addr addr, Addr size, Tick delay=0)
Definition: dma_device.cc:83
gem5::Packet::senderState
SenderState * senderState
This packet's sender state.
Definition: packet.hh:545
name
const std::string & name()
Definition: trace.cc:48
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568
gem5::MemBackdoor
Definition: backdoor.hh:41
gem5::context_switch_task_id::DMA
@ DMA
Definition: request.hh:84
gem5::ClockedObject
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
Definition: clocked_object.hh:234
gem5::Clocked::clockEdge
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...
Definition: clocked_object.hh:177
gem5::DmaReadFifo::DmaDoneEvent::reset
void reset(size_t size)
Definition: dma_device.cc:640
gem5::DmaReadFifo::maxReqSize
const Addr maxReqSize
Maximum request size in bytes.
Definition: dma_device.hh:516
gem5::DmaReadFifo::fifoSize
const size_t fifoSize
Maximum FIFO size in bytes.
Definition: dma_device.hh:523
gem5::DmaReadFifo::atEndOfBlock
bool atEndOfBlock() const
Has the DMA engine sent out the last request for the active block?
Definition: dma_device.hh:478
gem5::DmaReadFifo::DmaDoneEvent::process
void process()
Definition: dma_device.cc:649
gem5::EventManager::deschedule
void deschedule(Event &event)
Definition: eventq.hh:1021
gem5::MemCmd::toString
const std::string & toString() const
Return the string to a cmd given by idx.
Definition: packet.hh:276
gem5::Drainable::signalDrainDone
void signalDrainDone() const
Signal that an object is drained.
Definition: drain.hh:305
warn_if
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
Definition: logging.hh:283
state
atomic_var_t state
Definition: helpers.cc:188
gem5::DmaPort::sendAtomicReq
bool sendAtomicReq(DmaReqState *state)
Send the next packet from a DMA request in atomic mode.
Definition: dma_device.cc:297
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:214
gem5::Port
Ports are used to interface objects to each other.
Definition: port.hh:61
gem5::DmaPort::handleRespPacket
void handleRespPacket(PacketPtr pkt, Tick delay=0)
Handle a response packet by updating the corresponding DMA request state to reflect the bytes receive...
Definition: dma_device.cc:67
gem5::DmaPort::recvReqRetry
void recvReqRetry() override
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
Definition: dma_device.cc:181
gem5::ChunkGenerator::addr
Addr addr() const
Return starting address of current chunk.
Definition: chunk_generator.hh:119
clocked_object.hh
SERIALIZE_CONTAINER
#define SERIALIZE_CONTAINER(member)
Definition: serialize.hh:626
gem5::ArmISA::sendEvent
void sendEvent(ThreadContext *tc)
Send an event (SEV) to a specific PE if there isn't already a pending event.
Definition: utility.cc:65
gem5::DmaPort::recvTimingResp
bool recvTimingResp(PacketPtr pkt) override
Receive a timing response from the peer.
Definition: dma_device.cc:146
gem5::DmaPort::requestorId
const RequestorID requestorId
Id for all requests.
Definition: dma_device.hh:164
gem5::DmaPort::trySendTimingReq
void trySendTimingReq()
Take the first request on the transmit list and attempt to send a timing packet from it.
Definition: dma_device.cc:254
gem5::DmaDevice::DmaDevice
DmaDevice(const Params &p)
Definition: dma_device.cc:157
logging.hh
gem5::DmaPort::DmaReqState::createPacket
PacketPtr createPacket()
Definition: dma_device.cc:128
gem5::Fifo::write
void write(InputIterator in, size_t len)
Definition: circlebuf.hh:234
gem5::DmaReadFifo::buffer
Fifo< uint8_t > buffer
Definition: dma_device.hh:577
gem5::DmaReadFifo::DmaDoneEventUPtr
std::unique_ptr< DmaDoneEvent > DmaDoneEventUPtr
Definition: dma_device.hh:556
gem5::CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:66
gem5::DmaPort
Definition: dma_device.hh:61
gem5::DmaPort::DmaPort
DmaPort(ClockedObject *dev, System *s, uint32_t sid=0, uint32_t ssid=0)
Definition: dma_device.cc:58
gem5::DmaReadFifo::DmaReadFifo
DmaReadFifo(DmaPort &port, size_t size, unsigned max_req_size, unsigned max_pending, Request::Flags flags=0)
Definition: dma_device.cc:426
trace.hh
gem5::DmaPort::defaultSSid
const uint32_t defaultSSid
Default substreamId.
Definition: dma_device.hh:188
gem5::DmaPort::sendAtomicBdReq
bool sendAtomicBdReq(DmaReqState *state)
Send the next packet from a DMA request in atomic mode, and request and/or use memory backdoors if po...
Definition: dma_device.cc:312
gem5::Packet::getAddr
Addr getAddr() const
Definition: packet.hh:807
gem5::DmaPort::drain
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
Definition: dma_device.cc:170
gem5::DmaPort::DmaReqState::sid
const uint32_t sid
Stream IDs.
Definition: dma_device.hh:116
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::DmaPort::sys
System *const sys
The system that device/port are in.
Definition: dma_device.hh:161
gem5::DmaReadFifo::pendingRequests
std::deque< DmaDoneEventUPtr > pendingRequests
Definition: dma_device.hh:582
gem5::Fifo::read
void read(OutputIterator out, size_t len)
Definition: circlebuf.hh:230
gem5::MemCmd::isRead
bool isRead() const
Definition: packet.hh:227
gem5::DmaReadFifo::handlePending
void handlePending()
Handle pending requests that have been flagged as done.
Definition: dma_device.cc:595
gem5::DmaReadFifo::~DmaReadFifo
~DmaReadFifo()
Definition: dma_device.cc:440
gem5::DmaReadFifo::drain
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
Definition: dma_device.cc:614
gem5::Packet::isResponse
bool isResponse() const
Definition: packet.hh:598
gem5::DrainState::Draining
@ Draining
Draining buffers pending serialization/handover.
gem5::DmaReadFifo::resumeFillBypass
void resumeFillBypass()
Try to bypass DMA requests in non-caching mode.
Definition: dma_device.cc:535
gem5::Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:458
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:188
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84
gem5::PioDevice::getPort
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition: io_device.cc:67
gem5::DmaPort::defaultSid
const uint32_t defaultSid
Default streamId.
Definition: dma_device.hh:185

Generated on Sun Jul 30 2023 01:56:55 for gem5 by doxygen 1.8.17