gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
smmu_v3_deviceifc.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 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 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
39
40#include "base/trace.hh"
41#include "debug/SMMUv3.hh"
42#include "dev/arm/smmu_v3.hh"
44
45namespace gem5
46{
47
49 const SMMUv3DeviceInterfaceParams &p) :
51 smmu(nullptr),
52 microTLB(new SMMUTLB(p.utlb_entries,
53 p.utlb_assoc,
54 p.utlb_policy,
55 this, "utlb")),
56 mainTLB(new SMMUTLB(p.tlb_entries,
57 p.tlb_assoc,
58 p.tlb_policy,
59 this, "maintlb")),
60 microTLBEnable(p.utlb_enable),
61 mainTLBEnable(p.tlb_enable),
63 microTLBSem(p.utlb_slots),
64 mainTLBSem(p.tlb_slots),
65 microTLBLat(p.utlb_lat),
66 mainTLBLat(p.tlb_lat),
67 devicePort(new SMMUDevicePort(csprintf("%s.device_port",
68 name()), *this)),
69 atsDevicePort(name() + ".atsDevicePort", *this),
70 atsMemPort(name() + ".atsMemPort", *this),
71 portWidth(p.port_width),
72 wrBufSlotsRemaining(p.wrbuf_slots),
73 xlateSlotsRemaining(p.xlate_slots),
75 prefetchEnable(p.prefetch_enable),
77 p.prefetch_reserve_last_way),
78 deviceNeedsRetry(false),
82{}
83
84void
86{
87 if (devicePort->isConnected()) {
88 inform("Device port is connected to %s\n", devicePort->getPeer());
89
90 devicePort->sendRangeChange();
91 } else {
92 fatal("Device port is not connected.\n");
93 }
94}
95
96Port&
98{
99 if (name == "ats_mem_side_port") {
100 return atsMemPort;
101 } else if (name == "device_port") {
102 return *devicePort;
103 } else if (name == "ats_dev_side_port") {
104 return atsDevicePort;
105 } else {
106 return ClockedObject::getPort(name, id);
107 }
108}
109
110void
112{
113 devicePort->schedTimingResp(pkt, nextCycle());
114}
115
116void
126
127Tick
129{
130 DPRINTF(SMMUv3, "[a] req from %s addr=%#x size=%#x\n",
131 devicePort->getPeer(), pkt->getAddr(), pkt->getSize());
132
133 std::string proc_name = csprintf("%s.port", name());
134 SMMUTranslationProcess proc(proc_name, *smmu, *this);
136
137 SMMUAction a = smmu->runProcessAtomic(&proc, pkt);
138 assert(a.type == ACTION_SEND_RESP);
139
140 return a.delay;
141}
142
143bool
145{
146 DPRINTF(SMMUv3, "[t] req from %s addr=%#x size=%#x\n",
147 devicePort->getPeer(), pkt->getAddr(), pkt->getSize());
148
149 // @todo: We need to pay for this and not just zero it out
150 pkt->headerDelay = pkt->payloadDelay = 0;
151
152 unsigned nbeats =
153 (pkt->getSize() + (portWidth-1)) / portWidth;
154
155 if (xlateSlotsRemaining==0 ||
156 (pkt->isWrite() && wrBufSlotsRemaining < nbeats))
157 {
158 deviceNeedsRetry = true;
159 return false;
160 }
161
162 if (pkt->isWrite())
163 wrBufSlotsRemaining -= nbeats;
164
165 std::string proc_name = csprintf("%s.port", name());
167 new SMMUTranslationProcess(proc_name, *smmu, *this);
169
170 smmu->runProcessTiming(proc, pkt);
171
172 return true;
173}
174
175Tick
177{
178 DPRINTF(SMMUv3, "[a] ATS responder req addr=%#x size=%#x\n",
179 pkt->getAddr(), pkt->getSize());
180
181 std::string proc_name = csprintf("%s.atsport", name());
182 const bool ats_request = true;
184 proc_name, *smmu, *this);
185 proc.beginTransaction(SMMUTranslRequest::fromPacket(pkt, ats_request));
186
187 SMMUAction a = smmu->runProcessAtomic(&proc, pkt);
188 assert(a.type == ACTION_SEND_RESP_ATS);
189
190 return a.delay;
191}
192
193bool
195{
196 DPRINTF(SMMUv3, "[t] ATS responder req addr=%#x size=%#x\n",
197 pkt->getAddr(), pkt->getSize());
198
199 // @todo: We need to pay for this and not just zero it out
200 pkt->headerDelay = pkt->payloadDelay = 0;
201
202 if (xlateSlotsRemaining == 0) {
203 deviceNeedsRetry = true;
204 return false;
205 }
206
207 std::string proc_name = csprintf("%s.atsport", name());
208 const bool ats_request = true;
210 new SMMUTranslationProcess(proc_name, *smmu, *this);
211 proc->beginTransaction(SMMUTranslRequest::fromPacket(pkt, ats_request));
212
213 smmu->runProcessTiming(proc, pkt);
214
215 return true;
216}
217
218bool
220{
221 DPRINTF(SMMUv3, "[t] ATS requestor resp addr=%#x size=%#x\n",
222 pkt->getAddr(), pkt->getSize());
223
224 // @todo: We need to pay for this and not just zero it out
225 pkt->headerDelay = pkt->payloadDelay = 0;
226
227 SMMUProcess *proc =
229
230 smmu->runProcessTiming(proc, pkt);
231
232 return true;
233}
234
235void
237{
238 devicePort->sendRetryReq();
239}
240
241void
243{
244 DPRINTF(SMMUv3, "ATS retry\n");
245 atsDevicePort.sendRetryReq();
246}
247
248void
250{
251 if (deviceNeedsRetry && !sendDeviceRetryEvent.scheduled()) {
252 DPRINTF(SMMUv3, "sched responder retry\n");
253 deviceNeedsRetry = false;
255 }
256}
257
260{
261 // Wait until all SMMU translations are completed
262 if (xlateSlotsRemaining < params().xlate_slots) {
264 }
265 return DrainState::Drained;
266}
267
268} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
ClockedObject(const ClockedObjectParams &p)
Tick nextCycle() const
Based on the clock of the object, determine the start tick of the first cycle that is at least one cy...
virtual std::string name() const
Definition named.hh:60
Addr getAddr() const
Definition packet.hh:807
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Definition packet.hh:449
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition packet.hh:431
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
Definition packet.cc:342
bool isWrite() const
Definition packet.hh:594
unsigned getSize() const
Definition packet.hh:817
Ports are used to interface objects to each other.
Definition port.hh:62
void beginTransaction(const SMMUTranslRequest &req)
void schedAtsTimingResp(PacketPtr pkt)
Port & getPort(const std::string &name, PortID id) override
Get a port with a given name and index.
SMMUDeviceRetryEvent sendDeviceRetryEvent
Tick atsRecvAtomic(PacketPtr pkt)
void schedTimingResp(PacketPtr pkt)
SMMUv3DeviceInterface(const Params &p)
MemberEventWrapper<&SMMUv3DeviceInterface::atsSendDeviceRetry > atsSendDeviceRetryEvent
bool atsRecvTimingResp(PacketPtr pkt)
bool atsRecvTimingReq(PacketPtr pkt)
DrainState drain() override
Provide a default implementation of the drain interface for objects that don't need draining.
bool recvTimingReq(PacketPtr pkt)
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
void schedule(Event &event, Tick when)
Definition eventq.hh:1012
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:232
const Params & params() const
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
#define inform(...)
Definition logging.hh:289
Bitfield< 8 > a
Definition misc_types.hh:66
Bitfield< 0 > p
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
T safe_cast(U &&ref_or_ptr)
Definition cast.hh:74
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
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
@ ACTION_SEND_RESP
@ ACTION_SEND_RESP_ATS
This is an implementation of the SMMUv3 architecture.
static SMMUTranslRequest fromPacket(PacketPtr pkt, bool ats=false)

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