2 * Copyright (c) 2010, 2012-2013, 2016-2020 ARM Limited
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.
14 * Copyright (c) 2003-2005 The Regents of The University of Michigan
15 * Copyright (c) 2007-2008 The Florida State University
16 * All rights reserved.
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 #ifndef __ARCH_ARM_UTILITY_HH__
43 #define __ARCH_ARM_UTILITY_HH__
45 #include "arch/arm/isa_traits.hh"
46 #include "arch/arm/miscregs.hh"
47 #include "arch/arm/types.hh"
48 #include "base/logging.hh"
49 #include "base/trace.hh"
50 #include "base/types.hh"
51 #include "cpu/static_inst.hh"
52 #include "cpu/thread_context.hh"
59 buildRetPC(const PCState &curPC, const PCState &callPC)
61 PCState retPC = callPC;
67 testPredicate(uint32_t nz, uint32_t c, uint32_t v, ConditionCode code)
74 case COND_EQ: return z;
75 case COND_NE: return !z;
76 case COND_CS: return c;
77 case COND_CC: return !c;
78 case COND_MI: return n;
79 case COND_PL: return !n;
80 case COND_VS: return v;
81 case COND_VC: return !v;
82 case COND_HI: return (c && !z);
83 case COND_LS: return !(c && !z);
84 case COND_GE: return !(n ^ v);
85 case COND_LT: return (n ^ v);
86 case COND_GT: return !(n ^ v || z);
87 case COND_LE: return (n ^ v || z);
88 case COND_AL: return true;
89 case COND_UC: return true;
91 panic("Unhandled predicate condition: %d\n", code);
95 void copyRegs(ThreadContext *src, ThreadContext *dest);
98 copyMiscRegs(ThreadContext *src, ThreadContext *dest)
100 panic("Copy Misc. Regs Not Implemented Yet\n");
103 /** Send an event (SEV) to a specific PE if there isn't
104 * already a pending event */
105 void sendEvent(ThreadContext *tc);
108 inUserMode(CPSR cpsr)
110 return cpsr.mode == MODE_USER || cpsr.mode == MODE_EL0T;
114 inUserMode(ThreadContext *tc)
116 return inUserMode(tc->readMiscRegNoEffect(MISCREG_CPSR));
120 inPrivilegedMode(CPSR cpsr)
122 return !inUserMode(cpsr);
126 inPrivilegedMode(ThreadContext *tc)
128 return !inUserMode(tc);
131 bool inAArch64(ThreadContext *tc);
133 static inline OperatingMode
134 currOpMode(const ThreadContext *tc)
136 CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
137 return (OperatingMode) (uint8_t) cpsr.mode;
140 static inline ExceptionLevel
141 currEL(const ThreadContext *tc)
143 return opModeToEL(currOpMode(tc));
146 inline ExceptionLevel
149 return opModeToEL((OperatingMode) (uint8_t)cpsr.mode);
152 bool HaveVirtHostExt(ThreadContext *tc);
153 bool HaveSecureEL2Ext(ThreadContext *tc);
154 bool IsSecureEL2Enabled(ThreadContext *tc);
155 bool EL2Enabled(ThreadContext *tc);
158 * This function checks whether selected EL provided as an argument
159 * is using the AArch32 ISA. This information might be unavailable
160 * at the current EL status: it hence returns a pair of boolean values:
161 * a first boolean, true if information is available (known),
162 * and a second one, true if EL is using AArch32, false for AArch64.
164 * @param tc The thread context.
165 * @param el The target exception level.
166 * @retval known is FALSE for EL0 if the current Exception level
167 * is not EL0 and EL1 is using AArch64, since it cannot
168 * determine the state of EL0; TRUE otherwise.
169 * @retval aarch32 is TRUE if the specified Exception level is using AArch32;
172 std::pair<bool, bool>
173 ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el);
175 std::pair<bool, bool>
176 ELStateUsingAArch32K(ThreadContext *tc, ExceptionLevel el, bool secure);
179 ELStateUsingAArch32(ThreadContext *tc, ExceptionLevel el, bool secure);
181 bool ELIs32(ThreadContext *tc, ExceptionLevel el);
183 bool ELIs64(ThreadContext *tc, ExceptionLevel el);
186 * Returns true if the current exception level `el` is executing a Host OS or
187 * an application of a Host OS (Armv8.1 Virtualization Host Extensions).
189 bool ELIsInHost(ThreadContext *tc, ExceptionLevel el);
191 ExceptionLevel debugTargetFrom(ThreadContext *tc, bool secure);
193 bool isBigEndian64(const ThreadContext *tc);
197 * badMode is checking if the execution mode provided as an argument is
198 * valid and implemented for AArch32
200 * @param tc ThreadContext
201 * @param mode OperatingMode to check
202 * @return false if mode is valid and implemented, true otherwise
204 bool badMode32(ThreadContext *tc, OperatingMode mode);
207 * badMode is checking if the execution mode provided as an argument is
208 * valid and implemented.
210 * @param tc ThreadContext
211 * @param mode OperatingMode to check
212 * @return false if mode is valid and implemented, true otherwise
214 bool badMode(ThreadContext *tc, OperatingMode mode);
216 static inline uint8_t
221 it.bottom2 = psr.it1;
226 ExceptionLevel s1TranslationRegime(ThreadContext* tc, ExceptionLevel el);
229 * Removes the tag from tagged addresses if that mode is enabled.
230 * @param addr The address to be purified.
231 * @param tc The thread context.
232 * @param el The controlled exception level.
233 * @return The purified address.
235 Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el,
236 TCR tcr, bool isInstr);
237 Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el,
239 int computeAddrTop(ThreadContext *tc, bool selbit, bool isInstr,
240 TCR tcr, ExceptionLevel el);
243 inSecureState(SCR scr, CPSR cpsr)
245 switch ((OperatingMode) (uint8_t) cpsr.mode) {
259 bool inSecureState(ThreadContext *tc);
261 bool isSecureBelowEL3(ThreadContext *tc);
263 bool longDescFormatInUse(ThreadContext *tc);
265 /** This helper function is either returing the value of
266 * MPIDR_EL1 (by calling getMPIDR), or it is issuing a read
267 * to VMPIDR_EL2 (as it happens in virtualized systems) */
268 RegVal readMPIDR(ArmSystem *arm_sys, ThreadContext *tc);
270 /** This helper function is returning the value of MPIDR_EL1 */
271 RegVal getMPIDR(ArmSystem *arm_sys, ThreadContext *tc);
273 /** Retrieves MPIDR_EL1.{Aff2,Aff1,Aff0} affinity numbers */
274 RegVal getAffinity(ArmSystem *arm_sys, ThreadContext *tc);
276 static inline uint32_t
277 mcrMrcIssBuild(bool isRead, uint32_t crm, IntRegIndex rt, uint32_t crn,
278 uint32_t opc1, uint32_t opc2)
280 return (isRead << 0) |
289 mcrMrcIssExtract(uint32_t iss, bool &isRead, uint32_t &crm, IntRegIndex &rt,
290 uint32_t &crn, uint32_t &opc1, uint32_t &opc2)
292 isRead = (iss >> 0) & 0x1;
293 crm = (iss >> 1) & 0xF;
294 rt = (IntRegIndex) ((iss >> 5) & 0xF);
295 crn = (iss >> 10) & 0xF;
296 opc1 = (iss >> 14) & 0x7;
297 opc2 = (iss >> 17) & 0x7;
300 static inline uint32_t
301 mcrrMrrcIssBuild(bool isRead, uint32_t crm, IntRegIndex rt, IntRegIndex rt2,
304 return (isRead << 0) |
311 static inline uint32_t
312 msrMrs64IssBuild(bool isRead, uint32_t op0, uint32_t op1, uint32_t crn,
313 uint32_t crm, uint32_t op2, IntRegIndex rt)
325 mcrMrc15Trap(const MiscRegIndex miscReg, ExtMachInst machInst,
326 ThreadContext *tc, uint32_t imm);
328 mcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss,
329 ExceptionClass *ec = nullptr);
332 mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr,
333 HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss);
336 mcrrMrrc15Trap(const MiscRegIndex miscReg, ExtMachInst machInst,
337 ThreadContext *tc, uint32_t imm);
339 mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc,
340 uint32_t iss, ExceptionClass *ec = nullptr);
343 AArch64AArch32SystemAccessTrap(const MiscRegIndex miscReg,
344 ExtMachInst machInst, ThreadContext *tc,
345 uint32_t imm, ExceptionClass ec);
347 isAArch64AArch32SystemAccessTrapEL1(const MiscRegIndex miscReg,
350 isAArch64AArch32SystemAccessTrapEL2(const MiscRegIndex miscReg,
353 isGenericTimerHypTrap(const MiscRegIndex miscReg, ThreadContext *tc,
355 bool condGenericTimerPhysHypTrap(const MiscRegIndex miscReg,
358 isGenericTimerCommonEL0HypTrap(const MiscRegIndex miscReg, ThreadContext *tc,
361 isGenericTimerPhysHypTrap(const MiscRegIndex miscReg, ThreadContext *tc,
364 condGenericTimerPhysHypTrap(const MiscRegIndex miscReg, ThreadContext *tc);
366 isGenericTimerSystemAccessTrapEL1(const MiscRegIndex miscReg,
369 condGenericTimerSystemAccessTrapEL1(const MiscRegIndex miscReg,
372 isGenericTimerSystemAccessTrapEL2(const MiscRegIndex miscReg,
375 isGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex miscReg,
378 isGenericTimerPhysEL0SystemAccessTrapEL2(const MiscRegIndex miscReg,
381 isGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex miscReg,
384 isGenericTimerVirtSystemAccessTrapEL2(const MiscRegIndex miscReg,
387 condGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex miscReg,
390 condGenericTimerCommonEL1SystemAccessTrapEL2(const MiscRegIndex miscReg,
393 condGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex miscReg,
396 isGenericTimerSystemAccessTrapEL3(const MiscRegIndex miscReg,
399 bool SPAlignmentCheckEnabled(ThreadContext* tc);
401 uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp);
404 advancePC(PCState &pc, const StaticInstPtr &inst)
409 Addr truncPage(Addr addr);
410 Addr roundPage(Addr addr);
413 getExecutingAsid(ThreadContext *tc)
415 return tc->readMiscReg(MISCREG_CONTEXTIDR);
418 // Decodes the register index to access based on the fields used in a MSR
419 // or MRS instruction
421 decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int ®Idx,
422 CPSR cpsr, SCR scr, NSACR nsacr,
423 bool checkSecurity = true);
425 // This wrapper function is used to turn the register index into a source
426 // parameter for the instruction. See Operands.isa
428 decodeMrsMsrBankedIntRegIndex(uint8_t sysM, bool r)
434 validReg = decodeMrsMsrBankedReg(sysM, r, isIntReg, regIdx, 0, 0, 0, false);
435 return (validReg && isIntReg) ? regIdx : INTREG_DUMMY;
439 * Returns the n. of PA bits corresponding to the specified encoding.
441 int decodePhysAddrRange64(uint8_t pa_enc);
444 * Returns the encoding corresponding to the specified n. of PA bits.
446 uint8_t encodePhysAddrRange64(int pa_size);
448 inline ByteOrder byteOrder(const ThreadContext *tc)
450 return isBigEndian64(tc) ? BigEndianByteOrder : LittleEndianByteOrder;
453 bool isUnpriviledgeAccess(ThreadContext * tc);