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 bool ELIs32(ThreadContext *tc, ExceptionLevel el);
177 bool ELIs64(ThreadContext *tc, ExceptionLevel el);
180 * Returns true if the current exception level `el` is executing a Host OS or
181 * an application of a Host OS (Armv8.1 Virtualization Host Extensions).
183 bool ELIsInHost(ThreadContext *tc, ExceptionLevel el);
185 bool isBigEndian64(const ThreadContext *tc);
188 * badMode is checking if the execution mode provided as an argument is
189 * valid and implemented for AArch32
191 * @param tc ThreadContext
192 * @param mode OperatingMode to check
193 * @return false if mode is valid and implemented, true otherwise
195 bool badMode32(ThreadContext *tc, OperatingMode mode);
198 * badMode is checking if the execution mode provided as an argument is
199 * valid and implemented.
201 * @param tc ThreadContext
202 * @param mode OperatingMode to check
203 * @return false if mode is valid and implemented, true otherwise
205 bool badMode(ThreadContext *tc, OperatingMode mode);
207 static inline uint8_t
212 it.bottom2 = psr.it1;
217 ExceptionLevel s1TranslationRegime(ThreadContext* tc, ExceptionLevel el);
220 * Removes the tag from tagged addresses if that mode is enabled.
221 * @param addr The address to be purified.
222 * @param tc The thread context.
223 * @param el The controlled exception level.
224 * @return The purified address.
226 Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el,
227 TCR tcr, bool isInstr);
228 Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el,
230 int computeAddrTop(ThreadContext *tc, bool selbit, bool isInstr,
231 TTBCR tcr, ExceptionLevel el);
234 inSecureState(SCR scr, CPSR cpsr)
236 switch ((OperatingMode) (uint8_t) cpsr.mode) {
250 bool inSecureState(ThreadContext *tc);
252 bool longDescFormatInUse(ThreadContext *tc);
254 /** This helper function is either returing the value of
255 * MPIDR_EL1 (by calling getMPIDR), or it is issuing a read
256 * to VMPIDR_EL2 (as it happens in virtualized systems) */
257 RegVal readMPIDR(ArmSystem *arm_sys, ThreadContext *tc);
259 /** This helper function is returing the value of MPIDR_EL1 */
260 RegVal getMPIDR(ArmSystem *arm_sys, ThreadContext *tc);
262 static inline uint32_t
263 mcrMrcIssBuild(bool isRead, uint32_t crm, IntRegIndex rt, uint32_t crn,
264 uint32_t opc1, uint32_t opc2)
266 return (isRead << 0) |
275 mcrMrcIssExtract(uint32_t iss, bool &isRead, uint32_t &crm, IntRegIndex &rt,
276 uint32_t &crn, uint32_t &opc1, uint32_t &opc2)
278 isRead = (iss >> 0) & 0x1;
279 crm = (iss >> 1) & 0xF;
280 rt = (IntRegIndex) ((iss >> 5) & 0xF);
281 crn = (iss >> 10) & 0xF;
282 opc1 = (iss >> 14) & 0x7;
283 opc2 = (iss >> 17) & 0x7;
286 static inline uint32_t
287 mcrrMrrcIssBuild(bool isRead, uint32_t crm, IntRegIndex rt, IntRegIndex rt2,
290 return (isRead << 0) |
297 static inline uint32_t
298 msrMrs64IssBuild(bool isRead, uint32_t op0, uint32_t op1, uint32_t crn,
299 uint32_t crm, uint32_t op2, IntRegIndex rt)
311 mcrMrc15Trap(const MiscRegIndex miscReg, ExtMachInst machInst,
312 ThreadContext *tc, uint32_t imm);
314 mcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss,
315 ExceptionClass *ec = nullptr);
318 mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr,
319 HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss);
322 mcrrMrrc15Trap(const MiscRegIndex miscReg, ExtMachInst machInst,
323 ThreadContext *tc, uint32_t imm);
325 mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc,
326 uint32_t iss, ExceptionClass *ec = nullptr);
329 AArch64AArch32SystemAccessTrap(const MiscRegIndex miscReg,
330 ExtMachInst machInst, ThreadContext *tc,
331 uint32_t imm, ExceptionClass ec);
333 isAArch64AArch32SystemAccessTrapEL1(const MiscRegIndex miscReg,
336 isAArch64AArch32SystemAccessTrapEL2(const MiscRegIndex miscReg,
339 isGenericTimerHypTrap(const MiscRegIndex miscReg, ThreadContext *tc,
341 bool condGenericTimerPhysHypTrap(const MiscRegIndex miscReg,
344 isGenericTimerCommonEL0HypTrap(const MiscRegIndex miscReg, ThreadContext *tc,
347 isGenericTimerPhysHypTrap(const MiscRegIndex miscReg, ThreadContext *tc,
350 condGenericTimerPhysHypTrap(const MiscRegIndex miscReg, ThreadContext *tc);
352 isGenericTimerSystemAccessTrapEL1(const MiscRegIndex miscReg,
355 condGenericTimerSystemAccessTrapEL1(const MiscRegIndex miscReg,
358 isGenericTimerSystemAccessTrapEL2(const MiscRegIndex miscReg,
361 isGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex miscReg,
364 isGenericTimerPhysEL0SystemAccessTrapEL2(const MiscRegIndex miscReg,
367 isGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex miscReg,
370 isGenericTimerVirtSystemAccessTrapEL2(const MiscRegIndex miscReg,
373 condGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex miscReg,
376 condGenericTimerCommonEL1SystemAccessTrapEL2(const MiscRegIndex miscReg,
379 condGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex miscReg,
382 isGenericTimerSystemAccessTrapEL3(const MiscRegIndex miscReg,
385 bool SPAlignmentCheckEnabled(ThreadContext* tc);
387 uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp);
389 void skipFunction(ThreadContext *tc);
392 advancePC(PCState &pc, const StaticInstPtr &inst)
397 Addr truncPage(Addr addr);
398 Addr roundPage(Addr addr);
401 getExecutingAsid(ThreadContext *tc)
403 return tc->readMiscReg(MISCREG_CONTEXTIDR);
406 // Decodes the register index to access based on the fields used in a MSR
407 // or MRS instruction
409 decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int ®Idx,
410 CPSR cpsr, SCR scr, NSACR nsacr,
411 bool checkSecurity = true);
413 // This wrapper function is used to turn the register index into a source
414 // parameter for the instruction. See Operands.isa
416 decodeMrsMsrBankedIntRegIndex(uint8_t sysM, bool r)
422 validReg = decodeMrsMsrBankedReg(sysM, r, isIntReg, regIdx, 0, 0, 0, false);
423 return (validReg && isIntReg) ? regIdx : INTREG_DUMMY;
427 * Returns the n. of PA bits corresponding to the specified encoding.
429 int decodePhysAddrRange64(uint8_t pa_enc);
432 * Returns the encoding corresponding to the specified n. of PA bits.
434 uint8_t encodePhysAddrRange64(int pa_size);
436 inline ByteOrder byteOrder(const ThreadContext *tc)
438 return isBigEndian64(tc) ? BigEndianByteOrder : LittleEndianByteOrder;