gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
dma_device.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2013, 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) 2004-2005 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#ifndef __DEV_DMA_DEVICE_HH__
42#define __DEV_DMA_DEVICE_HH__
43
44#include <deque>
45#include <optional>
46#include <memory>
47
50#include "base/circlebuf.hh"
51#include "dev/io_device.hh"
52#include "mem/backdoor.hh"
53#include "params/DmaDevice.hh"
54#include "sim/drain.hh"
55#include "sim/system.hh"
56
57namespace gem5
58{
59
60class ClockedObject;
61
62class DmaPort : public RequestPort, public Drainable
63{
64 private:
66
72 void trySendTimingReq();
73
81 void sendDma();
82
84 {
88
91
93 bool aborted = false;
94
97
100
102 const Tick delay;
103
106
108 uint8_t *const data = nullptr;
109
112
115
117 const std::optional<uint32_t> sid;
118 const std::optional<uint32_t> ssid;
119
122
124 uint8_t *_data, Request::Flags _flags, RequestorID _id,
125 std::optional<uint32_t> _sid, std::optional<uint32_t> _ssid,
126 Event *ce, Tick _delay, Event *ae=nullptr)
127 : completionEvent(ce), abortEvent(ae), totBytes(tb), delay(_delay),
128 gen(addr, tb, chunk_sz), data(_data), flags(_flags), id(_id),
129 sid(_sid), ssid(_ssid), cmd(_cmd)
130 {}
131
133 };
134
136 bool sendAtomicReq(DmaReqState *state);
141 bool sendAtomicBdReq(DmaReqState *state);
142
153 void handleRespPacket(PacketPtr pkt, Tick delay=0);
154 void handleResp(DmaReqState *state, Addr addr, Addr size, Tick delay=0);
155
156 public:
159
162 System *const sys;
163
166
167 protected:
170
173
175 uint32_t pendingCount = 0;
176
183 bool retryPending = false;
184
186 const std::optional<uint32_t> defaultSid;
187
189 const std::optional<uint32_t> defaultSSid;
190
192
193 protected:
194
195 bool recvTimingResp(PacketPtr pkt) override;
196 void recvReqRetry() override;
197
198 public:
199
200 DmaPort(ClockedObject *dev, System *s, std::optional<uint32_t> sid=0,
201 std::optional<uint32_t> ssid=0);
202
203 void
204 dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
205 uint8_t *data, Tick delay, Request::Flags flag=0);
206
207 void
208 dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
209 uint8_t *data, std::optional<uint32_t> sid,
210 std::optional<uint32_t> ssid, Tick delay, Request::Flags flag=0);
211
212 // Abort and remove any pending DMA transmissions.
213 void abortPending();
214
215 bool dmaPending() const { return pendingCount > 0; }
216
217 DrainState drain() override;
218};
219
220class DmaDevice : public PioDevice
221{
222 protected:
224
225 public:
226 typedef DmaDeviceParams Params;
227 DmaDevice(const Params &p);
228 virtual ~DmaDevice() = default;
229
230 void
231 dmaWrite(Addr addr, int size, Event *event, uint8_t *data,
232 std::optional<uint32_t> sid, std::optional<uint32_t> ssid,
233 Tick delay=0)
234 {
235 dmaPort.dmaAction(MemCmd::WriteReq, addr, size, event, data,
236 sid, ssid, delay);
237 }
238
239 void
240 dmaWrite(Addr addr, int size, Event *event, uint8_t *data, Tick delay=0)
241 {
242 dmaPort.dmaAction(MemCmd::WriteReq, addr, size, event, data, delay);
243 }
244
245 void
246 dmaRead(Addr addr, int size, Event *event, uint8_t *data,
247 std::optional<uint32_t> sid, std::optional<uint32_t> ssid,
248 Tick delay=0)
249 {
250 dmaPort.dmaAction(MemCmd::ReadReq, addr, size, event, data,
251 sid, ssid, delay);
252 }
253
254 void
255 dmaRead(Addr addr, int size, Event *event, uint8_t *data, Tick delay=0)
256 {
257 dmaPort.dmaAction(MemCmd::ReadReq, addr, size, event, data, delay);
258 }
259
260 bool dmaPending() const { return dmaPort.dmaPending(); }
261
262 void init() override;
263
264 Addr cacheBlockSize() const { return sys->cacheLineSize(); }
265
266 Port &getPort(const std::string &if_name,
267 PortID idx=InvalidPortID) override;
268
269};
270
279class DmaCallback : public Drainable
280{
281 public:
282 virtual const std::string name() const { return "DmaCallback"; }
283
292 drain() override
293 {
295 }
296
297 protected:
298 int count = 0;
299
300 virtual ~DmaCallback() = default;
301
305 virtual void process() = 0;
306
307 private:
313 void
315 {
316 if (--count == 0) {
317 process();
318 // Need to notify DrainManager that this object is finished
319 // draining, even though it is immediately deleted.
321 delete this;
322 }
323 }
324
325 public:
326
331 Event *
333 {
334 ++count;
335 return new EventFunctionWrapper([this]{ chunkComplete(); }, name(),
336 true);
337 }
338};
339
383class DmaReadFifo : public Drainable, public Serializable
384{
385 public:
386 DmaReadFifo(DmaPort &port, size_t size,
387 unsigned max_req_size,
388 unsigned max_pending,
389 Request::Flags flags=0);
390
391 ~DmaReadFifo();
392
393 public: // Serializable
394 void serialize(CheckpointOut &cp) const override;
395 void unserialize(CheckpointIn &cp) override;
396
397 public: // Drainable
398 DrainState drain() override;
399
400 public: // FIFO access
417 bool tryGet(uint8_t *dst, size_t len);
418
419 template<typename T>
420 bool
421 tryGet(T &value)
422 {
423 return tryGet(static_cast<T *>(&value), sizeof(T));
424 };
425
434 void get(uint8_t *dst, size_t len);
435
436 template<typename T>
437 T
439 {
440 T value;
441 get(static_cast<uint8_t *>(&value), sizeof(T));
442 return value;
443 };
444
446 size_t size() const { return buffer.size(); }
448 void flush() { buffer.flush(); }
449
451 public: // FIFO fill control
466 void startFill(Addr start, size_t size);
467
476 void stopFill();
477
482 bool atEndOfBlock() const { return nextAddr == endAddr; }
483
488 bool
489 isActive() const
490 {
491 return !(pendingRequests.empty() && atEndOfBlock());
492 }
493
495 protected: // Callbacks
507 virtual void onEndOfBlock() {};
508
520 virtual void onIdle() {};
521
523 private: // Configuration
527 const size_t fifoSize;
530
532
534
535 private:
536 class DmaDoneEvent : public Event
537 {
538 public:
539 DmaDoneEvent(DmaReadFifo *_parent, size_t max_size);
540
541 void kill();
542 void cancel();
543 bool canceled() const { return _canceled; }
544 void reset(size_t size);
545 void process();
546
547 bool done() const { return _done; }
548 size_t requestSize() const { return _requestSize; }
549 const uint8_t *data() const { return _data.data(); }
550 uint8_t *data() { return _data.data(); }
551
552 private:
554 bool _done = false;
555 bool _canceled = false;
558 };
559
560 typedef std::unique_ptr<DmaDoneEvent> DmaDoneEventUPtr;
561
566 void dmaDone();
567
569 void handlePending();
570
572 void resumeFill();
573
575 void resumeFillTiming();
576
578 void resumeFillBypass();
579
580 private: // Internal state
582
585
588};
589
590} // namespace gem5
591
592#endif // __DEV_DMA_DEVICE_HH__
Declaration and inline definition of ChunkGenerator object.
const char data[]
The AddrRangeMap uses an STL map to implement an interval tree for address decoding.
This class takes an arbitrary memory region (address/length pair) and generates a series of appropria...
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
DMA callback class.
Event * getChunkEvent()
Request a chunk event.
void chunkComplete()
Called by DMA engine completion event on each chunk completion.
virtual ~DmaCallback()=default
DrainState drain() override
DmaPort ensures that all oustanding DMA accesses have completed before it finishes draining.
virtual const std::string name() const
virtual void process()=0
Callback function invoked on completion of all chunks.
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.
bool dmaPending() const
void dmaRead(Addr addr, int size, Event *event, uint8_t *data, Tick delay=0)
void dmaRead(Addr addr, int size, Event *event, uint8_t *data, std::optional< uint32_t > sid, std::optional< uint32_t > ssid, Tick delay=0)
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, std::optional< uint32_t > sid, std::optional< uint32_t > ssid, Tick delay=0)
virtual ~DmaDevice()=default
Addr cacheBlockSize() const
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, Tick delay=0)
DmaDevice(const Params &p)
DmaDeviceParams Params
const std::optional< uint32_t > defaultSSid
Default substreamId.
void abortPending()
bool dmaPending() const
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
const uint8_t * data() const
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.
bool tryGet(T &value)
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 flush()
Flush the FIFO.
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
Event(Priority p=Default_Pri, Flags f=0)
Definition eventq.hh:407
Simple FIFO implementation backed by a circular buffer.
Definition circlebuf.hh:214
MemCmd::Command Command
Definition packet.hh:369
PioDevice(const Params &p)
Definition io_device.cc:50
Ports are used to interface objects to each other.
Definition port.hh:62
RequestPort(const std::string &name, SimObject *_owner, PortID id=InvalidPortID)
Request port.
Definition port.cc:125
gem5::Flags< FlagsType > Flags
Definition request.hh:102
STL deque class.
Definition stl.hh:44
STL vector class.
Definition stl.hh:37
void signalDrainDone() const
Signal that an object is drained.
Definition drain.hh:305
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
Bitfield< 18, 16 > len
Bitfield< 4 > s
Bitfield< 10, 5 > event
Bitfield< 29, 28 > ce
Bitfield< 27 > tb
Bitfield< 0 > p
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
const PortID InvalidPortID
Definition types.hh:246
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
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
uint16_t RequestorID
Definition request.hh:95
Packet * PacketPtr
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 RequestorID id
The requestor ID to use for requests.
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.
DmaReqState(Packet::Command _cmd, Addr addr, Addr chunk_sz, Addr tb, uint8_t *_data, Request::Flags _flags, RequestorID _id, std::optional< uint32_t > _sid, std::optional< uint32_t > _ssid, Event *ce, Tick _delay, Event *ae=nullptr)
const Request::Flags flags
The flags to use for requests.
bool aborted
Whether this request was aborted.
Definition dma_device.hh:93
A virtual base opaque structure used to hold state associated with the packet (e.g....
Definition packet.hh:469

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