utility.hh revision 14169
16019Shines@cs.fsu.edu/* 27111Sgblack@eecs.umich.edu * Copyright (c) 2010, 2012-2013, 2016-2019 ARM Limited 37111Sgblack@eecs.umich.edu * All rights reserved 47111Sgblack@eecs.umich.edu * 57111Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 67111Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 77111Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 87111Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 97111Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 107111Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 117111Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 127111Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137111Sgblack@eecs.umich.edu * 146019Shines@cs.fsu.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan 156019Shines@cs.fsu.edu * Copyright (c) 2007-2008 The Florida State University 166019Shines@cs.fsu.edu * All rights reserved. 176019Shines@cs.fsu.edu * 186019Shines@cs.fsu.edu * Redistribution and use in source and binary forms, with or without 196019Shines@cs.fsu.edu * modification, are permitted provided that the following conditions are 206019Shines@cs.fsu.edu * met: redistributions of source code must retain the above copyright 216019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer; 226019Shines@cs.fsu.edu * redistributions in binary form must reproduce the above copyright 236019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer in the 246019Shines@cs.fsu.edu * documentation and/or other materials provided with the distribution; 256019Shines@cs.fsu.edu * neither the name of the copyright holders nor the names of its 266019Shines@cs.fsu.edu * contributors may be used to endorse or promote products derived from 276019Shines@cs.fsu.edu * this software without specific prior written permission. 286019Shines@cs.fsu.edu * 296019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 306019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 316019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 326019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 336019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 346019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 356019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 366019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 376019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 386019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 396019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 406019Shines@cs.fsu.edu * 416019Shines@cs.fsu.edu * Authors: Korey Sewell 426019Shines@cs.fsu.edu * Stephen Hines 436019Shines@cs.fsu.edu */ 446019Shines@cs.fsu.edu 456019Shines@cs.fsu.edu#ifndef __ARCH_ARM_UTILITY_HH__ 466019Shines@cs.fsu.edu#define __ARCH_ARM_UTILITY_HH__ 476019Shines@cs.fsu.edu 486242Sgblack@eecs.umich.edu#include "arch/arm/isa_traits.hh" 496019Shines@cs.fsu.edu#include "arch/arm/miscregs.hh" 506251Sgblack@eecs.umich.edu#include "arch/arm/types.hh" 517408Sgblack@eecs.umich.edu#include "base/logging.hh" 526216Snate@binkert.org#include "base/trace.hh" 536019Shines@cs.fsu.edu#include "base/types.hh" 546019Shines@cs.fsu.edu#include "cpu/static_inst.hh" 556251Sgblack@eecs.umich.edu#include "cpu/thread_context.hh" 566251Sgblack@eecs.umich.edu 576251Sgblack@eecs.umich.educlass ArmSystem; 586251Sgblack@eecs.umich.edu 596251Sgblack@eecs.umich.edunamespace ArmISA { 606251Sgblack@eecs.umich.edu 616251Sgblack@eecs.umich.eduinline PCState 626251Sgblack@eecs.umich.edubuildRetPC(const PCState &curPC, const PCState &callPC) 636251Sgblack@eecs.umich.edu{ 646019Shines@cs.fsu.edu PCState retPC = callPC; 656019Shines@cs.fsu.edu retPC.uEnd(); 666242Sgblack@eecs.umich.edu return retPC; 676242Sgblack@eecs.umich.edu} 686242Sgblack@eecs.umich.edu 696242Sgblack@eecs.umich.eduinline bool 706242Sgblack@eecs.umich.edutestPredicate(uint32_t nz, uint32_t c, uint32_t v, ConditionCode code) 716242Sgblack@eecs.umich.edu{ 726242Sgblack@eecs.umich.edu bool n = (nz & 0x2); 736242Sgblack@eecs.umich.edu bool z = (nz & 0x1); 746242Sgblack@eecs.umich.edu 756242Sgblack@eecs.umich.edu switch (code) 766242Sgblack@eecs.umich.edu { 776242Sgblack@eecs.umich.edu case COND_EQ: return z; 786242Sgblack@eecs.umich.edu case COND_NE: return !z; 796242Sgblack@eecs.umich.edu case COND_CS: return c; 806242Sgblack@eecs.umich.edu case COND_CC: return !c; 816242Sgblack@eecs.umich.edu case COND_MI: return n; 826242Sgblack@eecs.umich.edu case COND_PL: return !n; 836242Sgblack@eecs.umich.edu case COND_VS: return v; 846242Sgblack@eecs.umich.edu case COND_VC: return !v; 856242Sgblack@eecs.umich.edu case COND_HI: return (c && !z); 867111Sgblack@eecs.umich.edu case COND_LS: return !(c && !z); 876242Sgblack@eecs.umich.edu case COND_GE: return !(n ^ v); 886242Sgblack@eecs.umich.edu case COND_LT: return (n ^ v); 896242Sgblack@eecs.umich.edu case COND_GT: return !(n ^ v || z); 906242Sgblack@eecs.umich.edu case COND_LE: return (n ^ v || z); 916242Sgblack@eecs.umich.edu case COND_AL: return true; 926019Shines@cs.fsu.edu case COND_UC: return true; 936019Shines@cs.fsu.edu default: 946019Shines@cs.fsu.edu panic("Unhandled predicate condition: %d\n", code); 956019Shines@cs.fsu.edu } 966019Shines@cs.fsu.edu} 976019Shines@cs.fsu.edu 986019Shines@cs.fsu.edu/** 996019Shines@cs.fsu.edu * Function to insure ISA semantics about 0 registers. 1006019Shines@cs.fsu.edu * @param tc The thread context. 1016019Shines@cs.fsu.edu */ 1026019Shines@cs.fsu.edutemplate <class TC> 1036246Sgblack@eecs.umich.eduvoid zeroRegisters(TC *tc); 1046246Sgblack@eecs.umich.edu 1056246Sgblack@eecs.umich.eduinline void startupCPU(ThreadContext *tc, int cpuId) 1066246Sgblack@eecs.umich.edu{ 1076246Sgblack@eecs.umich.edu tc->activate(); 1086246Sgblack@eecs.umich.edu} 1096246Sgblack@eecs.umich.edu 1106329Sgblack@eecs.umich.eduvoid copyRegs(ThreadContext *src, ThreadContext *dest); 1116329Sgblack@eecs.umich.edu 1126329Sgblack@eecs.umich.edustatic inline void 1136329Sgblack@eecs.umich.educopyMiscRegs(ThreadContext *src, ThreadContext *dest) 1146329Sgblack@eecs.umich.edu{ 1156329Sgblack@eecs.umich.edu panic("Copy Misc. Regs Not Implemented Yet\n"); 1166329Sgblack@eecs.umich.edu} 1176329Sgblack@eecs.umich.edu 1186329Sgblack@eecs.umich.eduvoid initCPU(ThreadContext *tc, int cpuId); 1196329Sgblack@eecs.umich.edu 1206329Sgblack@eecs.umich.edustatic inline bool 1216329Sgblack@eecs.umich.eduinUserMode(CPSR cpsr) 1226757SAli.Saidi@ARM.com{ 1236757SAli.Saidi@ARM.com return cpsr.mode == MODE_USER || cpsr.mode == MODE_EL0T; 1246757SAli.Saidi@ARM.com} 1256757SAli.Saidi@ARM.com 1267638Sgblack@eecs.umich.edustatic inline bool 1277638Sgblack@eecs.umich.eduinUserMode(ThreadContext *tc) 1287638Sgblack@eecs.umich.edu{ 1297638Sgblack@eecs.umich.edu return inUserMode(tc->readMiscRegNoEffect(MISCREG_CPSR)); 1307638Sgblack@eecs.umich.edu} 1317638Sgblack@eecs.umich.edu 1326757SAli.Saidi@ARM.comstatic inline bool 1336757SAli.Saidi@ARM.cominPrivilegedMode(CPSR cpsr) 1347638Sgblack@eecs.umich.edu{ 1357638Sgblack@eecs.umich.edu return !inUserMode(cpsr); 1367638Sgblack@eecs.umich.edu} 1377638Sgblack@eecs.umich.edu 1387638Sgblack@eecs.umich.edustatic inline bool 1397638Sgblack@eecs.umich.eduinPrivilegedMode(ThreadContext *tc) 1407638Sgblack@eecs.umich.edu{ 1417638Sgblack@eecs.umich.edu return !inUserMode(tc); 1427638Sgblack@eecs.umich.edu} 1437638Sgblack@eecs.umich.edu 1447638Sgblack@eecs.umich.edubool inAArch64(ThreadContext *tc); 1457638Sgblack@eecs.umich.edu 1467638Sgblack@eecs.umich.edustatic inline OperatingMode 1476757SAli.Saidi@ARM.comcurrOpMode(ThreadContext *tc) 1486757SAli.Saidi@ARM.com{ 1496757SAli.Saidi@ARM.com CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 1506759SAli.Saidi@ARM.com return (OperatingMode) (uint8_t) cpsr.mode; 1516759SAli.Saidi@ARM.com} 1526759SAli.Saidi@ARM.com 1536757SAli.Saidi@ARM.comstatic inline ExceptionLevel 1546019Shines@cs.fsu.educurrEL(ThreadContext *tc) 1556019Shines@cs.fsu.edu{ 1566019Shines@cs.fsu.edu return opModeToEL(currOpMode(tc)); 1576019Shines@cs.fsu.edu} 158 159/** 160 * This function checks whether selected EL provided as an argument 161 * is using the AArch32 ISA. This information might be unavailable 162 * at the current EL status: it hence returns a pair of boolean values: 163 * a first boolean, true if information is available (known), 164 * and a second one, true if EL is using AArch32, false for AArch64. 165 * 166 * @param tc The thread context. 167 * @param el The target exception level. 168 * @retval known is FALSE for EL0 if the current Exception level 169 * is not EL0 and EL1 is using AArch64, since it cannot 170 * determine the state of EL0; TRUE otherwise. 171 * @retval aarch32 is TRUE if the specified Exception level is using AArch32; 172 * FALSE otherwise. 173 */ 174std::pair<bool, bool> 175ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el); 176 177bool ELIs32(ThreadContext *tc, ExceptionLevel el); 178 179bool ELIs64(ThreadContext *tc, ExceptionLevel el); 180 181/** 182 * Returns true if the current exception level `el` is executing a Host OS or 183 * an application of a Host OS (Armv8.1 Virtualization Host Extensions). 184 */ 185bool ELIsInHost(ThreadContext *tc, ExceptionLevel el); 186 187bool isBigEndian64(ThreadContext *tc); 188 189/** 190 * badMode is checking if the execution mode provided as an argument is 191 * valid and implemented for AArch32 192 * 193 * @param tc ThreadContext 194 * @param mode OperatingMode to check 195 * @return false if mode is valid and implemented, true otherwise 196 */ 197bool badMode32(ThreadContext *tc, OperatingMode mode); 198 199/** 200 * badMode is checking if the execution mode provided as an argument is 201 * valid and implemented. 202 * 203 * @param tc ThreadContext 204 * @param mode OperatingMode to check 205 * @return false if mode is valid and implemented, true otherwise 206 */ 207bool badMode(ThreadContext *tc, OperatingMode mode); 208 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