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