| /* | |
| * Copyright (c) 2010, 2012-2013, 2016-2018 ARM Limited | |
| * All rights reserved | |
| * | |
| * The license below extends only to copyright in the software and shall | |
| * not be construed as granting a license to any other intellectual | |
| * property including but not limited to intellectual property relating | |
| * to a hardware implementation of the functionality of the software | |
| * licensed hereunder. You may use the software subject to the license | |
| * terms below provided that you ensure that this notice is replicated | |
| * unmodified and in its entirety in all distributions of the software, | |
| * modified or unmodified, in source code or in binary form. | |
| * | |
| * Copyright (c) 2003-2005 The Regents of The University of Michigan | |
| * Copyright (c) 2007-2008 The Florida State University | |
| * All rights reserved. | |
| * | |
| * Redistribution and use in source and binary forms, with or without | |
| * modification, are permitted provided that the following conditions are | |
| * met: redistributions of source code must retain the above copyright | |
| * notice, this list of conditions and the following disclaimer; | |
| * redistributions in binary form must reproduce the above copyright | |
| * notice, this list of conditions and the following disclaimer in the | |
| * documentation and/or other materials provided with the distribution; | |
| * neither the name of the copyright holders nor the names of its | |
| * contributors may be used to endorse or promote products derived from | |
| * this software without specific prior written permission. | |
| * | |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| * | |
| * Authors: Korey Sewell | |
| * Stephen Hines | |
| */ | |
| #ifndef __ARCH_ARM_UTILITY_HH__ | |
| #define __ARCH_ARM_UTILITY_HH__ | |
| #include "arch/arm/isa_traits.hh" | |
| #include "arch/arm/miscregs.hh" | |
| #include "arch/arm/types.hh" | |
| #include "base/logging.hh" | |
| #include "base/trace.hh" | |
| #include "base/types.hh" | |
| #include "cpu/static_inst.hh" | |
| #include "cpu/thread_context.hh" | |
| class ArmSystem; | |
| namespace ArmISA { | |
| inline PCState | |
| buildRetPC(const PCState &curPC, const PCState &callPC) | |
| { | |
| PCState retPC = callPC; | |
| retPC.uEnd(); | |
| return retPC; | |
| } | |
| inline bool | |
| testPredicate(uint32_t nz, uint32_t c, uint32_t v, ConditionCode code) | |
| { | |
| bool n = (nz & 0x2); | |
| bool z = (nz & 0x1); | |
| switch (code) | |
| { | |
| case COND_EQ: return z; | |
| case COND_NE: return !z; | |
| case COND_CS: return c; | |
| case COND_CC: return !c; | |
| case COND_MI: return n; | |
| case COND_PL: return !n; | |
| case COND_VS: return v; | |
| case COND_VC: return !v; | |
| case COND_HI: return (c && !z); | |
| case COND_LS: return !(c && !z); | |
| case COND_GE: return !(n ^ v); | |
| case COND_LT: return (n ^ v); | |
| case COND_GT: return !(n ^ v || z); | |
| case COND_LE: return (n ^ v || z); | |
| case COND_AL: return true; | |
| case COND_UC: return true; | |
| default: | |
| panic("Unhandled predicate condition: %d\n", code); | |
| } | |
| } | |
| /** | |
| * Function to insure ISA semantics about 0 registers. | |
| * @param tc The thread context. | |
| */ | |
| template <class TC> | |
| void zeroRegisters(TC *tc); | |
| inline void startupCPU(ThreadContext *tc, int cpuId) | |
| { | |
| tc->activate(); | |
| } | |
| void copyRegs(ThreadContext *src, ThreadContext *dest); | |
| static inline void | |
| copyMiscRegs(ThreadContext *src, ThreadContext *dest) | |
| { | |
| panic("Copy Misc. Regs Not Implemented Yet\n"); | |
| } | |
| void initCPU(ThreadContext *tc, int cpuId); | |
| static inline bool | |
| inUserMode(CPSR cpsr) | |
| { | |
| return cpsr.mode == MODE_USER || cpsr.mode == MODE_EL0T; | |
| } | |
| static inline bool | |
| inUserMode(ThreadContext *tc) | |
| { | |
| return inUserMode(tc->readMiscRegNoEffect(MISCREG_CPSR)); | |
| } | |
| static inline bool | |
| inPrivilegedMode(CPSR cpsr) | |
| { | |
| return !inUserMode(cpsr); | |
| } | |
| static inline bool | |
| inPrivilegedMode(ThreadContext *tc) | |
| { | |
| return !inUserMode(tc); | |
| } | |
| bool inAArch64(ThreadContext *tc); | |
| static inline OperatingMode | |
| currOpMode(ThreadContext *tc) | |
| { | |
| CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); | |
| return (OperatingMode) (uint8_t) cpsr.mode; | |
| } | |
| static inline ExceptionLevel | |
| currEL(ThreadContext *tc) | |
| { | |
| CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); | |
| return (ExceptionLevel) (uint8_t) cpsr.el; | |
| } | |
| /** | |
| * This function checks whether selected EL provided as an argument | |
| * is using the AArch32 ISA. This information might be unavailable | |
| * at the current EL status: it hence returns a pair of boolean values: | |
| * a first boolean, true if information is available (known), | |
| * and a second one, true if EL is using AArch32, false for AArch64. | |
| * | |
| * @param tc The thread context. | |
| * @param el The target exception level. | |
| * @retval known is FALSE for EL0 if the current Exception level | |
| * is not EL0 and EL1 is using AArch64, since it cannot | |
| * determine the state of EL0; TRUE otherwise. | |
| * @retval aarch32 is TRUE if the specified Exception level is using AArch32; | |
| * FALSE otherwise. | |
| */ | |
| std::pair<bool, bool> | |
| ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el); | |
| bool ELIs32(ThreadContext *tc, ExceptionLevel el); | |
| bool ELIs64(ThreadContext *tc, ExceptionLevel el); | |
| bool isBigEndian64(ThreadContext *tc); | |
| /** | |
| * badMode is checking if the execution mode provided as an argument is | |
| * valid and implemented for AArch32 | |
| * | |
| * @param tc ThreadContext | |
| * @param mode OperatingMode to check | |
| * @return false if mode is valid and implemented, true otherwise | |
| */ | |
| bool badMode32(ThreadContext *tc, OperatingMode mode); | |
| /** | |
| * badMode is checking if the execution mode provided as an argument is | |
| * valid and implemented. | |
| * | |
| * @param tc ThreadContext | |
| * @param mode OperatingMode to check | |
| * @return false if mode is valid and implemented, true otherwise | |
| */ | |
| bool badMode(ThreadContext *tc, OperatingMode mode); | |
| static inline uint8_t | |
| itState(CPSR psr) | |
| { | |
| ITSTATE it = 0; | |
| it.top6 = psr.it2; | |
| it.bottom2 = psr.it1; | |
| return (uint8_t)it; | |
| } | |
| /** | |
| * Removes the tag from tagged addresses if that mode is enabled. | |
| * @param addr The address to be purified. | |
| * @param tc The thread context. | |
| * @param el The controlled exception level. | |
| * @return The purified address. | |
| */ | |
| Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, | |
| TTBCR tcr); | |
| Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el); | |
| static inline bool | |
| inSecureState(SCR scr, CPSR cpsr) | |
| { | |
| switch ((OperatingMode) (uint8_t) cpsr.mode) { | |
| case MODE_MON: | |
| case MODE_EL3T: | |
| case MODE_EL3H: | |
| return true; | |
| case MODE_HYP: | |
| case MODE_EL2T: | |
| case MODE_EL2H: | |
| return false; | |
| default: | |
| return !scr.ns; | |
| } | |
| } | |
| bool inSecureState(ThreadContext *tc); | |
| /** | |
| * Return TRUE if an Exception level below EL3 is in Secure state. | |
| * Differs from inSecureState in that it ignores the current EL | |
| * or Mode in considering security state. | |
| */ | |
| inline bool isSecureBelowEL3(ThreadContext *tc); | |
| bool longDescFormatInUse(ThreadContext *tc); | |
| uint32_t getMPIDR(ArmSystem *arm_sys, ThreadContext *tc); | |
| static inline uint32_t | |
| mcrMrcIssBuild(bool isRead, uint32_t crm, IntRegIndex rt, uint32_t crn, | |
| uint32_t opc1, uint32_t opc2) | |
| { | |
| return (isRead << 0) | | |
| (crm << 1) | | |
| (rt << 5) | | |
| (crn << 10) | | |
| (opc1 << 14) | | |
| (opc2 << 17); | |
| } | |
| static inline void | |
| mcrMrcIssExtract(uint32_t iss, bool &isRead, uint32_t &crm, IntRegIndex &rt, | |
| uint32_t &crn, uint32_t &opc1, uint32_t &opc2) | |
| { | |
| isRead = (iss >> 0) & 0x1; | |
| crm = (iss >> 1) & 0xF; | |
| rt = (IntRegIndex) ((iss >> 5) & 0xF); | |
| crn = (iss >> 10) & 0xF; | |
| opc1 = (iss >> 14) & 0x7; | |
| opc2 = (iss >> 17) & 0x7; | |
| } | |
| static inline uint32_t | |
| mcrrMrrcIssBuild(bool isRead, uint32_t crm, IntRegIndex rt, IntRegIndex rt2, | |
| uint32_t opc1) | |
| { | |
| return (isRead << 0) | | |
| (crm << 1) | | |
| (rt << 5) | | |
| (rt2 << 10) | | |
| (opc1 << 16); | |
| } | |
| static inline uint32_t | |
| msrMrs64IssBuild(bool isRead, uint32_t op0, uint32_t op1, uint32_t crn, | |
| uint32_t crm, uint32_t op2, IntRegIndex rt) | |
| { | |
| return isRead | | |
| (crm << 1) | | |
| (rt << 5) | | |
| (crn << 10) | | |
| (op1 << 14) | | |
| (op2 << 17) | | |
| (op0 << 20); | |
| } | |
| bool | |
| mcrMrc15TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr, | |
| HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss); | |
| bool | |
| mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr, | |
| HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss); | |
| bool | |
| mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr, | |
| HCR hcr, uint32_t iss); | |
| bool msrMrs64TrapToSup(const MiscRegIndex miscReg, ExceptionLevel el, | |
| CPACR cpacr); | |
| bool msrMrs64TrapToHyp(const MiscRegIndex miscReg, ExceptionLevel el, | |
| bool isRead, CPTR cptr, HCR hcr, bool * isVfpNeon); | |
| bool msrMrs64TrapToMon(const MiscRegIndex miscReg, CPTR cptr, | |
| ExceptionLevel el, bool * isVfpNeon); | |
| bool SPAlignmentCheckEnabled(ThreadContext* tc); | |
| uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp); | |
| void skipFunction(ThreadContext *tc); | |
| inline void | |
| advancePC(PCState &pc, const StaticInstPtr &inst) | |
| { | |
| inst->advancePC(pc); | |
| } | |
| Addr truncPage(Addr addr); | |
| Addr roundPage(Addr addr); | |
| inline uint64_t | |
| getExecutingAsid(ThreadContext *tc) | |
| { | |
| return tc->readMiscReg(MISCREG_CONTEXTIDR); | |
| } | |
| // Decodes the register index to access based on the fields used in a MSR | |
| // or MRS instruction | |
| bool | |
| decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int ®Idx, | |
| CPSR cpsr, SCR scr, NSACR nsacr, | |
| bool checkSecurity = true); | |
| // This wrapper function is used to turn the register index into a source | |
| // parameter for the instruction. See Operands.isa | |
| static inline int | |
| decodeMrsMsrBankedIntRegIndex(uint8_t sysM, bool r) | |
| { | |
| int regIdx; | |
| bool isIntReg; | |
| bool validReg; | |
| validReg = decodeMrsMsrBankedReg(sysM, r, isIntReg, regIdx, 0, 0, 0, false); | |
| return (validReg && isIntReg) ? regIdx : INTREG_DUMMY; | |
| } | |
| /** | |
| * Returns the n. of PA bits corresponding to the specified encoding. | |
| */ | |
| int decodePhysAddrRange64(uint8_t pa_enc); | |
| /** | |
| * Returns the encoding corresponding to the specified n. of PA bits. | |
| */ | |
| uint8_t encodePhysAddrRange64(int pa_size); | |
| inline ByteOrder byteOrder(ThreadContext *tc) | |
| { | |
| return isBigEndian64(tc) ? BigEndianByteOrder : LittleEndianByteOrder; | |
| }; | |
| } | |
| #endif |