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