gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
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 <optional>
47#include <utility>
48
49#include "base/logging.hh"
50#include "base/trace.hh"
51#include "debug/DMA.hh"
52#include "debug/Drain.hh"
53#include "sim/clocked_object.hh"
54#include "sim/system.hh"
55
56namespace gem5
57{
58
60 std::optional<uint32_t> sid, std::optional<uint32_t> ssid)
61 : RequestPort(dev->name() + ".dma"),
62 device(dev), sys(s), requestorId(s->getRequestorId(dev)),
63 sendEvent([this]{ sendDma(); }, dev->name()),
64 defaultSid(sid), defaultSSid(ssid), cacheLineSize(s->cacheLineSize())
65{ }
66
67void
69{
70 // Should always see a response with a sender state.
71 assert(pkt->isResponse());
72 warn_if(pkt->isError(), "Response pkt error.");
73
74 // Get the DMA sender state.
75 auto *state = dynamic_cast<DmaReqState*>(pkt->senderState);
76 assert(state);
77
78 handleResp(state, pkt->getAddr(), pkt->req->getSize(), delay);
79
80 delete pkt;
81}
82
83void
85{
86 assert(pendingCount != 0);
87 pendingCount--;
88 DPRINTF(DMA, "Received response %s for addr: %#x size: %d nb: %d," \
89 " tot: %d sched %d\n",
90 MemCmd(state->cmd).toString(), addr, size,
91 state->numBytes, state->totBytes,
92 state->completionEvent ?
93 state->completionEvent->scheduled() : 0);
94
95 // Update the number of bytes received based on the request rather
96 // than the packet as the latter could be rounded up to line sizes.
97 state->numBytes += size;
98 assert(state->totBytes >= state->numBytes);
99
100 bool all_bytes = (state->totBytes == state->numBytes);
101 if (state->aborted) {
102 // If this request was aborted, check to see if its in flight accesses
103 // have finished. There may be packets for more than one request in
104 // flight at a time, so check for finished requests, or no more
105 // packets.
106 if (all_bytes || pendingCount == 0) {
107 // If yes, signal its abort event (if any) and delete the state.
108 if (state->abortEvent) {
109 device->schedule(state->abortEvent, curTick());
110 }
111 delete state;
112 }
113 } else if (all_bytes) {
114 // If we have reached the end of this DMA request, then signal the
115 // completion and delete the sate.
116 if (state->completionEvent) {
117 delay += state->delay;
118 device->schedule(state->completionEvent, curTick() + delay);
119 }
120 delete state;
121 }
122
123 // We might be drained at this point, if so signal the drain event.
124 if (pendingCount == 0)
125 signalDrainDone();
126}
127
128PacketPtr
130{
131 RequestPtr req = std::make_shared<Request>(
132 gen.addr(), gen.size(), flags, id);
133 if (sid.has_value()) {
134 req->setStreamId(sid.value());
135 }
136 if (ssid.has_value()) {
137 req->setSubstreamId(ssid.value());
138 }
139 req->taskId(context_switch_task_id::DMA);
140
141 PacketPtr pkt = new Packet(req, cmd);
142
143 if (data)
144 pkt->dataStatic(data + gen.complete());
145
146 pkt->senderState = this;
147 return pkt;
148}
149
150bool
152{
153 // We shouldn't ever get a cacheable block in Modified state.
154 assert(pkt->req->isUncacheable() ||
155 !(pkt->cacheResponding() && !pkt->hasSharers()));
156
157 handleRespPacket(pkt);
158
159 return true;
160}
161
163 : PioDevice(p), dmaPort(this, sys, p.sid, p.ssid)
164{ }
165
166void
168{
169 panic_if(!dmaPort.isConnected(),
170 "DMA port of %s not connected to anything!", name());
172}
173
176{
177 if (pendingCount == 0) {
178 return DrainState::Drained;
179 } else {
180 DPRINTF(Drain, "DmaPort not drained\n");
182 }
183}
184
185void
187{
188 retryPending = false;
189 if (transmitList.size())
191}
192
193void
195 uint8_t *data, std::optional<uint32_t> sid,
196 std::optional<uint32_t> ssid, Tick delay,
197 Request::Flags flag)
198{
199 DPRINTF(DMA, "Starting DMA for addr: %#x size: %d sched: %d\n", addr, size,
200 event ? event->scheduled() : -1);
201
202 // One DMA request sender state for every action, that is then
203 // split into many requests and packets based on the block size,
204 // i.e. cache line size.
205 transmitList.push_back(
206 new DmaReqState(cmd, addr, cacheLineSize, size,
207 data, flag, requestorId, sid, ssid, event, delay));
208
209 // In zero time, also initiate the sending of the packets for the request
210 // we have just created. For atomic this involves actually completing all
211 // the requests.
212 sendDma();
213}
214
215void
217 uint8_t *data, Tick delay, Request::Flags flag)
218{
219 dmaAction(cmd, addr, size, event, data,
220 defaultSid, defaultSSid, delay, flag);
221}
222
223void
225{
226 if (inRetry) {
227 delete inRetry;
228 inRetry = nullptr;
229 }
230
231 if (pendingCount && !transmitList.empty()) {
232 auto *state = transmitList.front();
233 if (state->numBytes != state->gen.complete()) {
234 // In flight packets refer to the transmission at the front of the
235 // list, and not a transmission whose packets have all been sent
236 // but not completed. Preserve the state so the packets don't have
237 // dangling pointers.
238 transmitList.pop_front();
239 state->aborted = true;
240 }
241 }
242
243 // Get rid of requests that haven't started yet.
244 while (!transmitList.empty()) {
245 auto *state = transmitList.front();
246 if (state->abortEvent)
247 device->schedule(state->abortEvent, curTick());
248 delete state;
249 transmitList.pop_front();
250 }
251
252 if (sendEvent.scheduled())
253 device->deschedule(sendEvent);
254
255 if (pendingCount == 0)
257}
258
259void
261{
262 // Send the next packet for the first DMA request on the transmit list,
263 // and schedule the following send if it is successful
264 DmaReqState *state = transmitList.front();
265
266 PacketPtr pkt = inRetry ? inRetry : state->createPacket();
267 inRetry = nullptr;
268
269 DPRINTF(DMA, "Trying to send %s addr %#x\n", pkt->cmdString(),
270 pkt->getAddr());
271
272 // Check if this was the last packet now, since hypothetically the packet
273 // response may come immediately, and state may be deleted.
274 bool last = state->gen.last();
275 if (sendTimingReq(pkt)) {
276 pendingCount++;
277 } else {
278 retryPending = true;
279 inRetry = pkt;
280 }
281 if (!retryPending) {
282 state->gen.next();
283 // If that was the last packet from this request, pop it from the list.
284 if (last)
285 transmitList.pop_front();
286 DPRINTF(DMA, "-- Done\n");
287 // If there is more to do, then do so.
288 if (!transmitList.empty()) {
289 // This should ultimately wait for as many cycles as the device
290 // needs to send the packet, but currently the port does not have
291 // any known width so simply wait a single cycle.
292 device->schedule(sendEvent, device->clockEdge(Cycles(1)));
293 }
294 } else {
295 DPRINTF(DMA, "-- Failed, waiting for retry\n");
296 }
297
298 DPRINTF(DMA, "TransmitList: %d, retryPending: %d\n",
299 transmitList.size(), retryPending ? 1 : 0);
300}
301
302bool
304{
305 PacketPtr pkt = state->createPacket();
306 DPRINTF(DMA, "Sending DMA for addr: %#x size: %d\n",
307 state->gen.addr(), state->gen.size());
308 pendingCount++;
309 Tick lat = sendAtomic(pkt);
310
311 // Check if we're done, since handleResp may delete state.
312 bool done = !state->gen.next();
313 handleRespPacket(pkt, lat);
314 return done;
315}
316
317bool
319{
320 bool done = false;
321 pendingCount++;
322
323 auto bd_it = memBackdoors.contains(state->gen.addr());
324 if (bd_it == memBackdoors.end()) {
325 // We don't have a backdoor for this address, so use a packet.
326
327 PacketPtr pkt = state->createPacket();
328 DPRINTF(DMA, "Sending DMA for addr: %#x size: %d\n",
329 state->gen.addr(), state->gen.size());
330
331 MemBackdoorPtr bd = nullptr;
332 Tick lat = sendAtomicBackdoor(pkt, bd);
333
334 // If we got a backdoor, record it.
335 if (bd && memBackdoors.insert(bd->range(), bd) != memBackdoors.end()) {
336 // Invalidation callback which finds this backdoor and removes it.
337 auto callback = [this](const MemBackdoor &backdoor) {
338 for (auto it = memBackdoors.begin();
339 it != memBackdoors.end(); it++) {
340 if (it->second == &backdoor) {
341 memBackdoors.erase(it);
342 return;
343 }
344 }
345 panic("Got invalidation for unknown memory backdoor.");
346 };
347 bd->addInvalidationCallback(callback);
348 }
349
350 // Check if we're done now, since handleResp may delete state.
351 done = !state->gen.next();
352 handleRespPacket(pkt, lat);
353 } else {
354 // We have a backdoor that can at least partially satisfy this request.
355 DPRINTF(DMA, "Handling DMA for addr: %#x size %d through backdoor\n",
356 state->gen.addr(), state->gen.size());
357
358 const auto *bd = bd_it->second;
359 // Offset of this access into the backdoor.
360 const Addr offset = state->gen.addr() - bd->range().start();
361 // How many bytes we still need.
362 const Addr remaining = state->totBytes - state->gen.complete();
363 // How many bytes this backdoor can provide, starting from offset.
364 const Addr available = bd->range().size() - offset;
365
366 // How many bytes we're going to handle through this backdoor.
367 const Addr handled = std::min(remaining, available);
368
369 // If there's a buffer for data, read/write it.
370 if (state->data) {
371 uint8_t *bd_data = bd->ptr() + offset;
372 uint8_t *state_data = state->data + state->gen.complete();
373 if (MemCmd(state->cmd).isRead())
374 memcpy(state_data, bd_data, handled);
375 else
376 memcpy(bd_data, state_data, handled);
377 }
378
379 // Advance the chunk generator past this region of memory.
380 state->gen.setNext(state->gen.addr() + handled);
381
382 // Check if we're done now, since handleResp may delete state.
383 done = !state->gen.next();
384 handleResp(state, state->gen.addr(), handled);
385 }
386
387 return done;
388}
389
390void
392{
393 // Some kind of selection between access methods. More work is going to
394 // have to be done to make switching actually work.
395 assert(transmitList.size());
396
397 if (sys->isTimingMode()) {
398 // If we are either waiting for a retry or are still waiting after
399 // sending the last packet, then do not proceed.
400 if (retryPending || sendEvent.scheduled()) {
401 DPRINTF(DMA, "Can't send immediately, waiting to send\n");
402 return;
403 }
404
406 } else if (sys->isAtomicMode()) {
407 const bool bypass = sys->bypassCaches();
408
409 // Send everything there is to send in zero time.
410 while (!transmitList.empty()) {
411 DmaReqState *state = transmitList.front();
412 transmitList.pop_front();
413
414 bool done = state->gen.done();
415 while (!done)
416 done = bypass ? sendAtomicBdReq(state) : sendAtomicReq(state);
417 }
418 } else {
419 panic("Unknown memory mode.");
420 }
421}
422
423Port &
424DmaDevice::getPort(const std::string &if_name, PortID idx)
425{
426 if (if_name == "dma") {
427 return dmaPort;
428 }
429 return PioDevice::getPort(if_name, idx);
430}
431
433 unsigned max_req_size,
434 unsigned max_pending,
435 Request::Flags flags)
436 : maxReqSize(max_req_size), fifoSize(size),
437 reqFlags(flags), port(_port), cacheLineSize(port.sys->cacheLineSize()),
438 buffer(size)
439{
440 freeRequests.resize(max_pending);
441 for (auto &e : freeRequests)
442 e.reset(new DmaDoneEvent(this, max_req_size));
443
444}
445
447{
448 for (auto &p : pendingRequests) {
449 DmaDoneEvent *e(p.release());
450
451 if (e->done()) {
452 delete e;
453 } else {
454 // We can't kill in-flight DMAs, so we'll just transfer
455 // ownership to the event queue so that they get freed
456 // when they are done.
457 e->kill();
458 }
459 }
460}
461
462void
471
472void
479
480bool
481DmaReadFifo::tryGet(uint8_t *dst, size_t len)
482{
483 if (buffer.size() >= len) {
484 buffer.read(dst, len);
485 resumeFill();
486 return true;
487 } else {
488 return false;
489 }
490}
491
492void
493DmaReadFifo::get(uint8_t *dst, size_t len)
494{
495 panic_if(!tryGet(dst, len), "Buffer underrun in DmaReadFifo::get()");
496}
497
498void
500{
501 assert(atEndOfBlock());
502
503 nextAddr = start;
504 endAddr = start + size;
505 resumeFill();
506}
507
508void
510{
511 // Prevent new DMA requests by setting the next address to the end
512 // address. Pending requests will still complete.
514
515 // Flag in-flight accesses as canceled. This prevents their data
516 // from being written to the FIFO.
517 for (auto &p : pendingRequests)
518 p->cancel();
519}
520
521void
523{
524 // Don't try to fetch more data if we are draining. This ensures
525 // that the DMA engine settles down before we checkpoint it.
527 return;
528
529 const bool old_eob(atEndOfBlock());
530
531 if (port.sys->bypassCaches())
533 else
535
536 if (!old_eob && atEndOfBlock())
537 onEndOfBlock();
538}
539
540void
542{
543 const size_t fifo_space = buffer.capacity() - buffer.size();
544 if (fifo_space >= cacheLineSize || buffer.capacity() < cacheLineSize) {
545 const size_t block_remaining = endAddr - nextAddr;
546 const size_t xfer_size = std::min(fifo_space, block_remaining);
547 std::vector<uint8_t> tmp_buffer(xfer_size);
548
549 assert(pendingRequests.empty());
550 DPRINTF(DMA, "Direct bypass startAddr=%#x xfer_size=%#x " \
551 "fifo_space=%#x block_remaining=%#x\n",
552 nextAddr, xfer_size, fifo_space, block_remaining);
553
554 port.dmaAction(MemCmd::ReadReq, nextAddr, xfer_size, nullptr,
555 tmp_buffer.data(), 0, reqFlags);
556
557 buffer.write(tmp_buffer.begin(), xfer_size);
558 nextAddr += xfer_size;
559 }
560}
561
562void
564{
565 size_t size_pending(0);
566 for (auto &e : pendingRequests)
567 size_pending += e->requestSize();
568
569 while (!freeRequests.empty() && !atEndOfBlock()) {
570 const size_t req_size(std::min(maxReqSize, endAddr - nextAddr));
571 if (buffer.size() + size_pending + req_size > fifoSize)
572 break;
573
574 DmaDoneEventUPtr event(std::move(freeRequests.front()));
575 freeRequests.pop_front();
576 assert(event);
577
578 event->reset(req_size);
579 port.dmaAction(MemCmd::ReadReq, nextAddr, req_size, event.get(),
580 event->data(), 0, reqFlags);
581 nextAddr += req_size;
582 size_pending += req_size;
583
584 pendingRequests.emplace_back(std::move(event));
585 }
586}
587
588void
590{
591 const bool old_active(isActive());
592
594 resumeFill();
595
596 if (old_active && !isActive())
597 onIdle();
598}
599
600void
602{
603 while (!pendingRequests.empty() && pendingRequests.front()->done()) {
604 // Get the first finished pending request
605 DmaDoneEventUPtr event(std::move(pendingRequests.front()));
606 pendingRequests.pop_front();
607
608 if (!event->canceled())
609 buffer.write(event->data(), event->requestSize());
610
611 // Move the event to the list of free requests
612 freeRequests.emplace_back(std::move(event));
613 }
614
615 if (pendingRequests.empty())
617}
618
625
626
628 : parent(_parent), _data(max_size, 0)
629{
630}
631
632void
638
639void
644
645void
647{
648 assert(size <= _data.size());
649 _done = false;
650 _canceled = false;
652}
653
654void
656{
657 if (!parent)
658 return;
659
660 assert(!_done);
661 _done = true;
662 parent->dmaDone();
663}
664
665} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
const char data[]
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
Cycles is a wrapper class for representing cycle counts, i.e.
Definition types.hh:79
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
DmaDevice(const Params &p)
DmaDeviceParams Params
const std::optional< uint32_t > defaultSSid
Default substreamId.
void abortPending()
ClockedObject *const device
The device that owns this port.
EventFunctionWrapper sendEvent
Event used to schedule a future sending from the transmit list.
System *const sys
The system that device/port are in.
void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
bool sendAtomicBdReq(DmaReqState *state)
Send the next packet from a DMA request in atomic mode, and request and/or use memory backdoors if po...
const std::optional< uint32_t > defaultSid
Default streamId.
void recvReqRetry() override
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
DmaPort(ClockedObject *dev, System *s, std::optional< uint32_t > sid=0, std::optional< uint32_t > ssid=0)
Definition dma_device.cc:59
void trySendTimingReq()
Take the first request on the transmit list and attempt to send a timing packet from it.
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
PacketPtr inRetry
The packet (if any) waiting for a retry to send.
uint32_t pendingCount
Number of outstanding packets the dma port has.
std::deque< DmaReqState * > transmitList
Use a deque as we never do any insertion or removal in the middle.
AddrRangeMap< MemBackdoorPtr, 1 > memBackdoors
Definition dma_device.hh:65
void sendDma()
For timing, attempt to send the first item on the transmit list, and if it is successful and there ar...
void handleResp(DmaReqState *state, Addr addr, Addr size, Tick delay=0)
Definition dma_device.cc:84
bool retryPending
Whether the other side expects us to wait for a retry.
const RequestorID requestorId
Id for all requests.
bool recvTimingResp(PacketPtr pkt) override
Receive a timing response from the peer.
bool sendAtomicReq(DmaReqState *state)
Send the next packet from a DMA request in atomic mode.
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:68
const Addr cacheLineSize
std::vector< uint8_t > _data
DmaDoneEvent(DmaReadFifo *_parent, size_t max_size)
Fifo< uint8_t > buffer
void serialize(CheckpointOut &cp) const override
Serialize an object.
size_t size() const
Get the amount of data stored in the FIFO.
virtual void onIdle()
Last response received callback.
bool tryGet(uint8_t *dst, size_t len)
Try to read data from the FIFO.
void startFill(Addr start, size_t size)
Start filling the FIFO.
DmaReadFifo(DmaPort &port, size_t size, unsigned max_req_size, unsigned max_pending, Request::Flags flags=0)
const Request::Flags reqFlags
Request flags.
virtual void onEndOfBlock()
End of block callback.
void resumeFill()
Try to issue new DMA requests or bypass DMA requests.
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
void unserialize(CheckpointIn &cp) override
Unserialize an object.
std::deque< DmaDoneEventUPtr > freeRequests
void dmaDone()
DMA request done, handle incoming data and issue new request.
bool isActive() const
Is the DMA engine active (i.e., are there still in-flight accesses)?
void stopFill()
Stop the DMA engine.
void resumeFillBypass()
Try to bypass DMA requests in non-caching mode.
bool atEndOfBlock() const
Has the DMA engine sent out the last request for the active block?
const Addr maxReqSize
Maximum request size in bytes.
const size_t fifoSize
Maximum FIFO size in bytes.
void handlePending()
Handle pending requests that have been flagged as done.
const Addr cacheLineSize
void resumeFillTiming()
Try to issue new DMA requests during normal execution.
std::unique_ptr< DmaDoneEvent > DmaDoneEventUPtr
std::deque< DmaDoneEventUPtr > pendingRequests
static const FlagsType AutoDelete
Definition eventq.hh:110
void setFlags(Flags _flags)
Definition eventq.hh:331
bool isRead() const
Definition packet.hh:227
virtual std::string name() const
Definition named.hh:60
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
Addr getAddr() const
Definition packet.hh:807
const std::string & cmdString() const
Return the string name of the cmd field (for debugging and tracing).
Definition packet.hh:588
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
Definition packet.hh:1175
SenderState * senderState
This packet's sender state.
Definition packet.hh:545
MemCmd::Command Command
Definition packet.hh:369
RequestPtr req
A pointer to the original request.
Definition packet.hh:377
bool cacheResponding() const
Definition packet.hh:659
bool hasSharers() const
Definition packet.hh:686
PioDevice(const Params &p)
Definition io_device.cc:50
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
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition io_device.cc:59
Ports are used to interface objects to each other.
Definition port.hh:62
const std::string name() const
Return port name (for DPRINTF).
Definition port.hh:111
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:552
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
Definition port.hh:603
RequestPort(const std::string &name, SimObject *_owner, PortID id=InvalidPortID)
Request port.
Definition port.cc:125
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:565
gem5::Flags< FlagsType > Flags
Definition request.hh:102
STL vector class.
Definition stl.hh:37
ClockedObject declaration and implementation.
bool last() const
Is this the last chunk?
Addr addr() const
Return starting address of current chunk.
Addr complete() const
Number of bytes we have already chunked up.
void setNext(Addr next)
Grow this chunk to cover additional bytes which are already handled.
bool done() const
Are we done?
Addr size() const
Return size in bytes of current chunk.
bool next()
Advance generator to next chunk.
void signalDrainDone() const
Signal that an object is drained.
Definition drain.hh:305
DrainState drainState() const
Return the current drain state of an object.
Definition drain.hh:324
DrainState
Object drain/handover states.
Definition drain.hh:75
@ Draining
Draining buffers pending serialization/handover.
Definition drain.hh:77
@ Drained
Buffers drained, ready for serialization/handover.
Definition drain.hh:78
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:220
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:246
#define UNSERIALIZE_CONTAINER(member)
Definition serialize.hh:651
#define SERIALIZE_CONTAINER(member)
Definition serialize.hh:643
Bitfield< 18, 16 > len
Bitfield< 4 > s
Bitfield< 23, 0 > offset
Definition types.hh:144
Bitfield< 9 > e
Definition misc_types.hh:65
Bitfield< 10, 5 > event
Bitfield< 0 > p
Bitfield< 15, 2 > bd
Definition types.hh:79
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
std::shared_ptr< Request > RequestPtr
Definition request.hh:94
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
std::ostream CheckpointOut
Definition serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
MemBackdoor * MemBackdoorPtr
Definition backdoor.hh:127
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition types.hh:245
uint64_t Tick
Tick count type.
Definition types.hh:58
Packet * PacketPtr
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568
const Packet::Command cmd
Command for the request.
const std::optional< uint32_t > ssid
const Addr totBytes
Total number of bytes that this transaction involves.
Definition dma_device.hh:96
Event * completionEvent
Event to call on the device when this transaction (all packets) complete.
Definition dma_device.hh:87
Addr numBytes
Number of bytes that have been acked for this transaction.
Definition dma_device.hh:99
const Tick delay
Amount to delay completion of dma by.
ChunkGenerator gen
Object to track what chunks of bytes to send at a time.
uint8_t *const data
Pointer to a buffer for the data.
Event * abortEvent
Event to call on the device when this transaction is aborted.
Definition dma_device.hh:90
const std::optional< uint32_t > sid
Stream IDs.
const Request::Flags flags
The flags to use for requests.
bool aborted
Whether this request was aborted.
Definition dma_device.hh:93

Generated on Mon May 26 2025 09:19:09 for gem5 by doxygen 1.13.2