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