utility.cc revision 12494
1/* 2 * Copyright (c) 2009-2014, 2016-2017 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 FSTranslatingPortProxy &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 148void 149copyRegs(ThreadContext *src, ThreadContext *dest) 150{ 151 for (int i = 0; i < NumIntRegs; i++) 152 dest->setIntRegFlat(i, src->readIntRegFlat(i)); 153 154 for (int i = 0; i < NumFloatRegs; i++) 155 dest->setFloatRegFlat(i, src->readFloatRegFlat(i)); 156 157 for (int i = 0; i < NumVecRegs; i++) 158 dest->setVecRegFlat(i, src->readVecRegFlat(i)); 159 160 for (int i = 0; i < NumCCRegs; i++) 161 dest->setCCReg(i, src->readCCReg(i)); 162 163 for (int i = 0; i < NumMiscRegs; i++) 164 dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); 165 166 // setMiscReg "with effect" will set the misc register mapping correctly. 167 // e.g. updateRegMap(val) 168 dest->setMiscReg(MISCREG_CPSR, src->readMiscRegNoEffect(MISCREG_CPSR)); 169 170 // Copy over the PC State 171 dest->pcState(src->pcState()); 172 173 // Invalidate the tlb misc register cache 174 dynamic_cast<TLB *>(dest->getITBPtr())->invalidateMiscReg(); 175 dynamic_cast<TLB *>(dest->getDTBPtr())->invalidateMiscReg(); 176} 177 178bool 179inSecureState(ThreadContext *tc) 180{ 181 SCR scr = inAArch64(tc) ? tc->readMiscReg(MISCREG_SCR_EL3) : 182 tc->readMiscReg(MISCREG_SCR); 183 return ArmSystem::haveSecurity(tc) && inSecureState( 184 scr, tc->readMiscReg(MISCREG_CPSR)); 185} 186 187bool 188inAArch64(ThreadContext *tc) 189{ 190 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 191 return opModeIs64((OperatingMode) (uint8_t) cpsr.mode); 192} 193 194bool 195longDescFormatInUse(ThreadContext *tc) 196{ 197 TTBCR ttbcr = tc->readMiscReg(MISCREG_TTBCR); 198 return ArmSystem::haveLPAE(tc) && ttbcr.eae; 199} 200 201uint32_t 202getMPIDR(ArmSystem *arm_sys, ThreadContext *tc) 203{ 204 // Multiprocessor Affinity Register MPIDR from Cortex(tm)-A15 Technical 205 // Reference Manual 206 // 207 // bit 31 - Multi-processor extensions available 208 // bit 30 - Uni-processor system 209 // bit 24 - Multi-threaded cores 210 // bit 11-8 - Cluster ID 211 // bit 1-0 - CPU ID 212 // 213 // We deliberately extend both the Cluster ID and CPU ID fields to allow 214 // for simulation of larger systems 215 assert((0 <= tc->cpuId()) && (tc->cpuId() < 256)); 216 assert(tc->socketId() < 65536); 217 if (arm_sys->multiThread) { 218 return 0x80000000 | // multiprocessor extensions available 219 tc->contextId(); 220 } else if (arm_sys->multiProc) { 221 return 0x80000000 | // multiprocessor extensions available 222 tc->cpuId() | tc->socketId() << 8; 223 } else { 224 return 0x80000000 | // multiprocessor extensions available 225 0x40000000 | // in up system 226 tc->cpuId() | tc->socketId() << 8; 227 } 228} 229 230bool 231ELIs64(ThreadContext *tc, ExceptionLevel el) 232{ 233 return !ELIs32(tc, el); 234} 235 236bool 237ELIs32(ThreadContext *tc, ExceptionLevel el) 238{ 239 // Return true if the specified EL is in aarch32 state. 240 241 const bool have_el3 = ArmSystem::haveSecurity(tc); 242 const bool have_el2 = ArmSystem::haveVirtualization(tc); 243 244 panic_if(el == EL2 && !have_el2, "Asking for EL2 when it doesn't exist"); 245 panic_if(el == EL3 && !have_el3, "Asking for EL3 when it doesn't exist"); 246 247 if (ArmSystem::highestELIs64(tc) 248 && ArmSystem::highestEL(tc) == el) { 249 return false; 250 } else if (!ArmSystem::highestELIs64(tc)) { 251 // All levels are using AArch32 252 return true; 253 } else { 254 SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); 255 bool aarch32_below_el3 = (have_el3 && scr.rw == 0); 256 257 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); 258 bool aarch32_at_el1 = (aarch32_below_el3 259 || (have_el2 260 && !inSecureState(tc) && hcr.rw == 0)); 261 262 // Only know if EL0 using AArch32 from PSTATE 263 if (el == EL0 && !aarch32_at_el1) { 264 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); 265 panic_if(cpsr.el != EL0, "EL0 state is UNKNOWN"); 266 // EL0 controlled by PSTATE 267 return cpsr.width != 0; 268 } else { 269 return (aarch32_below_el3 && el != EL3) 270 || (aarch32_at_el1 && (el == EL0 || el == EL1) ); 271 } 272 } 273} 274 275bool 276isBigEndian64(ThreadContext *tc) 277{ 278 switch (opModeToEL(currOpMode(tc))) { 279 case EL3: 280 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).ee; 281 case EL2: 282 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).ee; 283 case EL1: 284 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).ee; 285 case EL0: 286 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).e0e; 287 default: 288 panic("Invalid exception level"); 289 break; 290 } 291} 292 293Addr 294purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, 295 TTBCR tcr) 296{ 297 switch (el) { 298 case EL0: 299 case EL1: 300 if (bits(addr, 55, 48) == 0xFF && tcr.tbi1) 301 return addr | mask(63, 55); 302 else if (!bits(addr, 55, 48) && tcr.tbi0) 303 return bits(addr,55, 0); 304 break; 305 case EL2: 306 assert(ArmSystem::haveVirtualization(tc)); 307 tcr = tc->readMiscReg(MISCREG_TCR_EL2); 308 if (tcr.tbi) 309 return addr & mask(56); 310 break; 311 case EL3: 312 assert(ArmSystem::haveSecurity(tc)); 313 if (tcr.tbi) 314 return addr & mask(56); 315 break; 316 default: 317 panic("Invalid exception level"); 318 break; 319 } 320 321 return addr; // Nothing to do if this is not a tagged address 322} 323 324Addr 325purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el) 326{ 327 TTBCR tcr; 328 329 switch (el) { 330 case EL0: 331 case EL1: 332 tcr = tc->readMiscReg(MISCREG_TCR_EL1); 333 if (bits(addr, 55, 48) == 0xFF && tcr.tbi1) 334 return addr | mask(63, 55); 335 else if (!bits(addr, 55, 48) && tcr.tbi0) 336 return bits(addr,55, 0); 337 break; 338 case EL2: 339 assert(ArmSystem::haveVirtualization(tc)); 340 tcr = tc->readMiscReg(MISCREG_TCR_EL2); 341 if (tcr.tbi) 342 return addr & mask(56); 343 break; 344 case EL3: 345 assert(ArmSystem::haveSecurity(tc)); 346 tcr = tc->readMiscReg(MISCREG_TCR_EL3); 347 if (tcr.tbi) 348 return addr & mask(56); 349 break; 350 default: 351 panic("Invalid exception level"); 352 break; 353 } 354 355 return addr; // Nothing to do if this is not a tagged address 356} 357 358Addr 359truncPage(Addr addr) 360{ 361 return addr & ~(PageBytes - 1); 362} 363 364Addr 365roundPage(Addr addr) 366{ 367 return (addr + PageBytes - 1) & ~(PageBytes - 1); 368} 369 370bool 371mcrMrc15TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr, 372 HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss) 373{ 374 bool isRead; 375 uint32_t crm; 376 IntRegIndex rt; 377 uint32_t crn; 378 uint32_t opc1; 379 uint32_t opc2; 380 bool trapToHype = false; 381 382 383 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { 384 mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2); 385 trapToHype = ((uint32_t) hstr) & (1 << crn); 386 trapToHype |= hdcr.tpm && (crn == 9) && (crm >= 12); 387 trapToHype |= hcr.tidcp && ( 388 ((crn == 9) && ((crm <= 2) || ((crm >= 5) && (crm <= 8)))) || 389 ((crn == 10) && ((crm <= 1) || (crm == 4) || (crm == 8))) || 390 ((crn == 11) && ((crm <= 8) || (crm == 15))) ); 391 392 if (!trapToHype) { 393 switch (unflattenMiscReg(miscReg)) { 394 case MISCREG_CPACR: 395 trapToHype = hcptr.tcpac; 396 break; 397 case MISCREG_REVIDR: 398 case MISCREG_TCMTR: 399 case MISCREG_TLBTR: 400 case MISCREG_AIDR: 401 trapToHype = hcr.tid1; 402 break; 403 case MISCREG_CTR: 404 case MISCREG_CCSIDR: 405 case MISCREG_CLIDR: 406 case MISCREG_CSSELR: 407 trapToHype = hcr.tid2; 408 break; 409 case MISCREG_ID_PFR0: 410 case MISCREG_ID_PFR1: 411 case MISCREG_ID_DFR0: 412 case MISCREG_ID_AFR0: 413 case MISCREG_ID_MMFR0: 414 case MISCREG_ID_MMFR1: 415 case MISCREG_ID_MMFR2: 416 case MISCREG_ID_MMFR3: 417 case MISCREG_ID_ISAR0: 418 case MISCREG_ID_ISAR1: 419 case MISCREG_ID_ISAR2: 420 case MISCREG_ID_ISAR3: 421 case MISCREG_ID_ISAR4: 422 case MISCREG_ID_ISAR5: 423 trapToHype = hcr.tid3; 424 break; 425 case MISCREG_DCISW: 426 case MISCREG_DCCSW: 427 case MISCREG_DCCISW: 428 trapToHype = hcr.tsw; 429 break; 430 case MISCREG_DCIMVAC: 431 case MISCREG_DCCIMVAC: 432 case MISCREG_DCCMVAC: 433 trapToHype = hcr.tpc; 434 break; 435 case MISCREG_ICIMVAU: 436 case MISCREG_ICIALLU: 437 case MISCREG_ICIALLUIS: 438 case MISCREG_DCCMVAU: 439 trapToHype = hcr.tpu; 440 break; 441 case MISCREG_TLBIALLIS: 442 case MISCREG_TLBIMVAIS: 443 case MISCREG_TLBIASIDIS: 444 case MISCREG_TLBIMVAAIS: 445 case MISCREG_DTLBIALL: 446 case MISCREG_ITLBIALL: 447 case MISCREG_DTLBIMVA: 448 case MISCREG_ITLBIMVA: 449 case MISCREG_DTLBIASID: 450 case MISCREG_ITLBIASID: 451 case MISCREG_TLBIMVAA: 452 case MISCREG_TLBIALL: 453 case MISCREG_TLBIMVA: 454 case MISCREG_TLBIASID: 455 trapToHype = hcr.ttlb; 456 break; 457 case MISCREG_ACTLR: 458 trapToHype = hcr.tac; 459 break; 460 case MISCREG_SCTLR: 461 case MISCREG_TTBR0: 462 case MISCREG_TTBR1: 463 case MISCREG_TTBCR: 464 case MISCREG_DACR: 465 case MISCREG_DFSR: 466 case MISCREG_IFSR: 467 case MISCREG_DFAR: 468 case MISCREG_IFAR: 469 case MISCREG_ADFSR: 470 case MISCREG_AIFSR: 471 case MISCREG_PRRR: 472 case MISCREG_NMRR: 473 case MISCREG_MAIR0: 474 case MISCREG_MAIR1: 475 case MISCREG_CONTEXTIDR: 476 trapToHype = hcr.tvm & !isRead; 477 break; 478 case MISCREG_PMCR: 479 trapToHype = hdcr.tpmcr; 480 break; 481 // No default action needed 482 default: 483 break; 484 } 485 } 486 } 487 return trapToHype; 488} 489 490 491bool 492mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr, 493 HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss) 494{ 495 bool isRead; 496 uint32_t crm; 497 IntRegIndex rt; 498 uint32_t crn; 499 uint32_t opc1; 500 uint32_t opc2; 501 bool trapToHype = false; 502 503 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { 504 mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2); 505 inform("trap check M:%x N:%x 1:%x 2:%x hdcr %x, hcptr %x, hstr %x\n", 506 crm, crn, opc1, opc2, hdcr, hcptr, hstr); 507 trapToHype = hdcr.tda && (opc1 == 0); 508 trapToHype |= hcptr.tta && (opc1 == 1); 509 if (!trapToHype) { 510 switch (unflattenMiscReg(miscReg)) { 511 case MISCREG_DBGOSLSR: 512 case MISCREG_DBGOSLAR: 513 case MISCREG_DBGOSDLR: 514 case MISCREG_DBGPRCR: 515 trapToHype = hdcr.tdosa; 516 break; 517 case MISCREG_DBGDRAR: 518 case MISCREG_DBGDSAR: 519 trapToHype = hdcr.tdra; 520 break; 521 case MISCREG_JIDR: 522 trapToHype = hcr.tid0; 523 break; 524 case MISCREG_JOSCR: 525 case MISCREG_JMCR: 526 trapToHype = hstr.tjdbx; 527 break; 528 case MISCREG_TEECR: 529 case MISCREG_TEEHBR: 530 trapToHype = hstr.ttee; 531 break; 532 // No default action needed 533 default: 534 break; 535 } 536 } 537 } 538 return trapToHype; 539} 540 541bool 542mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr, 543 HCR hcr, uint32_t iss) 544{ 545 uint32_t crm; 546 IntRegIndex rt; 547 uint32_t crn; 548 uint32_t opc1; 549 uint32_t opc2; 550 bool isRead; 551 bool trapToHype = false; 552 553 if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { 554 // This is technically the wrong function, but we can re-use it for 555 // the moment because we only need one field, which overlaps with the 556 // mcrmrc layout 557 mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2); 558 trapToHype = ((uint32_t) hstr) & (1 << crm); 559 560 if (!trapToHype) { 561 switch (unflattenMiscReg(miscReg)) { 562 case MISCREG_SCTLR: 563 case MISCREG_TTBR0: 564 case MISCREG_TTBR1: 565 case MISCREG_TTBCR: 566 case MISCREG_DACR: 567 case MISCREG_DFSR: 568 case MISCREG_IFSR: 569 case MISCREG_DFAR: 570 case MISCREG_IFAR: 571 case MISCREG_ADFSR: 572 case MISCREG_AIFSR: 573 case MISCREG_PRRR: 574 case MISCREG_NMRR: 575 case MISCREG_MAIR0: 576 case MISCREG_MAIR1: 577 case MISCREG_CONTEXTIDR: 578 trapToHype = hcr.tvm & !isRead; 579 break; 580 // No default action needed 581 default: 582 break; 583 } 584 } 585 } 586 return trapToHype; 587} 588 589bool 590msrMrs64TrapToSup(const MiscRegIndex miscReg, ExceptionLevel el, 591 CPACR cpacr /* CPACR_EL1 */) 592{ 593 bool trapToSup = false; 594 switch (miscReg) { 595 case MISCREG_FPCR: 596 case MISCREG_FPSR: 597 case MISCREG_FPEXC32_EL2: 598 if ((el == EL0 && cpacr.fpen != 0x3) || 599 (el == EL1 && !(cpacr.fpen & 0x1))) 600 trapToSup = true; 601 break; 602 default: 603 break; 604 } 605 return trapToSup; 606} 607 608bool 609msrMrs64TrapToHyp(const MiscRegIndex miscReg, 610 ExceptionLevel el, 611 bool isRead, 612 CPTR cptr /* CPTR_EL2 */, 613 HCR hcr /* HCR_EL2 */, 614 bool * isVfpNeon) 615{ 616 bool trapToHyp = false; 617 *isVfpNeon = false; 618 619 switch (miscReg) { 620 // FP/SIMD regs 621 case MISCREG_FPCR: 622 case MISCREG_FPSR: 623 case MISCREG_FPEXC32_EL2: 624 trapToHyp = cptr.tfp; 625 *isVfpNeon = true; 626 break; 627 // CPACR 628 case MISCREG_CPACR_EL1: 629 trapToHyp = cptr.tcpac && el == EL1; 630 break; 631 // Virtual memory control regs 632 case MISCREG_SCTLR_EL1: 633 case MISCREG_TTBR0_EL1: 634 case MISCREG_TTBR1_EL1: 635 case MISCREG_TCR_EL1: 636 case MISCREG_ESR_EL1: 637 case MISCREG_FAR_EL1: 638 case MISCREG_AFSR0_EL1: 639 case MISCREG_AFSR1_EL1: 640 case MISCREG_MAIR_EL1: 641 case MISCREG_AMAIR_EL1: 642 case MISCREG_CONTEXTIDR_EL1: 643 trapToHyp = ((hcr.trvm && isRead) || (hcr.tvm && !isRead)) 644 && el == EL1; 645 break; 646 // TLB maintenance instructions 647 case MISCREG_TLBI_VMALLE1: 648 case MISCREG_TLBI_VAE1_Xt: 649 case MISCREG_TLBI_ASIDE1_Xt: 650 case MISCREG_TLBI_VAAE1_Xt: 651 case MISCREG_TLBI_VALE1_Xt: 652 case MISCREG_TLBI_VAALE1_Xt: 653 case MISCREG_TLBI_VMALLE1IS: 654 case MISCREG_TLBI_VAE1IS_Xt: 655 case MISCREG_TLBI_ASIDE1IS_Xt: 656 case MISCREG_TLBI_VAAE1IS_Xt: 657 case MISCREG_TLBI_VALE1IS_Xt: 658 case MISCREG_TLBI_VAALE1IS_Xt: 659 trapToHyp = hcr.ttlb && el == EL1; 660 break; 661 // Cache maintenance instructions to the point of unification 662 case MISCREG_IC_IVAU_Xt: 663 case MISCREG_ICIALLU: 664 case MISCREG_ICIALLUIS: 665 case MISCREG_DC_CVAU_Xt: 666 trapToHyp = hcr.tpu && el <= EL1; 667 break; 668 // Data/Unified cache maintenance instructions to the point of coherency 669 case MISCREG_DC_IVAC_Xt: 670 case MISCREG_DC_CIVAC_Xt: 671 case MISCREG_DC_CVAC_Xt: 672 trapToHyp = hcr.tpc && el <= EL1; 673 break; 674 // Data/Unified cache maintenance instructions by set/way 675 case MISCREG_DC_ISW_Xt: 676 case MISCREG_DC_CSW_Xt: 677 case MISCREG_DC_CISW_Xt: 678 trapToHyp = hcr.tsw && el == EL1; 679 break; 680 // ACTLR 681 case MISCREG_ACTLR_EL1: 682 trapToHyp = hcr.tacr && el == EL1; 683 break; 684 685 // @todo: Trap implementation-dependent functionality based on 686 // hcr.tidcp 687 688 // ID regs, group 3 689 case MISCREG_ID_PFR0_EL1: 690 case MISCREG_ID_PFR1_EL1: 691 case MISCREG_ID_DFR0_EL1: 692 case MISCREG_ID_AFR0_EL1: 693 case MISCREG_ID_MMFR0_EL1: 694 case MISCREG_ID_MMFR1_EL1: 695 case MISCREG_ID_MMFR2_EL1: 696 case MISCREG_ID_MMFR3_EL1: 697 case MISCREG_ID_ISAR0_EL1: 698 case MISCREG_ID_ISAR1_EL1: 699 case MISCREG_ID_ISAR2_EL1: 700 case MISCREG_ID_ISAR3_EL1: 701 case MISCREG_ID_ISAR4_EL1: 702 case MISCREG_ID_ISAR5_EL1: 703 case MISCREG_MVFR0_EL1: 704 case MISCREG_MVFR1_EL1: 705 case MISCREG_MVFR2_EL1: 706 case MISCREG_ID_AA64PFR0_EL1: 707 case MISCREG_ID_AA64PFR1_EL1: 708 case MISCREG_ID_AA64DFR0_EL1: 709 case MISCREG_ID_AA64DFR1_EL1: 710 case MISCREG_ID_AA64ISAR0_EL1: 711 case MISCREG_ID_AA64ISAR1_EL1: 712 case MISCREG_ID_AA64MMFR0_EL1: 713 case MISCREG_ID_AA64MMFR1_EL1: 714 case MISCREG_ID_AA64AFR0_EL1: 715 case MISCREG_ID_AA64AFR1_EL1: 716 assert(isRead); 717 trapToHyp = hcr.tid3 && el == EL1; 718 break; 719 // ID regs, group 2 720 case MISCREG_CTR_EL0: 721 case MISCREG_CCSIDR_EL1: 722 case MISCREG_CLIDR_EL1: 723 case MISCREG_CSSELR_EL1: 724 trapToHyp = hcr.tid2 && el <= EL1; 725 break; 726 // ID regs, group 1 727 case MISCREG_AIDR_EL1: 728 case MISCREG_REVIDR_EL1: 729 assert(isRead); 730 trapToHyp = hcr.tid1 && el == EL1; 731 break; 732 default: 733 break; 734 } 735 return trapToHyp; 736} 737 738bool 739msrMrs64TrapToMon(const MiscRegIndex miscReg, CPTR cptr /* CPTR_EL3 */, 740 ExceptionLevel el, bool * isVfpNeon) 741{ 742 bool trapToMon = false; 743 *isVfpNeon = false; 744 745 switch (miscReg) { 746 // FP/SIMD regs 747 case MISCREG_FPCR: 748 case MISCREG_FPSR: 749 case MISCREG_FPEXC32_EL2: 750 trapToMon = cptr.tfp; 751 *isVfpNeon = true; 752 break; 753 // CPACR, CPTR 754 case MISCREG_CPACR_EL1: 755 if (el == EL1) { 756 trapToMon = cptr.tcpac; 757 } 758 break; 759 case MISCREG_CPTR_EL2: 760 if (el == EL2) { 761 trapToMon = cptr.tcpac; 762 } 763 break; 764 default: 765 break; 766 } 767 return trapToMon; 768} 769 770bool 771decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int ®Idx, 772 CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity) 773{ 774 OperatingMode mode = MODE_UNDEFINED; 775 bool ok = true; 776 777 // R mostly indicates if its a int register or a misc reg, we override 778 // below if the few corner cases 779 isIntReg = !r; 780 // Loosely based on ARM ARM issue C section B9.3.10 781 if (r) { 782 switch (sysM) 783 { 784 case 0xE: 785 regIdx = MISCREG_SPSR_FIQ; 786 mode = MODE_FIQ; 787 break; 788 case 0x10: 789 regIdx = MISCREG_SPSR_IRQ; 790 mode = MODE_IRQ; 791 break; 792 case 0x12: 793 regIdx = MISCREG_SPSR_SVC; 794 mode = MODE_SVC; 795 break; 796 case 0x14: 797 regIdx = MISCREG_SPSR_ABT; 798 mode = MODE_ABORT; 799 break; 800 case 0x16: 801 regIdx = MISCREG_SPSR_UND; 802 mode = MODE_UNDEFINED; 803 break; 804 case 0x1C: 805 regIdx = MISCREG_SPSR_MON; 806 mode = MODE_MON; 807 break; 808 case 0x1E: 809 regIdx = MISCREG_SPSR_HYP; 810 mode = MODE_HYP; 811 break; 812 default: 813 ok = false; 814 break; 815 } 816 } else { 817 int sysM4To3 = bits(sysM, 4, 3); 818 819 if (sysM4To3 == 0) { 820 mode = MODE_USER; 821 regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8); 822 } else if (sysM4To3 == 1) { 823 mode = MODE_FIQ; 824 regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8); 825 } else if (sysM4To3 == 3) { 826 if (bits(sysM, 1) == 0) { 827 mode = MODE_MON; 828 regIdx = intRegInMode(mode, 14 - bits(sysM, 0)); 829 } else { 830 mode = MODE_HYP; 831 if (bits(sysM, 0) == 1) { 832 regIdx = intRegInMode(mode, 13); // R13 in HYP 833 } else { 834 isIntReg = false; 835 regIdx = MISCREG_ELR_HYP; 836 } 837 } 838 } else { // Other Banked registers 839 int sysM2 = bits(sysM, 2); 840 int sysM1 = bits(sysM, 1); 841 842 mode = (OperatingMode) ( ((sysM2 || sysM1) << 0) | 843 (1 << 1) | 844 ((sysM2 && !sysM1) << 2) | 845 ((sysM2 && sysM1) << 3) | 846 (1 << 4) ); 847 regIdx = intRegInMode(mode, 14 - bits(sysM, 0)); 848 // Don't flatten the register here. This is going to go through 849 // setIntReg() which will do the flattening 850 ok &= mode != cpsr.mode; 851 } 852 } 853 854 // Check that the requested register is accessable from the current mode 855 if (ok && checkSecurity && mode != cpsr.mode) { 856 switch (cpsr.mode) 857 { 858 case MODE_USER: 859 ok = false; 860 break; 861 case MODE_FIQ: 862 ok &= mode != MODE_HYP; 863 ok &= (mode != MODE_MON) || !scr.ns; 864 break; 865 case MODE_HYP: 866 ok &= mode != MODE_MON; 867 ok &= (mode != MODE_FIQ) || !nsacr.rfr; 868 break; 869 case MODE_IRQ: 870 case MODE_SVC: 871 case MODE_ABORT: 872 case MODE_UNDEFINED: 873 case MODE_SYSTEM: 874 ok &= mode != MODE_HYP; 875 ok &= (mode != MODE_MON) || !scr.ns; 876 ok &= (mode != MODE_FIQ) || !nsacr.rfr; 877 break; 878 // can access everything, no further checks required 879 case MODE_MON: 880 break; 881 default: 882 panic("unknown Mode 0x%x\n", cpsr.mode); 883 break; 884 } 885 } 886 return (ok); 887} 888 889bool 890SPAlignmentCheckEnabled(ThreadContext* tc) 891{ 892 switch (opModeToEL(currOpMode(tc))) { 893 case EL3: 894 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).sa; 895 case EL2: 896 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).sa; 897 case EL1: 898 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa; 899 case EL0: 900 return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa0; 901 default: 902 panic("Invalid exception level"); 903 break; 904 } 905} 906 907int 908decodePhysAddrRange64(uint8_t pa_enc) 909{ 910 switch (pa_enc) { 911 case 0x0: 912 return 32; 913 case 0x1: 914 return 36; 915 case 0x2: 916 return 40; 917 case 0x3: 918 return 42; 919 case 0x4: 920 return 44; 921 case 0x5: 922 case 0x6: 923 case 0x7: 924 return 48; 925 default: 926 panic("Invalid phys. address range encoding"); 927 } 928} 929 930uint8_t 931encodePhysAddrRange64(int pa_size) 932{ 933 switch (pa_size) { 934 case 32: 935 return 0x0; 936 case 36: 937 return 0x1; 938 case 40: 939 return 0x2; 940 case 42: 941 return 0x3; 942 case 44: 943 return 0x4; 944 case 48: 945 return 0x5; 946 default: 947 panic("Invalid phys. address range"); 948 } 949} 950 951} // namespace ArmISA 952