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