gem5 v24.0.0.0
Loading...
Searching...
No Matches
mpam.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 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
38#include <optional>
39
40#include "arch/arm/mpam.hh"
41
42#include "arch/arm/regs/misc.hh"
45#include "arch/arm/system.hh"
46#include "arch/arm/types.hh"
47#include "arch/arm/utility.hh"
48#include "cpu/base.hh"
49#include "cpu/thread_context.hh"
50#include "debug/MPAM.hh"
51
53{
54
55std::unique_ptr<ExtensionBase>
57{
58 return std::make_unique<PartitionFieldExtension>(*this);
59}
60
61uint64_t
66
67uint64_t
72
73bool
75{
76 return this->_ns;
77}
78
79void
84
85void
90
91void
93{
94 this->_ns = ns;
95}
96
97
98namespace
99{
100
101using namespace misc_regs;
102
103static PartID
104getPARTID(ThreadContext *tc, ExceptionLevel el, bool ind)
105{
107 return ind ? reg.partidI : reg.partidD;
108}
109
110static PMG
111getPMG(ThreadContext *tc, ExceptionLevel el, bool ind)
112{
114 return ind ? reg.pmgI : reg.pmgD;
115}
116
117static bool
118useVirtualPartitions(ThreadContext *tc, ExceptionLevel el, MPAMIDR mpamidr)
119{
120 const MPAMHCR mpamhcr = tc->readMiscReg(MISCREG_MPAMHCR_EL2);
121 return mpamidr.hasHcr && EL2Enabled(tc) &&
122 ((el == EL0 && !ELIsInHost(tc, EL0) && mpamhcr.el0Vpmen) || // EL0 case
123 (el == EL1 && mpamhcr.el1Vpmen)); // EL1 case
124}
125
126static PartID
127mapVpmv(ThreadContext *tc, PartID vpartid)
128{
129 uint8_t reg_index = vpartid / 4;
130 uint8_t reg_field = vpartid % 4;
131
132 // Register field size in bits
133 size_t reg_field_size = sizeof(PartID) * 8;
134
135 // LSB of the register field (Every field is 16bits)
136 uint8_t lsb = reg_field * reg_field_size;
137 uint8_t msb = lsb + reg_field_size - 1;
138
139 const RegVal vpmv = tc->readMiscReg(MISCREG_MPAMVPM0_EL2 + reg_index);
140 return bits(vpmv, msb ,lsb);
141}
142
143static std::optional<PartID>
144virtToPhysPart(ThreadContext *tc, PartID vpartid, MPAMIDR mpamidr)
145{
146 // vpmrMax refers to the register index. Extract vpartid max
147 const uint8_t vpartid_max = (mpamidr.vpmrMax << 2) + 3;
148 const RegVal mpam_vpmv = tc->readMiscReg(MISCREG_MPAMVPMV_EL2);
149
150 if (vpartid > vpartid_max) {
151 vpartid = vpartid % (vpartid_max + 1);
152 }
153
154 PartID phys_partid = 0;
155 if (bits(mpam_vpmv, vpartid)) {
156 // Valid mapping entry for virtual partition vpartid
157 phys_partid = mapVpmv(tc, vpartid);
158 } else if (bits(mpam_vpmv, 0)) {
159 // Default virtual partition valid
160 phys_partid = mapVpmv(tc, 0);
161 } else {
162 // Error
163 return std::nullopt;
164 }
165
166 return phys_partid > mpamidr.partidMax ?
167 std::nullopt : std::make_optional(phys_partid);
168}
169
170static std::optional<PartID>
171genPARTID(ThreadContext *tc, ExceptionLevel el, bool ind)
172{
173 const MPAMIDR mpamidr = tc->readMiscReg(MISCREG_MPAMIDR_EL1);
174 auto partid = getPARTID(tc, el, ind);
175
176 if (partid > mpamidr.partidMax) {
177 return std::nullopt;
178 } else if (useVirtualPartitions(tc, el, mpamidr)) {
179 return virtToPhysPart(tc, partid, mpamidr);
180 } else {
181 return partid;
182 }
183}
184
185static std::optional<PMG>
186genPMG(ThreadContext *tc, ExceptionLevel el, bool ind)
187{
188 const MPAMIDR mpamidr = tc->readMiscReg(MISCREG_MPAMIDR_EL1);
189 PMG pgroup = getPMG(tc, el, ind);
190 return pgroup > mpamidr.pmgMax ? std::nullopt : std::make_optional(pgroup);
191}
192
193static bool
194isEnabled(ThreadContext *tc)
195{
197 return reg.mpamEn;
198}
199
200static std::shared_ptr<PartitionFieldExtension>
201genExtensionDefault()
202{
203 // tag with partID data
204 auto ext = std::make_shared<PartitionFieldExtension>();
205 ext->setPartitionID(DEFAULT_PARTITION_ID);
206 ext->setPartitionMonitoringID(DEFAULT_PARTITION_MONITORING_ID);
207 return ext;
208}
209
210static std::shared_ptr<PartitionFieldExtension>
211genExtension(ThreadContext *tc, bool ind)
212{
213 ExceptionLevel curr_el = currEL(tc);
214 const MPAMHCR mpamhcr = tc->readMiscReg(MISCREG_MPAMHCR_EL2);
215 const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
216
217 bool gstplk = curr_el == EL0 && EL2Enabled(tc) &&
218 mpamhcr.gstappPlk && !hcr.tge;
219 if (gstplk) {
220 curr_el = EL1;
221 }
222
223 // tag with partID data
224 auto ext = std::make_shared<
225 PartitionFieldExtension>();
226
227 auto part_id = genPARTID(tc, curr_el, ind).value_or(
229 auto part_mon_id = genPMG(tc, curr_el, ind).value_or(
231
232 ext->setPartitionID(part_id);
233 ext->setPartitionMonitoringID(part_mon_id);
234 return ext;
235}
236
237} // namespace
238
239void
240tagRequest(ThreadContext *tc, const RequestPtr &req, bool ind)
241{
242 if (!HaveExt(tc, ArmExtension::FEAT_MPAM) || !isEnabled(tc))
243 return;
244
245 const MPAMIDR mpamidr = tc->readMiscReg(MISCREG_MPAMIDR_EL1);
246 const MPAM mpam3 = tc->readMiscReg(MISCREG_MPAM3_EL3);
247 auto ext = mpamidr.hasSdeflt && mpam3.el3.sdeflt && isSecure(tc) ?
248 genExtensionDefault() :
249 genExtension(tc, ind);
250
251 DPRINTFS(MPAM, tc->getCpuPtr(),
252 "MPAM Tagging req %#x => PART_ID: %d, PART_MON_ID: %d\n",
253 req->getPaddr(),
254 ext->getPartitionID(),
255 ext->getPartitionMonitoringID());
256
257 bool mpam_ns = !isSecure(tc);
258 if (!mpam_ns && mpam3.el3.forceNs) {
259 mpam_ns = true;
260 }
261
262 ext->setMpamNS(mpam_ns);
263
264 req->setExtension(ext);
265}
266
267} // namespace gem5::ArmISA::mpam
#define DPRINTFS(x, s,...)
Definition trace.hh:217
bool getMpamNS() const
MPAM_NS getter.
Definition mpam.cc:74
void setPartitionID(uint64_t id)
_partitionID setter
Definition mpam.cc:80
std::unique_ptr< ExtensionBase > clone() const override
Definition mpam.cc:56
uint64_t getPartitionMonitoringID() const
_partitionMonitoringID getter
Definition mpam.cc:68
void setMpamNS(bool ns)
MPAM_NS setter.
Definition mpam.cc:92
uint64_t getPartitionID() const
_partitionID getter
Definition mpam.cc:62
void setPartitionMonitoringID(uint64_t id)
_partitionMonitoringID setter
Definition mpam.cc:86
ArmISA::ExceptionLevel highestEL() const
Returns the highest implemented exception level.
Definition system.hh:191
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
virtual BaseCPU * getCpuPtr()=0
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition bitfield.hh:79
RegAccessor::type readRegister(ThreadContext *tc, ExceptionLevel el)
void tagRequest(ThreadContext *tc, const RequestPtr &req, bool ind)
Tag a memory request with MPAM information.
Definition mpam.cc:240
const uint64_t DEFAULT_PARTITION_MONITORING_ID
Definition mpam.hh:49
uint8_t PMG
Partition Manager data type.
Definition mpam.hh:104
const uint64_t DEFAULT_PARTITION_ID
Definition mpam.hh:48
uint16_t PartID
Partition ID data type.
Definition mpam.hh:102
bool ELIsInHost(ThreadContext *tc, ExceptionLevel el)
Returns true if the current exception level el is executing a Host OS or an application of a Host OS ...
Definition utility.cc:290
ExceptionLevel currEL(const ThreadContext *tc)
Returns the current Exception Level (EL) of the provided ThreadContext.
Definition utility.cc:133
bool isSecure(ThreadContext *tc)
Definition utility.cc:74
Bitfield< 33 > id
Bitfield< 0 > ns
bool EL2Enabled(ThreadContext *tc)
Definition utility.cc:267
@ MISCREG_MPAM3_EL3
Definition misc.hh:1150
@ MISCREG_MPAMHCR_EL2
Definition misc.hh:1152
@ MISCREG_MPAMVPMV_EL2
Definition misc.hh:1153
@ MISCREG_MPAMVPM0_EL2
Definition misc.hh:1154
@ MISCREG_MPAMIDR_EL1
Definition misc.hh:1146
@ MISCREG_HCR_EL2
Definition misc.hh:595
Bitfield< 3, 2 > el
Definition misc_types.hh:73
bool HaveExt(ThreadContext *tc, ArmExtension ext)
Returns true if the provided ThreadContext supports the ArmExtension passed as a second argument.
Definition utility.cc:231
Bitfield< 12 > ext
Bitfield< 5, 3 > reg
Definition types.hh:92
std::shared_ptr< Request > RequestPtr
Definition request.hh:94
uint64_t RegVal
Definition types.hh:173

Generated on Tue Jun 18 2024 16:23:56 for gem5 by doxygen 1.11.0