1/* 2 * Copyright (c) 2009-2014, 2016-2019 ARM Limited 3 * All rights reserved. 4 * 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. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Ali Saidi 38 */ 39 40#include "arch/arm/utility.hh" 41 42#include <memory> 43 44#include "arch/arm/faults.hh" 45#include "arch/arm/isa_traits.hh" 46#include "arch/arm/system.hh" 47#include "arch/arm/tlb.hh" 48#include "arch/arm/vtophys.hh" 49#include "cpu/base.hh" 50#include "cpu/checker/cpu.hh" 51#include "cpu/thread_context.hh" 52#include "mem/fs_translating_port_proxy.hh" 53#include "sim/full_system.hh" 54 55namespace ArmISA { 56 57void 58initCPU(ThreadContext *tc, int cpuId) 59{ 60 // Reset CP15?? What does that mean -- ali 61 62 // FPEXC.EN = 0 63 64 static Fault reset = std::make_shared<Reset>(); 65 reset->invoke(tc); 66} 67 68uint64_t 69getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp) 70{ 71 if (!FullSystem) { 72 panic("getArgument() only implemented for full system mode.\n"); 73 M5_DUMMY_RETURN 74 } 75 76 if (fp) 77 panic("getArgument(): Floating point arguments not implemented\n"); 78 79 if (inAArch64(tc)) { 80 if (size == (uint16_t)(-1)) 81 size = sizeof(uint64_t); 82 83 if (number < 8 /*NumArgumentRegs64*/) { 84 return tc->readIntReg(number); 85 } else { 86 panic("getArgument(): No support reading stack args for AArch64\n"); 87 } 88 } else { 89 if (size == (uint16_t)(-1)) 90 // todo: should this not be sizeof(uint32_t) rather? 91 size = ArmISA::MachineBytes; 92 93 if (number < NumArgumentRegs) { 94 // If the argument is 64 bits, it must be in an even regiser 95 // number. Increment the number here if it isn't even. 96 if (size == sizeof(uint64_t)) { 97 if ((number % 2) != 0) 98 number++; 99 // Read the two halves of the data. Number is inc here to 100 // get the second half of the 64 bit reg. 101 uint64_t tmp; 102 tmp = tc->readIntReg(number++); 103 tmp |= tc->readIntReg(number) << 32; 104 return tmp; 105 } else { 106 return tc->readIntReg(number); 107 } 108 } else { 109 Addr sp = tc->readIntReg(StackPointerReg); 110 PortProxy &vp = tc->getVirtProxy(); 111 uint64_t arg; 112 if (size == sizeof(uint64_t)) { 113 // If the argument is even it must be aligned 114 if ((number % 2) != 0) 115 number++; 116 arg = vp.read<uint64_t>(sp + 117 (number-NumArgumentRegs) * sizeof(uint32_t)); 118 // since two 32 bit args == 1 64 bit arg, increment number 119 number++; 120 } else { 121 arg = vp.read<uint32_t>(sp + 122 (number-NumArgumentRegs) * sizeof(uint32_t)); 123 } 124 return arg; 125 } 126 } 127 panic("getArgument() should always return\n"); 128} 129 130void 131skipFunction(ThreadContext *tc) 132{ 133 PCState newPC = tc->pcState(); 134 if (inAArch64(tc)) { 135 newPC.set(tc->readIntReg(INTREG_X30)); 136 } else { 137 newPC.set(tc->readIntReg(ReturnAddressReg) & ~ULL(1)); 138 } 139 140 CheckerCPU *checker = tc->getCheckerCpuPtr(); 141 if (checker) { 142 tc->pcStateNoRecord(newPC); 143 } else { 144 tc->pcState(newPC); 145 } 146} 147 148static void 149copyVecRegs(ThreadContext *src, ThreadContext *dest) 150{ 151 auto src_mode = RenameMode<ArmISA::ISA>::mode(src->pcState()); 152 153 // The way vector registers are copied (VecReg vs VecElem) is relevant 154 // in the O3 model only. 155 if (src_mode == Enums::Full) { 156 for (auto idx = 0; idx < NumVecRegs; idx++) 157 dest->setVecRegFlat(idx, src->readVecRegFlat(idx)); 158 } else { 159 for (auto idx = 0; idx < NumVecRegs; idx++) 160 for (auto elem_idx = 0; elem_idx < NumVecElemPerVecReg; elem_idx++) 161 dest->setVecElemFlat( 162 idx, elem_idx, src->readVecElemFlat(idx, elem_idx)); 163 } 164} 165 166void 167copyRegs(ThreadContext *src, ThreadContext *dest) 168{ 169 for (int i = 0; i < NumIntRegs; i++) 170 dest->setIntRegFlat(i, src->readIntRegFlat(i)); 171 172 for (int i = 0; i < NumFloatRegs; i++) 173 dest->setFloatRegFlat(i, src->readFloatRegFlat(i)); 174 175 for (int i = 0; i < NumCCRegs; i++) 176 dest->setCCReg(i, src->readCCReg(i)); 177 178 for (int i = 0; i < NumMiscRegs; i++) 179 dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); 180 181 copyVecRegs(src, dest); 182 183 // setMiscReg "with effect" will set the misc register mapping correctly. 184 // e.g. updateRegMap(val) 185 dest->setMiscReg(MISCREG_CPSR, src->readMiscRegNoEffect(MISCREG_CPSR)); 186 187 // Copy over the PC State 188 dest->pcState(src->pcState()); 189 190 // Invalidate the tlb misc register cache 191 dynamic_cast<TLB *>(dest->getITBPtr())->invalidateMiscReg(); 192 dynamic_cast<TLB *>(dest->getDTBPtr())->invalidateMiscReg(); 193} 194 195bool 196inSecureState(ThreadContext *tc) 197{ 198 SCR scr = inAArch64(tc) ? tc->readMiscReg(MISCREG_SCR_EL3) : 199 tc->readMiscReg(MISCREG_SCR); 200 return ArmSystem::haveSecurity(tc) && inSecureState( 201 scr, tc->readMiscReg(MISCREG_CPSR)); 202} 203 204inline bool 205isSecureBelowEL3(ThreadContext *tc) 206{ 207 SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); 208 return ArmSystem::haveEL(tc, EL3) && scr.ns == 0; 209} 210 211bool 212inAArch64(ThreadContext *tc) 213{ 214 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 215 return opModeIs64((OperatingMode) (uint8_t) cpsr.mode); 216} 217 218bool 219longDescFormatInUse(ThreadContext *tc) 220{ 221 TTBCR ttbcr = tc->readMiscReg(MISCREG_TTBCR); 222 return ArmSystem::haveLPAE(tc) && ttbcr.eae; 223} 224 225RegVal 226readMPIDR(ArmSystem *arm_sys, ThreadContext *tc) 227{ 228 const ExceptionLevel current_el = currEL(tc); 229 230 const bool is_secure = isSecureBelowEL3(tc); 231 232 switch (current_el) { 233 case EL0: 234 // Note: in MsrMrs instruction we read the register value before 235 // checking access permissions. This means that EL0 entry must 236 // be part of the table even if MPIDR is not accessible in user 237 // mode. 238 warn_once("Trying to read MPIDR at EL0\n"); 239 M5_FALLTHROUGH; 240 case EL1: 241 if (ArmSystem::haveEL(tc, EL2) && !is_secure) 242 return tc->readMiscReg(MISCREG_VMPIDR_EL2); 243 else 244 return getMPIDR(arm_sys, tc); 245 case EL2: 246 case EL3: 247 return getMPIDR(arm_sys, tc); 248 default: 249 panic("Invalid EL for reading MPIDR register\n"); 250 } 251} 252 253RegVal 254getMPIDR(ArmSystem *arm_sys, ThreadContext *tc) 255{ 256 // Multiprocessor Affinity Register MPIDR from Cortex(tm)-A15 Technical 257 // Reference Manual 258 // 259 // bit 31 - Multi-processor extensions available 260 // bit 30 - Uni-processor system 261 // bit 24 - Multi-threaded cores 262 // bit 11-8 - Cluster ID 263 // bit 1-0 - CPU ID 264 // 265 // We deliberately extend both the Cluster ID and CPU ID fields to allow 266 // for simulation of larger systems 267 assert((0 <= tc->cpuId()) && (tc->cpuId() < 256)); 268 assert(tc->socketId() < 65536); 269 if (arm_sys->multiThread) { 270 return 0x80000000 | // multiprocessor extensions available 271 0x01000000 | // multi-threaded cores 272 tc->contextId(); 273 } else if (arm_sys->multiProc) { 274 return 0x80000000 | // multiprocessor extensions available 275 tc->cpuId() | tc->socketId() << 8; 276 } else { 277 return 0x80000000 | // multiprocessor extensions available 278 0x40000000 | // in up system 279 tc->cpuId() | tc->socketId() << 8; 280 } 281} 282 283bool 284ELIs64(ThreadContext *tc, ExceptionLevel el) 285{ 286 return !ELIs32(tc, el); 287} 288 289bool 290ELIs32(ThreadContext *tc, ExceptionLevel el) 291{ 292 bool known, aarch32; 293 std::tie(known, aarch32) = ELUsingAArch32K(tc, el); 294 panic_if(!known, "EL state is UNKNOWN"); 295 return aarch32; 296} 297 298bool 299ELIsInHost(ThreadContext *tc, ExceptionLevel el) 300{ 301 if (!ArmSystem::haveVirtualization(tc)) { 302 return false; 303 } 304 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); 305 return (!isSecureBelowEL3(tc) && !ELIs32(tc, EL2) && hcr.e2h == 1 && 306 (el == EL2 || (el == EL0 && hcr.tge == 1))); 307} 308 309std::pair<bool, bool> 310ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el) 311{ 312 // Return true if the specified EL is in aarch32 state. 313 const bool have_el3 = ArmSystem::haveSecurity(tc); 314 const bool have_el2 = ArmSystem::haveVirtualization(tc); 315 316 panic_if(el == EL2 && !have_el2, "Asking for EL2 when it doesn't exist"); 317 panic_if(el == EL3 && !have_el3, "Asking for EL3 when it doesn't exist"); 318 319 bool known, aarch32; 320 known = aarch32 = false; 321 if (ArmSystem::highestELIs64(tc) && ArmSystem::highestEL(tc) == el) { 322 // Target EL is the highest one in a system where 323 // the highest is using AArch64. 324 known = true; aarch32 = false; 325 } else if (!ArmSystem::highestELIs64(tc)) { 326 // All ELs are using AArch32: 327 known = true; aarch32 = true; 328 } else { 329 SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); 330 bool aarch32_below_el3 = (have_el3 && scr.rw == 0); 331 332 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); 333 bool aarch32_at_el1 = (aarch32_below_el3 334 || (have_el2 335 && !isSecureBelowEL3(tc) && hcr.rw == 0)); 336 337 // Only know if EL0 using AArch32 from PSTATE 338 if (el == EL0 && !aarch32_at_el1) { 339 // EL0 controlled by PSTATE 340 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 341 342 known = (currEL(tc) == EL0); 343 aarch32 = (cpsr.width == 1); 344 } else { 345 known = true; 346 aarch32 = (aarch32_below_el3 && el != EL3) 347 || (aarch32_at_el1 && (el == EL0 || el == EL1) ); 348 } 349 } 350 351 return std::make_pair(known, aarch32); 352} 353 354bool 355isBigEndian64(ThreadContext *tc) 356{ 357 switch (currEL(tc)) { 358 case EL3: 359 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).ee; 360 case EL2: 361 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).ee; 362 case EL1: 363 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).ee; 364 case EL0: 365 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).e0e; 366 default: 367 panic("Invalid exception level"); 368 break; 369 } 370} 371 372bool 373badMode32(ThreadContext *tc, OperatingMode mode) 374{ 375 return unknownMode32(mode) || !ArmSystem::haveEL(tc, opModeToEL(mode)); 376} 377 378bool 379badMode(ThreadContext *tc, OperatingMode mode) 380{ 381 return unknownMode(mode) || !ArmSystem::haveEL(tc, opModeToEL(mode)); 382} 383 384Addr 385purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, 386 TTBCR tcr) 387{ 388 switch (el) { 389 case EL0: 390 case EL1: 391 if (bits(addr, 55, 48) == 0xFF && tcr.tbi1) 392 return addr | mask(63, 55); 393 else if (!bits(addr, 55, 48) && tcr.tbi0) 394 return bits(addr,55, 0); 395 break; 396 case EL2: 397 assert(ArmSystem::haveVirtualization(tc)); 398 tcr = tc->readMiscReg(MISCREG_TCR_EL2); 399 if (tcr.tbi) 400 return addr & mask(56); 401 break; 402 case EL3: 403 assert(ArmSystem::haveSecurity(tc)); 404 if (tcr.tbi) 405 return addr & mask(56); 406 break; 407 default: 408 panic("Invalid exception level"); 409 break; 410 } 411 412 return addr; // Nothing to do if this is not a tagged address 413} 414 415Addr 416purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el) 417{ 418 TTBCR tcr; 419 420 switch (el) { 421 case EL0: 422 case EL1: 423 tcr = tc->readMiscReg(MISCREG_TCR_EL1); 424 if (bits(addr, 55, 48) == 0xFF && tcr.tbi1) 425 return addr | mask(63, 55); 426 else if (!bits(addr, 55, 48) && tcr.tbi0) 427 return bits(addr,55, 0); 428 break; 429 case EL2: 430 assert(ArmSystem::haveVirtualization(tc)); 431 tcr = tc->readMiscReg(MISCREG_TCR_EL2); 432 if (tcr.tbi) 433 return addr & mask(56); 434 break; 435 case EL3: 436 assert(ArmSystem::haveSecurity(tc)); 437 tcr = tc->readMiscReg(MISCREG_TCR_EL3); 438 if (tcr.tbi) 439 return addr & mask(56); 440 break; 441 default: 442 panic("Invalid exception level"); 443 break; 444 } 445 446 return addr; // Nothing to do if this is not a tagged address 447} 448 449Addr 450truncPage(Addr addr) 451{ 452 return addr & ~(PageBytes - 1); 453} 454 455Addr 456roundPage(Addr addr) 457{ 458 return (addr + PageBytes - 1) & ~(PageBytes - 1); 459} 460 461bool 462mcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss) 463{ 464 bool isRead; 465 uint32_t crm; 466 IntRegIndex rt; 467 uint32_t crn; 468 uint32_t opc1; 469 uint32_t opc2; 470 bool trapToHype = false; 471 472 const CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 473 const HCR hcr = tc->readMiscReg(MISCREG_HCR); 474 const SCR scr = tc->readMiscReg(MISCREG_SCR); 475 const HDCR hdcr = tc->readMiscReg(MISCREG_HDCR); 476 const HSTR hstr = tc->readMiscReg(MISCREG_HSTR); 477 const HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR); 478 479 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { 480 mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2); 481 trapToHype = ((uint32_t) hstr) & (1 << crn); 482 trapToHype |= hdcr.tpm && (crn == 9) && (crm >= 12); 483 trapToHype |= hcr.tidcp && ( 484 ((crn == 9) && ((crm <= 2) || ((crm >= 5) && (crm <= 8)))) || 485 ((crn == 10) && ((crm <= 1) || (crm == 4) || (crm == 8))) || 486 ((crn == 11) && ((crm <= 8) || (crm == 15))) ); 487 488 if (!trapToHype) { 489 switch (unflattenMiscReg(miscReg)) { 490 case MISCREG_CPACR: 491 trapToHype = hcptr.tcpac; 492 break; 493 case MISCREG_REVIDR: 494 case MISCREG_TCMTR: 495 case MISCREG_TLBTR: 496 case MISCREG_AIDR: 497 trapToHype = hcr.tid1; 498 break; 499 case MISCREG_CTR: 500 case MISCREG_CCSIDR: 501 case MISCREG_CLIDR: 502 case MISCREG_CSSELR: 503 trapToHype = hcr.tid2; 504 break; 505 case MISCREG_ID_PFR0: 506 case MISCREG_ID_PFR1: 507 case MISCREG_ID_DFR0: 508 case MISCREG_ID_AFR0: 509 case MISCREG_ID_MMFR0: 510 case MISCREG_ID_MMFR1: 511 case MISCREG_ID_MMFR2: 512 case MISCREG_ID_MMFR3: 513 case MISCREG_ID_ISAR0: 514 case MISCREG_ID_ISAR1: 515 case MISCREG_ID_ISAR2: 516 case MISCREG_ID_ISAR3: 517 case MISCREG_ID_ISAR4: 518 case MISCREG_ID_ISAR5: 519 trapToHype = hcr.tid3; 520 break; 521 case MISCREG_DCISW: 522 case MISCREG_DCCSW: 523 case MISCREG_DCCISW: 524 trapToHype = hcr.tsw; 525 break; 526 case MISCREG_DCIMVAC: 527 case MISCREG_DCCIMVAC: 528 case MISCREG_DCCMVAC: 529 trapToHype = hcr.tpc; 530 break; 531 case MISCREG_ICIMVAU: 532 case MISCREG_ICIALLU: 533 case MISCREG_ICIALLUIS: 534 case MISCREG_DCCMVAU: 535 trapToHype = hcr.tpu; 536 break; 537 case MISCREG_TLBIALLIS: 538 case MISCREG_TLBIMVAIS: 539 case MISCREG_TLBIASIDIS: 540 case MISCREG_TLBIMVAAIS: 541 case MISCREG_TLBIMVALIS: 542 case MISCREG_TLBIMVAALIS: 543 case MISCREG_DTLBIALL: 544 case MISCREG_ITLBIALL: 545 case MISCREG_DTLBIMVA: 546 case MISCREG_ITLBIMVA: 547 case MISCREG_DTLBIASID: 548 case MISCREG_ITLBIASID: 549 case MISCREG_TLBIMVAA: 550 case MISCREG_TLBIALL: 551 case MISCREG_TLBIMVA: 552 case MISCREG_TLBIMVAL: 553 case MISCREG_TLBIMVAAL: 554 case MISCREG_TLBIASID: 555 trapToHype = hcr.ttlb; 556 break; 557 case MISCREG_ACTLR: 558 trapToHype = hcr.tac; 559 break; 560 case MISCREG_SCTLR: 561 case MISCREG_TTBR0: 562 case MISCREG_TTBR1: 563 case MISCREG_TTBCR: 564 case MISCREG_DACR: 565 case MISCREG_DFSR: 566 case MISCREG_IFSR: 567 case MISCREG_DFAR: 568 case MISCREG_IFAR: 569 case MISCREG_ADFSR: 570 case MISCREG_AIFSR: 571 case MISCREG_PRRR: 572 case MISCREG_NMRR: 573 case MISCREG_MAIR0: 574 case MISCREG_MAIR1: 575 case MISCREG_CONTEXTIDR: 576 trapToHype = hcr.tvm & !isRead; 577 break; 578 case MISCREG_PMCR: 579 trapToHype = hdcr.tpmcr; 580 break; 581 // GICv3 regs 582 case MISCREG_ICC_SGI0R: 583 if (tc->getIsaPtr()->haveGICv3CpuIfc()) 584 trapToHype = hcr.fmo; 585 break; 586 case MISCREG_ICC_SGI1R: 587 case MISCREG_ICC_ASGI1R: 588 if (tc->getIsaPtr()->haveGICv3CpuIfc()) 589 trapToHype = hcr.imo; 590 break; 591 // No default action needed 592 default: 593 break; 594 } 595 } 596 } 597 return trapToHype; 598} 599 600 601bool 602mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr, 603 HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss) 604{ 605 bool isRead; 606 uint32_t crm; 607 IntRegIndex rt; 608 uint32_t crn; 609 uint32_t opc1; 610 uint32_t opc2; 611 bool trapToHype = false; 612 613 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { 614 mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2); 615 inform("trap check M:%x N:%x 1:%x 2:%x hdcr %x, hcptr %x, hstr %x\n", 616 crm, crn, opc1, opc2, hdcr, hcptr, hstr); 617 trapToHype = hdcr.tda && (opc1 == 0); 618 trapToHype |= hcptr.tta && (opc1 == 1); 619 if (!trapToHype) { 620 switch (unflattenMiscReg(miscReg)) { 621 case MISCREG_DBGOSLSR: 622 case MISCREG_DBGOSLAR: 623 case MISCREG_DBGOSDLR: 624 case MISCREG_DBGPRCR: 625 trapToHype = hdcr.tdosa; 626 break; 627 case MISCREG_DBGDRAR: 628 case MISCREG_DBGDSAR: 629 trapToHype = hdcr.tdra; 630 break; 631 case MISCREG_JIDR: 632 trapToHype = hcr.tid0; 633 break; 634 case MISCREG_JOSCR: 635 case MISCREG_JMCR: 636 trapToHype = hstr.tjdbx; 637 break; 638 case MISCREG_TEECR: 639 case MISCREG_TEEHBR: 640 trapToHype = hstr.ttee; 641 break; 642 // No default action needed 643 default: 644 break; 645 } 646 } 647 } 648 return trapToHype; 649} 650 651bool 652mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr, 653 HCR hcr, uint32_t iss) 654{ 655 uint32_t crm; 656 IntRegIndex rt; 657 uint32_t crn; 658 uint32_t opc1; 659 uint32_t opc2; 660 bool isRead; 661 bool trapToHype = false; 662 663 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { 664 // This is technically the wrong function, but we can re-use it for 665 // the moment because we only need one field, which overlaps with the 666 // mcrmrc layout 667 mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2); 668 trapToHype = ((uint32_t) hstr) & (1 << crm); 669 670 if (!trapToHype) { 671 switch (unflattenMiscReg(miscReg)) { 672 case MISCREG_SCTLR: 673 case MISCREG_TTBR0: 674 case MISCREG_TTBR1: 675 case MISCREG_TTBCR: 676 case MISCREG_DACR: 677 case MISCREG_DFSR: 678 case MISCREG_IFSR: 679 case MISCREG_DFAR: 680 case MISCREG_IFAR: 681 case MISCREG_ADFSR: 682 case MISCREG_AIFSR: 683 case MISCREG_PRRR: 684 case MISCREG_NMRR: 685 case MISCREG_MAIR0: 686 case MISCREG_MAIR1: 687 case MISCREG_CONTEXTIDR: 688 trapToHype = hcr.tvm & !isRead; 689 break; 690 // No default action needed 691 default: 692 break; 693 } 694 } 695 } 696 return trapToHype; 697} 698 699bool 700decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int ®Idx, 701 CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity) 702{ 703 OperatingMode mode = MODE_UNDEFINED; 704 bool ok = true; 705 706 // R mostly indicates if its a int register or a misc reg, we override 707 // below if the few corner cases 708 isIntReg = !r; 709 // Loosely based on ARM ARM issue C section B9.3.10 710 if (r) { 711 switch (sysM) 712 { 713 case 0xE: 714 regIdx = MISCREG_SPSR_FIQ; 715 mode = MODE_FIQ; 716 break; 717 case 0x10: 718 regIdx = MISCREG_SPSR_IRQ; 719 mode = MODE_IRQ; 720 break; 721 case 0x12: 722 regIdx = MISCREG_SPSR_SVC; 723 mode = MODE_SVC; 724 break; 725 case 0x14: 726 regIdx = MISCREG_SPSR_ABT; 727 mode = MODE_ABORT; 728 break; 729 case 0x16: 730 regIdx = MISCREG_SPSR_UND; 731 mode = MODE_UNDEFINED; 732 break; 733 case 0x1C: 734 regIdx = MISCREG_SPSR_MON; 735 mode = MODE_MON; 736 break; 737 case 0x1E: 738 regIdx = MISCREG_SPSR_HYP; 739 mode = MODE_HYP; 740 break; 741 default: 742 ok = false; 743 break; 744 } 745 } else { 746 int sysM4To3 = bits(sysM, 4, 3); 747 748 if (sysM4To3 == 0) { 749 mode = MODE_USER; 750 regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8); 751 } else if (sysM4To3 == 1) { 752 mode = MODE_FIQ; 753 regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8); 754 } else if (sysM4To3 == 3) { 755 if (bits(sysM, 1) == 0) { 756 mode = MODE_MON; 757 regIdx = intRegInMode(mode, 14 - bits(sysM, 0)); 758 } else { 759 mode = MODE_HYP; 760 if (bits(sysM, 0) == 1) { 761 regIdx = intRegInMode(mode, 13); // R13 in HYP 762 } else { 763 isIntReg = false; 764 regIdx = MISCREG_ELR_HYP; 765 } 766 } 767 } else { // Other Banked registers 768 int sysM2 = bits(sysM, 2); 769 int sysM1 = bits(sysM, 1); 770 771 mode = (OperatingMode) ( ((sysM2 || sysM1) << 0) | 772 (1 << 1) | 773 ((sysM2 && !sysM1) << 2) | 774 ((sysM2 && sysM1) << 3) | 775 (1 << 4) ); 776 regIdx = intRegInMode(mode, 14 - bits(sysM, 0)); 777 // Don't flatten the register here. This is going to go through 778 // setIntReg() which will do the flattening 779 ok &= mode != cpsr.mode; 780 } 781 } 782 783 // Check that the requested register is accessable from the current mode 784 if (ok && checkSecurity && mode != cpsr.mode) { 785 switch (cpsr.mode) 786 { 787 case MODE_USER: 788 ok = false; 789 break; 790 case MODE_FIQ: 791 ok &= mode != MODE_HYP; 792 ok &= (mode != MODE_MON) || !scr.ns; 793 break; 794 case MODE_HYP: 795 ok &= mode != MODE_MON; 796 ok &= (mode != MODE_FIQ) || !nsacr.rfr; 797 break; 798 case MODE_IRQ: 799 case MODE_SVC: 800 case MODE_ABORT: 801 case MODE_UNDEFINED: 802 case MODE_SYSTEM: 803 ok &= mode != MODE_HYP; 804 ok &= (mode != MODE_MON) || !scr.ns; 805 ok &= (mode != MODE_FIQ) || !nsacr.rfr; 806 break; 807 // can access everything, no further checks required 808 case MODE_MON: 809 break; 810 default: 811 panic("unknown Mode 0x%x\n", cpsr.mode); 812 break; 813 } 814 } 815 return (ok); 816} 817 818bool 819SPAlignmentCheckEnabled(ThreadContext* tc) 820{ 821 switch (currEL(tc)) { 822 case EL3: 823 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).sa; 824 case EL2: 825 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).sa; 826 case EL1: 827 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa; 828 case EL0: 829 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa0; 830 default: 831 panic("Invalid exception level"); 832 break; 833 } 834} 835 836int 837decodePhysAddrRange64(uint8_t pa_enc) 838{ 839 switch (pa_enc) { 840 case 0x0: 841 return 32; 842 case 0x1: 843 return 36; 844 case 0x2: 845 return 40; 846 case 0x3: 847 return 42; 848 case 0x4: 849 return 44; 850 case 0x5: 851 case 0x6: 852 case 0x7: 853 return 48; 854 default: 855 panic("Invalid phys. address range encoding"); 856 } 857} 858 859uint8_t 860encodePhysAddrRange64(int pa_size) 861{ 862 switch (pa_size) { 863 case 32: 864 return 0x0; 865 case 36: 866 return 0x1; 867 case 40: 868 return 0x2; 869 case 42: 870 return 0x3; 871 case 44: 872 return 0x4; 873 case 48: 874 return 0x5; 875 default: 876 panic("Invalid phys. address range"); 877 } 878} 879 880} // namespace ArmISA 881