gem5 [DEVELOP-FOR-25.1]
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#include "params/SMMUv3DeviceInterface.hh"
45
46namespace gem5
47{
48
50 const SMMUv3DeviceInterfaceParams &p) :
52 smmu(nullptr),
53 microTLB(new SMMUTLB(p.utlb_entries,
54 p.utlb_assoc,
55 p.utlb_policy,
56 this, "utlb")),
57 mainTLB(new SMMUTLB(p.tlb_entries,
58 p.tlb_assoc,
59 p.tlb_policy,
60 this, "maintlb")),
61 microTLBEnable(p.utlb_enable),
62 mainTLBEnable(p.tlb_enable),
64 microTLBSem(p.utlb_slots),
65 mainTLBSem(p.tlb_slots),
66 microTLBLat(p.utlb_lat),
67 mainTLBLat(p.tlb_lat),
68 devicePort(new SMMUDevicePort(csprintf("%s.device_port",
69 name()), *this)),
70 atsDevicePort(name() + ".atsDevicePort", *this),
71 atsMemPort(name() + ".atsMemPort", *this),
72 portWidth(p.port_width),
73 wrBufSlotsRemaining(p.wrbuf_slots),
74 xlateSlotsRemaining(p.xlate_slots),
76 prefetchEnable(p.prefetch_enable),
78 p.prefetch_reserve_last_way),
79 deviceNeedsRetry(false),
83{}
84
85void
87{
88 if (devicePort->isConnected()) {
89 inform("Device port is connected to %s\n", devicePort->getPeer());
90
91 devicePort->sendRangeChange();
92 } else {
93 fatal("Device port is not connected.\n");
94 }
95}
96
97Port&
99{
100 if (name == "ats_mem_side_port") {
101 return atsMemPort;
102 } else if (name == "device_port") {
103 return *devicePort;
104 } else if (name == "ats_dev_side_port") {
105 return atsDevicePort;
106 } else {
107 return ClockedObject::getPort(name, id);
108 }
109}
110
111void
113{
114 devicePort->schedTimingResp(pkt, nextCycle());
115}
116
117void
127
128Tick
130{
131 DPRINTF(SMMUv3, "[a] req from %s addr=%#x size=%#x\n",
132 devicePort->getPeer(), pkt->getAddr(), pkt->getSize());
133
134 std::string proc_name = csprintf("%s.port", name());
135 SMMUTranslationProcess proc(proc_name, *smmu, *this);
137
138 SMMUAction a = smmu->runProcessAtomic(&proc, pkt);
139 assert(a.type == ACTION_SEND_RESP);
140
141 return a.delay;
142}
143
144bool
146{
147 DPRINTF(SMMUv3, "[t] req from %s addr=%#x size=%#x\n",
148 devicePort->getPeer(), pkt->getAddr(), pkt->getSize());
149
150 // @todo: We need to pay for this and not just zero it out
151 pkt->headerDelay = pkt->payloadDelay = 0;
152
153 unsigned nbeats =
154 (pkt->getSize() + (portWidth-1)) / portWidth;
155
156 if (xlateSlotsRemaining==0 ||
157 (pkt->isWrite() && wrBufSlotsRemaining < nbeats))
158 {
159 deviceNeedsRetry = true;
160 return false;
161 }
162
163 if (pkt->isWrite())
164 wrBufSlotsRemaining -= nbeats;
165
166 std::string proc_name = csprintf("%s.port", name());
168 new SMMUTranslationProcess(proc_name, *smmu, *this);
170
171 smmu->runProcessTiming(proc, pkt);
172
173 return true;
174}
175
176Tick
178{
179 DPRINTF(SMMUv3, "[a] ATS responder req addr=%#x size=%#x\n",
180 pkt->getAddr(), pkt->getSize());
181
182 std::string proc_name = csprintf("%s.atsport", name());
183 const bool ats_request = true;
185 proc_name, *smmu, *this);
186 proc.beginTransaction(SMMUTranslRequest::fromPacket(pkt, ats_request));
187
188 SMMUAction a = smmu->runProcessAtomic(&proc, pkt);
189 assert(a.type == ACTION_SEND_RESP_ATS);
190
191 return a.delay;
192}
193
194bool
196{
197 DPRINTF(SMMUv3, "[t] ATS responder req addr=%#x size=%#x\n",
198 pkt->getAddr(), pkt->getSize());
199
200 // @todo: We need to pay for this and not just zero it out
201 pkt->headerDelay = pkt->payloadDelay = 0;
202
203 if (xlateSlotsRemaining == 0) {
204 deviceNeedsRetry = true;
205 return false;
206 }
207
208 std::string proc_name = csprintf("%s.atsport", name());
209 const bool ats_request = true;
211 new SMMUTranslationProcess(proc_name, *smmu, *this);
212 proc->beginTransaction(SMMUTranslRequest::fromPacket(pkt, ats_request));
213
214 smmu->runProcessTiming(proc, pkt);
215
216 return true;
217}
218
219bool
221{
222 DPRINTF(SMMUv3, "[t] ATS requestor resp addr=%#x size=%#x\n",
223 pkt->getAddr(), pkt->getSize());
224
225 // @todo: We need to pay for this and not just zero it out
226 pkt->headerDelay = pkt->payloadDelay = 0;
227
228 SMMUProcess *proc =
230
231 smmu->runProcessTiming(proc, pkt);
232
233 return true;
234}
235
236void
238{
239 devicePort->sendRetryReq();
240}
241
242void
244{
245 DPRINTF(SMMUv3, "ATS retry\n");
246 atsDevicePort.sendRetryReq();
247}
248
249void
251{
252 if (deviceNeedsRetry && !sendDeviceRetryEvent.scheduled()) {
253 DPRINTF(SMMUv3, "sched responder retry\n");
254 deviceNeedsRetry = false;
256 }
257}
258
261{
262 // Wait until all SMMU translations are completed
263 if (xlateSlotsRemaining < params().xlate_slots) {
265 }
266 return DrainState::Drained;
267}
268
269} // 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:76
@ Draining
Draining buffers pending serialization/handover.
Definition drain.hh:78
@ Drained
Buffers drained, ready for serialization/handover.
Definition drain.hh:79
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 Oct 27 2025 04:13:01 for gem5 by doxygen 1.14.0