utility.cc (9920:028e4da64b42) utility.cc (10037:5cac77888310)
1/*
1/*
2 * Copyright (c) 2009-2012 ARM Limited
2 * Copyright (c) 2009-2013 ARM Limited
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated

--- 24 unchanged lines hidden (view full) ---

35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Ali Saidi
38 */
39
40
41#include "arch/arm/faults.hh"
42#include "arch/arm/isa_traits.hh"
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated

--- 24 unchanged lines hidden (view full) ---

35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Ali Saidi
38 */
39
40
41#include "arch/arm/faults.hh"
42#include "arch/arm/isa_traits.hh"
43#include "arch/arm/system.hh"
43#include "arch/arm/tlb.hh"
44#include "arch/arm/utility.hh"
45#include "arch/arm/vtophys.hh"
46#include "cpu/checker/cpu.hh"
47#include "cpu/base.hh"
48#include "cpu/thread_context.hh"
49#include "mem/fs_translating_port_proxy.hh"
50#include "sim/full_system.hh"

--- 14 unchanged lines hidden (view full) ---

65uint64_t
66getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
67{
68 if (!FullSystem) {
69 panic("getArgument() only implemented for full system mode.\n");
70 M5_DUMMY_RETURN
71 }
72
44#include "arch/arm/tlb.hh"
45#include "arch/arm/utility.hh"
46#include "arch/arm/vtophys.hh"
47#include "cpu/checker/cpu.hh"
48#include "cpu/base.hh"
49#include "cpu/thread_context.hh"
50#include "mem/fs_translating_port_proxy.hh"
51#include "sim/full_system.hh"

--- 14 unchanged lines hidden (view full) ---

66uint64_t
67getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
68{
69 if (!FullSystem) {
70 panic("getArgument() only implemented for full system mode.\n");
71 M5_DUMMY_RETURN
72 }
73
73 if (size == (uint16_t)(-1))
74 size = ArmISA::MachineBytes;
75 if (fp)
76 panic("getArgument(): Floating point arguments not implemented\n");
77
74 if (fp)
75 panic("getArgument(): Floating point arguments not implemented\n");
76
78 if (number < NumArgumentRegs) {
79 // If the argument is 64 bits, it must be in an even regiser
80 // number. Increment the number here if it isn't even.
81 if (size == sizeof(uint64_t)) {
82 if ((number % 2) != 0)
83 number++;
84 // Read the two halves of the data. Number is inc here to
85 // get the second half of the 64 bit reg.
86 uint64_t tmp;
87 tmp = tc->readIntReg(number++);
88 tmp |= tc->readIntReg(number) << 32;
89 return tmp;
77 if (inAArch64(tc)) {
78 if (size == (uint16_t)(-1))
79 size = sizeof(uint64_t);
80
81 if (number < 8 /*NumArgumentRegs64*/) {
82 return tc->readIntReg(number);
90 } else {
83 } else {
91 return tc->readIntReg(number);
84 panic("getArgument(): No support reading stack args for AArch64\n");
92 }
93 } else {
85 }
86 } else {
94 Addr sp = tc->readIntReg(StackPointerReg);
95 FSTranslatingPortProxy &vp = tc->getVirtProxy();
96 uint64_t arg;
97 if (size == sizeof(uint64_t)) {
98 // If the argument is even it must be aligned
99 if ((number % 2) != 0)
100 number++;
101 arg = vp.read<uint64_t>(sp +
102 (number-NumArgumentRegs) * sizeof(uint32_t));
103 // since two 32 bit args == 1 64 bit arg, increment number
104 number++;
87 if (size == (uint16_t)(-1))
88 size = ArmISA::MachineBytes;
89
90 if (number < NumArgumentRegs) {
91 // If the argument is 64 bits, it must be in an even regiser
92 // number. Increment the number here if it isn't even.
93 if (size == sizeof(uint64_t)) {
94 if ((number % 2) != 0)
95 number++;
96 // Read the two halves of the data. Number is inc here to
97 // get the second half of the 64 bit reg.
98 uint64_t tmp;
99 tmp = tc->readIntReg(number++);
100 tmp |= tc->readIntReg(number) << 32;
101 return tmp;
102 } else {
103 return tc->readIntReg(number);
104 }
105 } else {
105 } else {
106 arg = vp.read<uint32_t>(sp +
107 (number-NumArgumentRegs) * sizeof(uint32_t));
106 Addr sp = tc->readIntReg(StackPointerReg);
107 FSTranslatingPortProxy &vp = tc->getVirtProxy();
108 uint64_t arg;
109 if (size == sizeof(uint64_t)) {
110 // If the argument is even it must be aligned
111 if ((number % 2) != 0)
112 number++;
113 arg = vp.read<uint64_t>(sp +
114 (number-NumArgumentRegs) * sizeof(uint32_t));
115 // since two 32 bit args == 1 64 bit arg, increment number
116 number++;
117 } else {
118 arg = vp.read<uint32_t>(sp +
119 (number-NumArgumentRegs) * sizeof(uint32_t));
120 }
121 return arg;
108 }
122 }
109 return arg;
110 }
123 }
124 panic("getArgument() should always return\n");
111}
112
113void
114skipFunction(ThreadContext *tc)
115{
116 PCState newPC = tc->pcState();
125}
126
127void
128skipFunction(ThreadContext *tc)
129{
130 PCState newPC = tc->pcState();
117 newPC.set(tc->readIntReg(ReturnAddressReg) & ~ULL(1));
131 if (inAArch64(tc)) {
132 newPC.set(tc->readIntReg(INTREG_X30));
133 } else {
134 newPC.set(tc->readIntReg(ReturnAddressReg) & ~ULL(1));
135 }
118
119 CheckerCPU *checker = tc->getCheckerCpuPtr();
120 if (checker) {
121 tc->pcStateNoRecord(newPC);
122 } else {
123 tc->pcState(newPC);
124 }
125}

--- 20 unchanged lines hidden (view full) ---

146 // Copy over the PC State
147 dest->pcState(src->pcState());
148
149 // Invalidate the tlb misc register cache
150 dest->getITBPtr()->invalidateMiscReg();
151 dest->getDTBPtr()->invalidateMiscReg();
152}
153
136
137 CheckerCPU *checker = tc->getCheckerCpuPtr();
138 if (checker) {
139 tc->pcStateNoRecord(newPC);
140 } else {
141 tc->pcState(newPC);
142 }
143}

--- 20 unchanged lines hidden (view full) ---

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