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