gem5 v24.0.0.0
Loading...
Searching...
No Matches
system_hub.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2021 Advanced Micro Devices, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
33
34#include "debug/AMDGPUSystemHub.hh"
35#include "mem/packet_access.hh"
36#include "mem/port.hh"
37
38namespace gem5
39{
40
41void
43{
44 // Some requests, in particular atomics, need to be sent in order
45 // to receive the correct values. If there is an atomic in progress
46 // we must block it until that request is complete. This is overly
47 // conservative and blocks reads/writes but this situation is rare
48 // so it should not impact simulated performance.
49 DeferredReq this_req(pkt, callback);
50 outstandingReqs[pkt->getAddr()].push_back(this_req);
51
52 if (outstandingReqs[pkt->getAddr()].size () > 1) {
53 // There is another request in progress, Delay this one.
54 DPRINTF(AMDGPUSystemHub, "SystemHub deferring request for %#lx\n",
55 pkt->getAddr());
56 } else {
57 // No other requests, we can send immediately.
58 sendDeferredRequest(this_req);
59 }
60}
61
62void
64{
65 PacketPtr pkt = deferredReq.first;
66 Event *callback = deferredReq.second;
67 Tick delay = 0;
68 std::string req_type;
69
70 if (pkt->isAtomicOp()) {
71 AtomicResponseEvent *atomicRespEvent =
72 new AtomicResponseEvent(*this, callback, pkt);
73
74 // First read the value. The response event will do the atomic/write
75 // This places the current value in the packet, which is correct since
76 // atomics return the value prior to performing the atomic.
77 dmaRead(pkt->getAddr(), pkt->getSize(), atomicRespEvent,
78 pkt->getPtr<uint8_t>(), 0, 0, delay);
79
80 req_type = "Atomic";
81 } else if (pkt->isWrite()) {
82 ResponseEvent *dmaRespEvent =
83 new ResponseEvent(*this, callback, pkt);
84
85 dmaWrite(pkt->getAddr(), pkt->getSize(), dmaRespEvent,
86 pkt->getPtr<uint8_t>(), 0, 0, delay);
87
88 req_type = "Write";
89 } else {
90 ResponseEvent *dmaRespEvent =
91 new ResponseEvent(*this, callback, pkt);
92
93 assert(pkt->isRead());
94 dmaRead(pkt->getAddr(), pkt->getSize(), dmaRespEvent,
95 pkt->getPtr<uint8_t>(), 0, 0, delay);
96
97 req_type = "Read";
98 }
99
100 DPRINTF(AMDGPUSystemHub, "SystemHub %s request for %#lx size %d\n",
101 req_type.c_str(), pkt->getAddr(), pkt->getSize());
102}
103
104void
106{
107 // Remove our request
108 assert(outstandingReqs.count(addr));
109
110 [[maybe_unused]] DeferredReq& frontPkt = outstandingReqs[addr].front();
111 assert(frontPkt.first == donePkt);
112
113 outstandingReqs[addr].pop_front();
114
115 // If there are no more requests this can be removed from the map.
116 // Otherwise issue the next request in the list
117 if (outstandingReqs[addr].empty()) {
118 DPRINTF(AMDGPUSystemHub, "SystemHub done with packets for addr %#lx\n",
119 donePkt->getAddr());
120
121 outstandingReqs.erase(addr);
122 } else {
123 DeferredReq& nextPkt = outstandingReqs[addr].front();
124
125 DPRINTF(AMDGPUSystemHub, "SystemHub sending deferred request for addr"
126 " %#lx size %d\n", nextPkt.first->getAddr(),
127 nextPkt.first->getSize());
128
129 sendDeferredRequest(nextPkt);
130 }
131}
132
133void
137
139 AMDGPUSystemHub& _hub, Event *_callback, PacketPtr _pkt)
140 : systemHub(_hub), callback(_callback), pkt(_pkt)
141{
142 // Delete this event after process is called
144}
145
146void
148{
149 DPRINTF(AMDGPUSystemHub, "SystemHub response for addr %#lx size %d\n",
150 pkt->getAddr(), pkt->getSize());
151
152 systemHub.sendNextRequest(pkt->getAddr(), pkt);
153
154 callback->process();
155}
156
158 AMDGPUSystemHub& _hub, Event *_callback, PacketPtr _pkt)
159 : systemHub(_hub), callback(_callback), pkt(_pkt)
160{
161 // Delete this event after process is called
163}
164
165void
167{
168 // Make a second response with the original sender's callback
169 ResponseEvent *dmaRespEvent = new ResponseEvent(systemHub, callback, pkt);
170 Tick delay = 0;
171
172 // Create a new write packet which will be modifed then written
173 RequestPtr write_req =
174 std::make_shared<Request>(pkt->getAddr(), pkt->getSize(), 0,
175 pkt->requestorId());
176
177 PacketPtr write_pkt = Packet::createWrite(write_req);
178 uint8_t *write_data = new uint8_t[pkt->getSize()];
179 std::memcpy(write_data, pkt->getPtr<uint8_t>(), pkt->getSize());
180 write_pkt->dataDynamic(write_data);
181
182 // Perform the atomic on the write packet data. The atomic op is not
183 // copied from the original packet, so use the original packet.
184 assert(pkt->isAtomicOp());
185 (*pkt->getAtomicOp())(write_pkt->getPtr<uint8_t>());
186
187 // Write back the new value. The atomic is not considered done until
188 // this packet's response event is triggered.
189 systemHub.dmaWrite(write_pkt->getAddr(), write_pkt->getSize(),
190 dmaRespEvent, write_pkt->getPtr<uint8_t>(), 0, 0, delay);
191
192 // Atomics from the GPU are at most 64-bit and usually 32-bit.
193 // We can take a peek at the data for debugging purposes.
194 [[maybe_unused]] uint64_t req_data = 0x12345678;
195 if (write_pkt->getSize() == 8) {
196 req_data = write_pkt->getLE<uint64_t>();
197 } else if (pkt->getSize() == 4) {
198 req_data = write_pkt->getLE<uint32_t>();
199 }
200
201 DPRINTF(AMDGPUSystemHub, "SystemHub atomic %#lx writing %lx size %d\n",
202 write_pkt->getAddr(), req_data, write_pkt->getSize());
203}
204
207{
208 AddrRangeList ranges;
209 return ranges;
210}
211
212} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
AtomicResponseEvent(AMDGPUSystemHub &_hub, Event *_callback, PacketPtr _pkt)
ResponseEvent(AMDGPUSystemHub &_hub, Event *_callback, PacketPtr _pkt)
This class handles reads from the system/host memory space from the shader.
Definition system_hub.hh:51
void sendRequest(PacketPtr pkt, Event *callback)
Definition system_hub.cc:42
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
void sendDeferredRequest(DeferredReq &deferredReq)
Definition system_hub.cc:63
void dmaResponse(PacketPtr pkt)
void sendNextRequest(Addr addr, const PacketPtr donePkt)
std::unordered_map< Addr, DeferredReqList > outstandingReqs
Definition system_hub.hh:68
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
void dmaRead(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
static const FlagsType AutoDelete
Definition eventq.hh:110
void setFlags(Flags _flags)
Definition eventq.hh:331
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
bool isRead() const
Definition packet.hh:593
Addr getAddr() const
Definition packet.hh:807
bool isAtomicOp() const
Definition packet.hh:846
static PacketPtr createWrite(const RequestPtr &req)
Definition packet.hh:1044
T * getPtr()
get a pointer to the data ptr.
Definition packet.hh:1225
bool isWrite() const
Definition packet.hh:594
unsigned getSize() const
Definition packet.hh:817
void dataDynamic(T *p)
Set the data pointer to a value that should have delete [] called on it.
Definition packet.hh:1213
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
STL pair class.
Definition stl.hh:58
Port Object Declaration.
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
std::shared_ptr< Request > RequestPtr
Definition request.hh:94
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
uint64_t Tick
Tick count type.
Definition types.hh:58

Generated on Tue Jun 18 2024 16:24:02 for gem5 by doxygen 1.11.0