utility.hh revision 14169
11736SN/A/* 21736SN/A * Copyright (c) 2010, 2012-2013, 2016-2019 ARM Limited 31736SN/A * All rights reserved 41736SN/A * 51736SN/A * The license below extends only to copyright in the software and shall 61736SN/A * not be construed as granting a license to any other intellectual 71736SN/A * property including but not limited to intellectual property relating 81736SN/A * to a hardware implementation of the functionality of the software 91736SN/A * licensed hereunder. You may use the software subject to the license 101736SN/A * terms below provided that you ensure that this notice is replicated 111736SN/A * unmodified and in its entirety in all distributions of the software, 121736SN/A * modified or unmodified, in source code or in binary form. 131736SN/A * 141736SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 151736SN/A * Copyright (c) 2007-2008 The Florida State University 161736SN/A * All rights reserved. 171736SN/A * 181736SN/A * Redistribution and use in source and binary forms, with or without 191736SN/A * modification, are permitted provided that the following conditions are 201736SN/A * met: redistributions of source code must retain the above copyright 211736SN/A * notice, this list of conditions and the following disclaimer; 221736SN/A * redistributions in binary form must reproduce the above copyright 231736SN/A * notice, this list of conditions and the following disclaimer in the 241736SN/A * documentation and/or other materials provided with the distribution; 251736SN/A * neither the name of the copyright holders nor the names of its 262665Ssaidi@eecs.umich.edu * contributors may be used to endorse or promote products derived from 272665Ssaidi@eecs.umich.edu * this software without specific prior written permission. 282665Ssaidi@eecs.umich.edu * 291736SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302889Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 312655Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 322667Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 332763Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 342667Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 352667Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 362667Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 372868Sktlim@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 382655Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 392667Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402667Sstever@eecs.umich.edu * 411530SN/A * Authors: Korey Sewell 421530SN/A * Stephen Hines 431530SN/A */ 441530SN/A 451530SN/A#ifndef __ARCH_ARM_UTILITY_HH__ 461530SN/A#define __ARCH_ARM_UTILITY_HH__ 472969Sktlim@umich.edu 482969Sktlim@umich.edu#include "arch/arm/isa_traits.hh" 492969Sktlim@umich.edu#include "arch/arm/miscregs.hh" 502969Sktlim@umich.edu#include "arch/arm/types.hh" 512969Sktlim@umich.edu#include "base/logging.hh" 522667Sstever@eecs.umich.edu#include "base/trace.hh" 532667Sstever@eecs.umich.edu#include "base/types.hh" 542667Sstever@eecs.umich.edu#include "cpu/static_inst.hh" 551692SN/A#include "cpu/thread_context.hh" 561869SN/A 571869SN/Aclass ArmSystem; 581869SN/A 591869SN/Anamespace ArmISA { 601692SN/A 611869SN/Ainline PCState 621869SN/AbuildRetPC(const PCState &curPC, const PCState &callPC) 631869SN/A{ 641581SN/A PCState retPC = callPC; 651530SN/A retPC.uEnd(); 661530SN/A return retPC; 671530SN/A} 682667Sstever@eecs.umich.edu 691530SN/Ainline bool 701530SN/AtestPredicate(uint32_t nz, uint32_t c, uint32_t v, ConditionCode code) 711530SN/A{ 721530SN/A bool n = (nz & 0x2); 731530SN/A bool z = (nz & 0x1); 742738Sstever@eecs.umich.edu 752738Sstever@eecs.umich.edu switch (code) 762738Sstever@eecs.umich.edu { 772740Sstever@eecs.umich.edu case COND_EQ: return z; 782738Sstever@eecs.umich.edu case COND_NE: return !z; 792889Sbinkertn@umich.edu case COND_CS: return c; 802889Sbinkertn@umich.edu case COND_CC: return !c; 812667Sstever@eecs.umich.edu case COND_MI: return n; 822667Sstever@eecs.umich.edu case COND_PL: return !n; 832667Sstever@eecs.umich.edu case COND_VS: return v; 842667Sstever@eecs.umich.edu case COND_VC: return !v; 852667Sstever@eecs.umich.edu case COND_HI: return (c && !z); 862762Sstever@eecs.umich.edu case COND_LS: return !(c && !z); 872667Sstever@eecs.umich.edu case COND_GE: return !(n ^ v); 882667Sstever@eecs.umich.edu case COND_LT: return (n ^ v); 892667Sstever@eecs.umich.edu case COND_GT: return !(n ^ v || z); 902763Sstever@eecs.umich.edu case COND_LE: return (n ^ v || z); 912738Sstever@eecs.umich.edu case COND_AL: return true; 922738Sstever@eecs.umich.edu case COND_UC: return true; 932763Sstever@eecs.umich.edu default: 942667Sstever@eecs.umich.edu panic("Unhandled predicate condition: %d\n", code); 952667Sstever@eecs.umich.edu } 962667Sstever@eecs.umich.edu} 972667Sstever@eecs.umich.edu 982667Sstever@eecs.umich.edu/** 992667Sstever@eecs.umich.edu * Function to insure ISA semantics about 0 registers. 1002667Sstever@eecs.umich.edu * @param tc The thread context. 1012667Sstever@eecs.umich.edu */ 1022667Sstever@eecs.umich.edutemplate <class TC> 1032667Sstever@eecs.umich.eduvoid zeroRegisters(TC *tc); 1041527SN/A 1052667Sstever@eecs.umich.eduinline void startupCPU(ThreadContext *tc, int cpuId) 1062667Sstever@eecs.umich.edu{ 1072763Sstever@eecs.umich.edu tc->activate(); 1081511SN/A} 1092667Sstever@eecs.umich.edu 1102763Sstever@eecs.umich.eduvoid copyRegs(ThreadContext *src, ThreadContext *dest); 1112655Sstever@eecs.umich.edu 1122667Sstever@eecs.umich.edustatic inline void 1132667Sstever@eecs.umich.educopyMiscRegs(ThreadContext *src, ThreadContext *dest) 1142667Sstever@eecs.umich.edu{ 1152667Sstever@eecs.umich.edu panic("Copy Misc. Regs Not Implemented Yet\n"); 1162797Sktlim@umich.edu} 1172860Sktlim@umich.edu 1182839Sktlim@umich.eduvoid initCPU(ThreadContext *tc, int cpuId); 1192860Sktlim@umich.edu 1202860Sktlim@umich.edustatic inline bool 1212860Sktlim@umich.eduinUserMode(CPSR cpsr) 1222860Sktlim@umich.edu{ 1232860Sktlim@umich.edu return cpsr.mode == MODE_USER || cpsr.mode == MODE_EL0T; 1242860Sktlim@umich.edu} 1252860Sktlim@umich.edu 1262860Sktlim@umich.edustatic inline bool 1272860Sktlim@umich.eduinUserMode(ThreadContext *tc) 1282860Sktlim@umich.edu{ 1292839Sktlim@umich.edu return inUserMode(tc->readMiscRegNoEffect(MISCREG_CPSR)); 1302839Sktlim@umich.edu} 1312839Sktlim@umich.edu 1322797Sktlim@umich.edustatic inline bool 1332839Sktlim@umich.eduinPrivilegedMode(CPSR cpsr) 1342797Sktlim@umich.edu{ 1352860Sktlim@umich.edu return !inUserMode(cpsr); 1362860Sktlim@umich.edu} 1372839Sktlim@umich.edu 1382860Sktlim@umich.edustatic inline bool 1392797Sktlim@umich.eduinPrivilegedMode(ThreadContext *tc) 1402797Sktlim@umich.edu{ 1412797Sktlim@umich.edu return !inUserMode(tc); 1422797Sktlim@umich.edu} 1432868Sktlim@umich.edu 1442797Sktlim@umich.edubool inAArch64(ThreadContext *tc); 1452797Sktlim@umich.edu 1462839Sktlim@umich.edustatic inline OperatingMode 1472797Sktlim@umich.educurrOpMode(ThreadContext *tc) 1482868Sktlim@umich.edu{ 1492797Sktlim@umich.edu CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 1502797Sktlim@umich.edu return (OperatingMode) (uint8_t) cpsr.mode; 1512868Sktlim@umich.edu} 1522797Sktlim@umich.edu 1532868Sktlim@umich.edustatic inline ExceptionLevel 1542865Sktlim@umich.educurrEL(ThreadContext *tc) 1552797Sktlim@umich.edu{ 1562797Sktlim@umich.edu return opModeToEL(currOpMode(tc)); 1572797Sktlim@umich.edu} 1582797Sktlim@umich.edu 1592797Sktlim@umich.edu/** 1602839Sktlim@umich.edu * This function checks whether selected EL provided as an argument 1612797Sktlim@umich.edu * is using the AArch32 ISA. This information might be unavailable 1622797Sktlim@umich.edu * at the current EL status: it hence returns a pair of boolean values: 1632797Sktlim@umich.edu * a first boolean, true if information is available (known), 1642797Sktlim@umich.edu * and a second one, true if EL is using AArch32, false for AArch64. 1652797Sktlim@umich.edu * 1662797Sktlim@umich.edu * @param tc The thread context. 1672797Sktlim@umich.edu * @param el The target exception level. 1682797Sktlim@umich.edu * @retval known is FALSE for EL0 if the current Exception level 1692839Sktlim@umich.edu * is not EL0 and EL1 is using AArch64, since it cannot 1702797Sktlim@umich.edu * determine the state of EL0; TRUE otherwise. 1712797Sktlim@umich.edu * @retval aarch32 is TRUE if the specified Exception level is using AArch32; 1722797Sktlim@umich.edu * FALSE otherwise. 1732797Sktlim@umich.edu */ 1742797Sktlim@umich.edustd::pair<bool, bool> 1752797Sktlim@umich.eduELUsingAArch32K(ThreadContext *tc, ExceptionLevel el); 1762797Sktlim@umich.edu 1772797Sktlim@umich.edubool ELIs32(ThreadContext *tc, ExceptionLevel el); 1782797Sktlim@umich.edu 1792797Sktlim@umich.edubool ELIs64(ThreadContext *tc, ExceptionLevel el); 1802797Sktlim@umich.edu 1812797Sktlim@umich.edu/** 1822797Sktlim@umich.edu * Returns true if the current exception level `el` is executing a Host OS or 1832797Sktlim@umich.edu * an application of a Host OS (Armv8.1 Virtualization Host Extensions). 1842797Sktlim@umich.edu */ 1852797Sktlim@umich.edubool ELIsInHost(ThreadContext *tc, ExceptionLevel el); 1862797Sktlim@umich.edu 1872797Sktlim@umich.edubool isBigEndian64(ThreadContext *tc); 1882797Sktlim@umich.edu 1892797Sktlim@umich.edu/** 1902839Sktlim@umich.edu * badMode is checking if the execution mode provided as an argument is 1912839Sktlim@umich.edu * valid and implemented for AArch32 1922797Sktlim@umich.edu * 1932797Sktlim@umich.edu * @param tc ThreadContext 1942839Sktlim@umich.edu * @param mode OperatingMode to check 1952839Sktlim@umich.edu * @return false if mode is valid and implemented, true otherwise 1962797Sktlim@umich.edu */ 1972839Sktlim@umich.edubool badMode32(ThreadContext *tc, OperatingMode mode); 1982797Sktlim@umich.edu 1992839Sktlim@umich.edu/** 2002797Sktlim@umich.edu * badMode is checking if the execution mode provided as an argument is 2012797Sktlim@umich.edu * valid and implemented. 2022797Sktlim@umich.edu * 2032797Sktlim@umich.edu * @param tc ThreadContext 2042797Sktlim@umich.edu * @param mode OperatingMode to check 2052797Sktlim@umich.edu * @return false if mode is valid and implemented, true otherwise 2062797Sktlim@umich.edu */ 2072797Sktlim@umich.edubool badMode(ThreadContext *tc, OperatingMode mode); 2082797Sktlim@umich.edu 209static inline uint8_t 210itState(CPSR psr) 211{ 212 ITSTATE it = 0; 213 it.top6 = psr.it2; 214 it.bottom2 = psr.it1; 215 216 return (uint8_t)it; 217} 218 219/** 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. 225 */ 226Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, 227 TTBCR tcr); 228Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el); 229 230static inline bool 231inSecureState(SCR scr, CPSR cpsr) 232{ 233 switch ((OperatingMode) (uint8_t) cpsr.mode) { 234 case MODE_MON: 235 case MODE_EL3T: 236 case MODE_EL3H: 237 return true; 238 case MODE_HYP: 239 case MODE_EL2T: 240 case MODE_EL2H: 241 return false; 242 default: 243 return !scr.ns; 244 } 245} 246 247bool inSecureState(ThreadContext *tc); 248 249/** 250 * Return TRUE if an Exception level below EL3 is in Secure state. 251 * Differs from inSecureState in that it ignores the current EL 252 * or Mode in considering security state. 253 */ 254inline bool isSecureBelowEL3(ThreadContext *tc); 255 256bool longDescFormatInUse(ThreadContext *tc); 257 258/** This helper function is either returing the value of 259 * MPIDR_EL1 (by calling getMPIDR), or it is issuing a read 260 * to VMPIDR_EL2 (as it happens in virtualized systems) */ 261RegVal readMPIDR(ArmSystem *arm_sys, ThreadContext *tc); 262 263/** This helper function is returing the value of MPIDR_EL1 */ 264RegVal getMPIDR(ArmSystem *arm_sys, ThreadContext *tc); 265 266static inline uint32_t 267mcrMrcIssBuild(bool isRead, uint32_t crm, IntRegIndex rt, uint32_t crn, 268 uint32_t opc1, uint32_t opc2) 269{ 270 return (isRead << 0) | 271 (crm << 1) | 272 (rt << 5) | 273 (crn << 10) | 274 (opc1 << 14) | 275 (opc2 << 17); 276} 277 278static inline void 279mcrMrcIssExtract(uint32_t iss, bool &isRead, uint32_t &crm, IntRegIndex &rt, 280 uint32_t &crn, uint32_t &opc1, uint32_t &opc2) 281{ 282 isRead = (iss >> 0) & 0x1; 283 crm = (iss >> 1) & 0xF; 284 rt = (IntRegIndex) ((iss >> 5) & 0xF); 285 crn = (iss >> 10) & 0xF; 286 opc1 = (iss >> 14) & 0x7; 287 opc2 = (iss >> 17) & 0x7; 288} 289 290static inline uint32_t 291mcrrMrrcIssBuild(bool isRead, uint32_t crm, IntRegIndex rt, IntRegIndex rt2, 292 uint32_t opc1) 293{ 294 return (isRead << 0) | 295 (crm << 1) | 296 (rt << 5) | 297 (rt2 << 10) | 298 (opc1 << 16); 299} 300 301static inline uint32_t 302msrMrs64IssBuild(bool isRead, uint32_t op0, uint32_t op1, uint32_t crn, 303 uint32_t crm, uint32_t op2, IntRegIndex rt) 304{ 305 return isRead | 306 (crm << 1) | 307 (rt << 5) | 308 (crn << 10) | 309 (op1 << 14) | 310 (op2 << 17) | 311 (op0 << 20); 312} 313 314bool 315mcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss); 316 317bool 318mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr, 319 HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss); 320bool 321mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr, 322 HCR hcr, uint32_t iss); 323 324bool SPAlignmentCheckEnabled(ThreadContext* tc); 325 326uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp); 327 328void skipFunction(ThreadContext *tc); 329 330inline void 331advancePC(PCState &pc, const StaticInstPtr &inst) 332{ 333 inst->advancePC(pc); 334} 335 336Addr truncPage(Addr addr); 337Addr roundPage(Addr addr); 338 339inline uint64_t 340getExecutingAsid(ThreadContext *tc) 341{ 342 return tc->readMiscReg(MISCREG_CONTEXTIDR); 343} 344 345// Decodes the register index to access based on the fields used in a MSR 346// or MRS instruction 347bool 348decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int ®Idx, 349 CPSR cpsr, SCR scr, NSACR nsacr, 350 bool checkSecurity = true); 351 352// This wrapper function is used to turn the register index into a source 353// parameter for the instruction. See Operands.isa 354static inline int 355decodeMrsMsrBankedIntRegIndex(uint8_t sysM, bool r) 356{ 357 int regIdx; 358 bool isIntReg; 359 bool validReg; 360 361 validReg = decodeMrsMsrBankedReg(sysM, r, isIntReg, regIdx, 0, 0, 0, false); 362 return (validReg && isIntReg) ? regIdx : INTREG_DUMMY; 363} 364 365/** 366 * Returns the n. of PA bits corresponding to the specified encoding. 367 */ 368int decodePhysAddrRange64(uint8_t pa_enc); 369 370/** 371 * Returns the encoding corresponding to the specified n. of PA bits. 372 */ 373uint8_t encodePhysAddrRange64(int pa_size); 374 375inline ByteOrder byteOrder(ThreadContext *tc) 376{ 377 return isBigEndian64(tc) ? BigEndianByteOrder : LittleEndianByteOrder; 378}; 379 380} 381 382#endif 383