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