gem5 v24.1.0.1
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
faults.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010, 2012-2014, 2016-2019, 2022, 2024 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 * Copyright (c) 2003-2005 The Regents of The University of Michigan
15 * Copyright (c) 2007-2008 The Florida State University
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#include "arch/arm/faults.hh"
43
46#include "arch/arm/isa.hh"
49#include "arch/arm/system.hh"
50#include "arch/arm/utility.hh"
51#include "base/compiler.hh"
52#include "base/trace.hh"
53#include "cpu/base.hh"
54#include "cpu/thread_context.hh"
55#include "debug/Faults.hh"
56#include "sim/full_system.hh"
57
58namespace gem5
59{
60
61namespace ArmISA
62{
63
64const uint32_t HighVecs = 0xFFFF0000;
65
67 0x01, // AlignmentFault
68 0x04, // InstructionCacheMaintenance
69 0xff, // SynchExtAbtOnTranslTableWalkL0 (INVALID)
70 0x0c, // SynchExtAbtOnTranslTableWalkL1
71 0x0e, // SynchExtAbtOnTranslTableWalkL2
72 0xff, // SynchExtAbtOnTranslTableWalkL3 (INVALID)
73 0xff, // SynchPtyErrOnTranslTableWalkL0 (INVALID)
74 0x1c, // SynchPtyErrOnTranslTableWalkL1
75 0x1e, // SynchPtyErrOnTranslTableWalkL2
76 0xff, // SynchPtyErrOnTranslTableWalkL3 (INVALID)
77 0xff, // TranslationL0 (INVALID)
78 0x05, // TranslationL1
79 0x07, // TranslationL2
80 0xff, // TranslationL3 (INVALID)
81 0xff, // AccessFlagL0 (INVALID)
82 0x03, // AccessFlagL1
83 0x06, // AccessFlagL2
84 0xff, // AccessFlagL3 (INVALID)
85 0xff, // DomainL0 (INVALID)
86 0x09, // DomainL1
87 0x0b, // DomainL2
88 0xff, // DomainL3 (INVALID)
89 0xff, // PermissionL0 (INVALID)
90 0x0d, // PermissionL1
91 0x0f, // PermissionL2
92 0xff, // PermissionL3 (INVALID)
93 0x02, // DebugEvent
94 0x08, // SynchronousExternalAbort
95 0x10, // TLBConflictAbort
96 0x19, // SynchPtyErrOnMemoryAccess
97 0x16, // AsynchronousExternalAbort
98 0x18, // AsynchPtyErrOnMemoryAccess
99 0xff, // AddressSizeL0 (INVALID)
100 0xff, // AddressSizeL1 (INVALID)
101 0xff, // AddressSizeL2 (INVALID)
102 0xff, // AddressSizeL3 (INVALID)
103 0x40, // PrefetchTLBMiss
104 0x80 // PrefetchUncacheable
105};
106
107static_assert(sizeof(ArmFault::shortDescFaultSources) ==
109 "Invalid size of ArmFault::shortDescFaultSources[]");
110
112 0x21, // AlignmentFault
113 0xff, // InstructionCacheMaintenance (INVALID)
114 0xff, // SynchExtAbtOnTranslTableWalkL0 (INVALID)
115 0x15, // SynchExtAbtOnTranslTableWalkL1
116 0x16, // SynchExtAbtOnTranslTableWalkL2
117 0x17, // SynchExtAbtOnTranslTableWalkL3
118 0xff, // SynchPtyErrOnTranslTableWalkL0 (INVALID)
119 0x1d, // SynchPtyErrOnTranslTableWalkL1
120 0x1e, // SynchPtyErrOnTranslTableWalkL2
121 0x1f, // SynchPtyErrOnTranslTableWalkL3
122 0xff, // TranslationL0 (INVALID)
123 0x05, // TranslationL1
124 0x06, // TranslationL2
125 0x07, // TranslationL3
126 0xff, // AccessFlagL0 (INVALID)
127 0x09, // AccessFlagL1
128 0x0a, // AccessFlagL2
129 0x0b, // AccessFlagL3
130 0xff, // DomainL0 (INVALID)
131 0x3d, // DomainL1
132 0x3e, // DomainL2
133 0xff, // DomainL3 (RESERVED)
134 0xff, // PermissionL0 (INVALID)
135 0x0d, // PermissionL1
136 0x0e, // PermissionL2
137 0x0f, // PermissionL3
138 0x22, // DebugEvent
139 0x10, // SynchronousExternalAbort
140 0x30, // TLBConflictAbort
141 0x18, // SynchPtyErrOnMemoryAccess
142 0x11, // AsynchronousExternalAbort
143 0x19, // AsynchPtyErrOnMemoryAccess
144 0xff, // AddressSizeL0 (INVALID)
145 0xff, // AddressSizeL1 (INVALID)
146 0xff, // AddressSizeL2 (INVALID)
147 0xff, // AddressSizeL3 (INVALID)
148 0x40, // PrefetchTLBMiss
149 0x80 // PrefetchUncacheable
150};
151
152static_assert(sizeof(ArmFault::longDescFaultSources) ==
154 "Invalid size of ArmFault::longDescFaultSources[]");
155
157 0x21, // AlignmentFault
158 0xff, // InstructionCacheMaintenance (INVALID)
159 0x14, // SynchExtAbtOnTranslTableWalkL0
160 0x15, // SynchExtAbtOnTranslTableWalkL1
161 0x16, // SynchExtAbtOnTranslTableWalkL2
162 0x17, // SynchExtAbtOnTranslTableWalkL3
163 0x1c, // SynchPtyErrOnTranslTableWalkL0
164 0x1d, // SynchPtyErrOnTranslTableWalkL1
165 0x1e, // SynchPtyErrOnTranslTableWalkL2
166 0x1f, // SynchPtyErrOnTranslTableWalkL3
167 0x04, // TranslationL0
168 0x05, // TranslationL1
169 0x06, // TranslationL2
170 0x07, // TranslationL3
171 0x08, // AccessFlagL0
172 0x09, // AccessFlagL1
173 0x0a, // AccessFlagL2
174 0x0b, // AccessFlagL3
175 // @todo: Section & Page Domain Fault in AArch64?
176 0xff, // DomainL0 (INVALID)
177 0xff, // DomainL1 (INVALID)
178 0xff, // DomainL2 (INVALID)
179 0xff, // DomainL3 (INVALID)
180 0x0c, // PermissionL0
181 0x0d, // PermissionL1
182 0x0e, // PermissionL2
183 0x0f, // PermissionL3
184 0x22, // DebugEvent
185 0x10, // SynchronousExternalAbort
186 0x30, // TLBConflictAbort
187 0x18, // SynchPtyErrOnMemoryAccess
188 0xff, // AsynchronousExternalAbort (INVALID)
189 0xff, // AsynchPtyErrOnMemoryAccess (INVALID)
190 0x00, // AddressSizeL0
191 0x01, // AddressSizeL1
192 0x02, // AddressSizeL2
193 0x03, // AddressSizeL3
194 0x40, // PrefetchTLBMiss
195 0x80 // PrefetchUncacheable
196};
197
198static_assert(sizeof(ArmFault::aarch64FaultSources) ==
200 "Invalid size of ArmFault::aarch64FaultSources[]");
201
202// Fields: name, offset, cur{ELT,ELH}Offset, lowerEL{64,32}Offset, next mode,
203// {ARM, Thumb, ARM_ELR, Thumb_ELR} PC offset, hyp trap,
204// {A, F} disable, class, stat
206 // Some dummy values (the reset vector has an IMPLEMENTATION DEFINED
207 // location in AArch64)
208 "Reset", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC,
209 0, 0, 0, 0, false, true, true, ExceptionClass::UNKNOWN
210);
212 "Undefined Instruction", 0x004, 0x000, 0x200, 0x400, 0x600, MODE_UNDEFINED,
213 4, 2, 0, 0, true, false, false, ExceptionClass::UNKNOWN
214);
216 "Supervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
217 4, 2, 4, 2, true, false, false, ExceptionClass::SVC_TO_HYP
218);
220 "Secure Monitor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_MON,
221 4, 4, 4, 4, false, true, true, ExceptionClass::SMC_TO_HYP
222);
224 "Hypervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_HYP,
225 4, 4, 4, 4, true, false, false, ExceptionClass::HVC
226);
228 "Prefetch Abort", 0x00C, 0x000, 0x200, 0x400, 0x600, MODE_ABORT,
229 4, 4, 0, 0, true, true, false, ExceptionClass::PREFETCH_ABORT_TO_HYP
230);
232 "Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600, MODE_ABORT,
233 8, 8, 0, 0, true, true, false, ExceptionClass::DATA_ABORT_TO_HYP
234);
236 "Virtual Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600, MODE_ABORT,
237 8, 8, 0, 0, true, true, false, ExceptionClass::INVALID
238);
240 // @todo: double check these values
241 "Hypervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_HYP,
242 0, 0, 0, 0, false, false, false, ExceptionClass::UNKNOWN
243);
245 "Secure Monitor Trap", 0x004, 0x000, 0x200, 0x400, 0x600, MODE_MON,
246 4, 2, 0, 0, false, false, false, ExceptionClass::UNKNOWN
247);
249 "IRQ", 0x018, 0x080, 0x280, 0x480, 0x680, MODE_IRQ,
250 4, 4, 0, 0, false, true, false, ExceptionClass::UNKNOWN
251);
253 "Virtual IRQ", 0x018, 0x080, 0x280, 0x480, 0x680, MODE_IRQ,
254 4, 4, 0, 0, false, true, false, ExceptionClass::INVALID
255);
257 "FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700, MODE_FIQ,
258 4, 4, 0, 0, false, true, true, ExceptionClass::UNKNOWN
259);
261 "Virtual FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700, MODE_FIQ,
262 4, 4, 0, 0, false, true, true, ExceptionClass::INVALID
263);
265 "Illegal Inst Set State Fault", 0x004, 0x000, 0x200, 0x400, 0x600, MODE_UNDEFINED,
266 4, 2, 0, 0, true, false, false, ExceptionClass::ILLEGAL_INST
269 // Some dummy values (SupervisorTrap is AArch64-only)
270 "Supervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
271 0, 0, 0, 0, false, false, false, ExceptionClass::UNKNOWN
272);
274 // Some dummy values (PCAlignmentFault is AArch64-only)
275 "PC Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
276 0, 0, 0, 0, true, false, false, ExceptionClass::PC_ALIGNMENT
277);
279 // Some dummy values (SPAlignmentFault is AArch64-only)
280 "SP Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
281 0, 0, 0, 0, true, false, false, ExceptionClass::STACK_PTR_ALIGNMENT
282);
284 // Some dummy values (SError is AArch64-only)
285 "SError", 0x000, 0x180, 0x380, 0x580, 0x780, MODE_SVC,
286 0, 0, 0, 0, false, true, true, ExceptionClass::SERROR
287);
289 // Some dummy values (SoftwareBreakpoint is AArch64-only)
290 "Software Breakpoint", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
291 0, 0, 0, 0, true, false, false, ExceptionClass::SOFTWARE_BREAKPOINT
292);
294 "Hardware Breakpoint", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
295 0, 0, 0, 0, true, false, false, ExceptionClass::HW_BREAKPOINT
296);
298 "Watchpoint", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
299 0, 0, 0, 0, true, false, false, ExceptionClass::WATCHPOINT
300);
302 "SoftwareStep", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
303 0, 0, 0, 0, true, false, false, ExceptionClass::SOFTWARE_STEP
304);
306 // Some dummy values
307 "ArmSev Flush", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC,
308 0, 0, 0, 0, false, true, true, ExceptionClass::UNKNOWN
309);
310
311Addr
313{
314 Addr base;
315
316 // Check for invalid modes
317 CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
318 assert(ArmSystem::haveEL(tc, EL3) || cpsr.mode != MODE_MON);
319 assert(ArmSystem::haveEL(tc, EL2) || cpsr.mode != MODE_HYP);
320
321 switch (cpsr.mode)
322 {
323 case MODE_MON:
325 break;
326 case MODE_HYP:
328 break;
329 default:
330 SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
331 if (sctlr.v) {
332 base = HighVecs;
333 } else {
334 base = ArmSystem::haveEL(tc, EL3) ?
335 tc->readMiscReg(MISCREG_VBAR) : 0;
336 }
337 break;
338 }
339
340 return base + offset(tc);
341}
342
343Addr
345{
346 Addr vbar;
347 switch (toEL) {
348 case EL3:
349 assert(ArmSystem::haveEL(tc, EL3));
350 vbar = tc->readMiscReg(MISCREG_VBAR_EL3);
351 break;
352 case EL2:
353 assert(ArmSystem::haveEL(tc, EL2));
354 vbar = tc->readMiscReg(MISCREG_VBAR_EL2);
355 break;
356 case EL1:
357 vbar = tc->readMiscReg(MISCREG_VBAR_EL1);
358 break;
359 default:
360 panic("Invalid target exception level");
361 break;
362 }
363 return vbar + offset64(tc);
364}
365
368{
369 switch (toEL) {
370 case EL1:
371 return MISCREG_ESR_EL1;
372 case EL2:
373 return MISCREG_ESR_EL2;
374 case EL3:
375 return MISCREG_ESR_EL3;
376 default:
377 panic("Invalid exception level");
378 break;
379 }
380}
381
382void
384{
385 ESR esr = 0;
386 uint32_t exc_class = (uint32_t) ec(tc);
387 uint32_t iss_val = iss();
388
389 assert(!from64 || ArmSystem::highestELIs64(tc));
390
391 esr.ec = exc_class;
392 esr.il = il(tc);
393
394 // Condition code valid for EC[5:4] nonzero
395 if (!from64 && ((bits(exc_class, 5, 4) == 0) &&
396 (bits(exc_class, 3, 0) != 0))) {
397
398 if (!machInst.thumb) {
399 ConditionCode cond_code = (ConditionCode) (uint32_t) machInst.condCode;
400 // If its on unconditional instruction report with a cond code of
401 // 0xE, ie the unconditional code
402 esr.cond_iss.cv = 1;
403 esr.cond_iss.cond = (cond_code == COND_UC) ? COND_AL : cond_code;
404 }
405 esr.cond_iss.iss = bits(iss_val, 19, 0);
406 } else {
407 esr.iss = iss_val;
408 }
409 tc->setMiscReg(syndrome_reg, esr);
410}
411
412void
414{
415 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
416
417 // Determine source exception level and mode
418 fromMode = (OperatingMode) (uint8_t) cpsr.mode;
420 if (opModeIs64(fromMode))
421 from64 = true;
422
423 // Determine target exception level (aarch64) or target execution
424 // mode (aarch32).
425 if (ArmSystem::haveEL(tc, EL3) && routeToMonitor(tc)) {
427 toEL = EL3;
428 } else if (ArmSystem::haveEL(tc, EL2) && routeToHyp(tc)) {
430 toEL = EL2;
431 hypRouted = true;
432 } else {
433 toMode = nextMode();
435 }
436
437 if (fromEL > toEL)
438 toEL = fromEL;
439
440 // Check for Set Priviledge Access Never, if PAN is supported
441 if (HaveExt(tc, ArmExtension::FEAT_PAN)) {
442 if (toEL == EL1) {
443 const SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1);
444 span = !sctlr.span;
445 }
446
447 const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
448 if (toEL == EL2 && hcr.e2h && hcr.tge) {
449 const SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR_EL2);
450 span = !sctlr.span;
451 }
452 }
453
454 to64 = ELIs64(tc, toEL);
455
456 // The fault specific informations have been updated; it is
457 // now possible to use them inside the fault.
458 faultUpdated = true;
459}
460
461void
463{
464 // Update fault state informations, like the starting mode (aarch32)
465 // or EL (aarch64) and the ending mode or EL.
466 // From the update function we are also evaluating if the fault must
467 // be handled in AArch64 mode (to64).
468 update(tc);
469
470 if (from64 != to64) {
471 // Switching modes, sync up versions of the vector register file.
472 if (from64) {
474 } else {
476 }
477 }
478
479 if (to64) {
480 // Invoke exception handler in AArch64 state
481 invoke64(tc, inst);
482 } else {
483 // Invoke exception handler in AArch32 state
484 invoke32(tc, inst);
485 }
486}
487
488void
490{
491 // ARMv7 (ARM ARM issue C B1.9)
492 bool have_security = ArmSystem::haveEL(tc, EL3);
493
495 if (!FullSystem)
496 return;
498 SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
500 CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR);
501 saved_cpsr.nz = tc->getReg(cc_reg::Nz);
502 saved_cpsr.c = tc->getReg(cc_reg::C);
503 saved_cpsr.v = tc->getReg(cc_reg::V);
504 saved_cpsr.ge = tc->getReg(cc_reg::Ge);
506 [[maybe_unused]] Addr cur_pc = tc->pcState().as<PCState>().pc();
507 ITSTATE it = tc->pcState().as<PCState>().itstate();
508 saved_cpsr.it2 = it.top6;
509 saved_cpsr.it1 = it.bottom2;
511 // if we have a valid instruction then use it to annotate this fault with
512 // extra information. This is used to generate the correct fault syndrome
513 // information
514 [[maybe_unused]] ArmStaticInst *arm_inst = instrAnnotate(inst);
515
516 // Ensure Secure state if initially in Monitor mode
517 if (have_security && saved_cpsr.mode == MODE_MON) {
519 if (scr.ns) {
520 scr.ns = 0;
522 }
523 }
524
525 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
526 cpsr.mode = toMode;
527
528 // some bits are set differently if we have been routed to hyp mode
529 if (cpsr.mode == MODE_HYP) {
530 SCTLR hsctlr = tc->readMiscReg(MISCREG_HSCTLR);
531 cpsr.t = hsctlr.te;
532 cpsr.e = hsctlr.ee;
533 if (!scr.ea) {cpsr.a = 1;}
534 if (!scr.fiq) {cpsr.f = 1;}
535 if (!scr.irq) {cpsr.i = 1;}
536 } else if (cpsr.mode == MODE_MON) {
537 // Special case handling when entering monitor mode
538 cpsr.t = sctlr.te;
539 cpsr.e = sctlr.ee;
540 cpsr.a = 1;
541 cpsr.f = 1;
542 cpsr.i = 1;
543 } else {
544 cpsr.t = sctlr.te;
545 cpsr.e = sctlr.ee;
546
547 // The *Disable functions are virtual and different per fault
548 cpsr.a = cpsr.a | abortDisable(tc);
549 cpsr.f = cpsr.f | fiqDisable(tc);
550 cpsr.i = 1;
551 }
552 cpsr.it1 = cpsr.it2 = 0;
553 cpsr.pan = span ? 1 : saved_cpsr.pan;
554 tc->setMiscReg(MISCREG_CPSR, cpsr);
555
556 // Make sure mailbox sets to one always
558
559 // Clear the exclusive monitor
561
562 if (cpsr.mode == MODE_HYP) {
563 tc->setMiscReg(MISCREG_ELR_HYP, cur_pc +
564 (saved_cpsr.t ? thumbPcOffset(true) : armPcOffset(true)));
565 } else {
566 tc->setReg(int_reg::Lr, cur_pc +
567 (saved_cpsr.t ? thumbPcOffset(false) : armPcOffset(false)));
568 }
569
570 switch (cpsr.mode) {
571 case MODE_FIQ:
572 tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr);
573 break;
574 case MODE_IRQ:
575 tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr);
576 break;
577 case MODE_SVC:
578 tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr);
579 break;
580 case MODE_MON:
581 assert(have_security);
582 tc->setMiscReg(MISCREG_SPSR_MON, saved_cpsr);
583 break;
584 case MODE_ABORT:
585 tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr);
586 break;
587 case MODE_UNDEFINED:
588 tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr);
589 if (ec(tc) != ExceptionClass::UNKNOWN)
591 break;
592 case MODE_HYP:
593 assert(ArmSystem::haveEL(tc, EL2));
594 tc->setMiscReg(MISCREG_SPSR_HYP, saved_cpsr);
596 break;
597 default:
598 panic("unknown Mode\n");
599 }
600
601 Addr new_pc = getVector(tc);
602 DPRINTF(Faults, "Invoking Fault:%s cpsr:%#x PC:%#x lr:%#x newVec: %#x "
603 "%s\n", name(), cpsr, cur_pc, tc->getReg(int_reg::Lr),
604 new_pc, arm_inst ? csprintf("inst: %#x", arm_inst->encoding()) :
605 std::string());
606 PCState pc(new_pc);
607 pc.thumb(cpsr.t);
608 pc.nextThumb(pc.thumb());
609 pc.aarch64(!cpsr.width);
610 pc.nextAArch64(!cpsr.width);
611 pc.illegalExec(false);
612 tc->pcState(pc);
613}
614
615void
617{
618 // Determine actual misc. register indices for ELR_ELx and SPSR_ELx
619 MiscRegIndex elr_idx, spsr_idx;
620 switch (toEL) {
621 case EL1:
622 elr_idx = MISCREG_ELR_EL1;
623 spsr_idx = MISCREG_SPSR_EL1;
624 break;
625 case EL2:
626 assert(ArmSystem::haveEL(tc, EL2));
627 elr_idx = MISCREG_ELR_EL2;
628 spsr_idx = MISCREG_SPSR_EL2;
629 break;
630 case EL3:
631 assert(ArmSystem::haveEL(tc, EL3));
632 elr_idx = MISCREG_ELR_EL3;
633 spsr_idx = MISCREG_SPSR_EL3;
634 break;
635 default:
636 panic("Invalid target exception level");
637 break;
638 }
639
640 // Save process state into SPSR_ELx
641 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
642 CPSR spsr = cpsr;
643 spsr.nz = tc->getReg(cc_reg::Nz);
644 spsr.c = tc->getReg(cc_reg::C);
645 spsr.v = tc->getReg(cc_reg::V);
646 spsr.ss = isResetSPSR() ? 0: cpsr.ss;
647 if (from64) {
648 // Force some bitfields to 0
649 spsr.q = 0;
650 spsr.it1 = 0;
651 spsr.ge = 0;
652 spsr.it2 = 0;
653 spsr.t = 0;
654 } else {
655 spsr.ge = tc->getReg(cc_reg::Ge);
656 ITSTATE it = tc->pcState().as<PCState>().itstate();
657 spsr.it2 = it.top6;
658 spsr.it1 = it.bottom2;
659 spsr.uao = 0;
660 }
661 tc->setMiscReg(spsr_idx, spsr);
662
663 // Save preferred return address into ELR_ELx
664 Addr curr_pc = tc->pcState().instAddr();
665 Addr ret_addr = curr_pc;
666 if (from64)
667 ret_addr += armPcElrOffset();
668 else
669 ret_addr += spsr.t ? thumbPcElrOffset() : armPcElrOffset();
670 tc->setMiscReg(elr_idx, ret_addr);
671
672 Addr vec_address = getVector64(tc);
673
674 // Update process state
675 OperatingMode64 mode = 0;
676 mode.spX = 1;
677 mode.el = toEL;
678 mode.width = 0;
679 cpsr.mode = mode;
680 cpsr.daif = 0xf;
681 cpsr.il = 0;
682 cpsr.ss = 0;
683 cpsr.pan = span ? 1 : spsr.pan;
684 cpsr.uao = 0;
685 tc->setMiscReg(MISCREG_CPSR, cpsr);
686
687 // If we have a valid instruction then use it to annotate this fault with
688 // extra information. This is used to generate the correct fault syndrome
689 // information
690 [[maybe_unused]] ArmStaticInst *arm_inst = instrAnnotate(inst);
691
692 // Set PC to start of exception handler
693 Addr new_pc = purifyTaggedAddr(vec_address, tc, toEL, true);
694 DPRINTF(Faults, "Invoking Fault (AArch64 target EL):%s cpsr:%#x PC:%#x "
695 "elr:%#x newVec: %#x %s\n", name(), cpsr, curr_pc, ret_addr,
696 new_pc, arm_inst ? csprintf("inst: %#x", arm_inst->encoding()) :
697 std::string());
698 PCState pc(new_pc);
699 pc.aarch64(!cpsr.width);
700 pc.nextAArch64(!cpsr.width);
701 pc.illegalExec(false);
702 pc.stepped(false);
703 tc->pcState(pc);
704
705 // Save exception syndrome
706 if ((nextMode() != MODE_IRQ) && (nextMode() != MODE_FIQ))
708}
709
712{
713 if (inst) {
714 auto arm_inst = static_cast<ArmStaticInst *>(inst.get());
715 arm_inst->annotateFault(this);
716 return arm_inst;
717 } else {
718 return nullptr;
719 }
720}
721
722Addr
724{
725 Addr base;
726
727 // Check for invalid modes
728 [[maybe_unused]] CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
729 assert(ArmSystem::haveEL(tc, EL3) || cpsr.mode != MODE_MON);
730 assert(ArmSystem::haveEL(tc, EL2) || cpsr.mode != MODE_HYP);
731
732 // RVBAR is aliased (implemented as) MVBAR in gem5, since the two
733 // are mutually exclusive; there is no need to check here for
734 // which register to use since they hold the same value
736
737 return base + offset(tc);
738}
739
740void
742{
743 if (FullSystem) {
744 tc->getCpuPtr()->clearInterrupts(tc->threadId());
745 tc->clearArchRegs();
746 }
747 if (!ArmSystem::highestELIs64(tc)) {
748 ArmFault::invoke(tc, inst);
750 getMPIDR(dynamic_cast<ArmSystem*>(tc->getSystemPtr()), tc));
751
752 // Unless we have SMC code to get us there, boot in HYP!
753 if (ArmSystem::haveEL(tc, EL2) &&
754 !ArmSystem::haveEL(tc, EL3)) {
755 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
756 cpsr.mode = MODE_HYP;
757 tc->setMiscReg(MISCREG_CPSR, cpsr);
758 }
759 } else {
760 // Advance the PC to the IMPLEMENTATION DEFINED reset value
762 pc.aarch64(true);
763 pc.nextAArch64(true);
764 tc->pcState(pc);
765 }
766}
767
768void
770{
771 if (FullSystem) {
772 ArmFault::invoke(tc, inst);
773 return;
774 }
775
776 // If the mnemonic isn't defined this has to be an unknown instruction.
777 assert(unknown || mnemonic != NULL);
778 auto arm_inst = static_cast<ArmStaticInst *>(inst.get());
779 if (disabled) {
780 panic("Attempted to execute disabled instruction "
781 "'%s' (inst 0x%08x)", mnemonic, arm_inst->encoding());
782 } else if (unknown) {
783 panic("Attempted to execute unknown instruction (inst 0x%08x)",
784 arm_inst->encoding());
785 } else {
786 panic("Attempted to execute unimplemented instruction "
787 "'%s' (inst 0x%08x)", mnemonic, arm_inst->encoding());
788 }
789}
790
791bool
793{
795 return fromEL == EL2 ||
796 (EL2Enabled(tc) && (fromEL == EL0) && hcr.tge);
797}
798
799uint32_t
801{
802
803 // If UndefinedInstruction is routed to hypervisor, iss field is 0.
804 if (hypRouted) {
805 return 0;
806 }
807
809 return issRaw;
810
811 uint32_t new_iss = 0;
812 uint32_t op0, op1, op2, CRn, CRm, Rt, dir;
813
814 dir = bits(machInst, 21, 21);
815 op0 = bits(machInst, 20, 19);
816 op1 = bits(machInst, 18, 16);
817 CRn = bits(machInst, 15, 12);
818 CRm = bits(machInst, 11, 8);
819 op2 = bits(machInst, 7, 5);
820 Rt = bits(machInst, 4, 0);
821
822 new_iss = op0 << 20 | op2 << 17 | op1 << 14 | CRn << 10 |
823 Rt << 5 | CRm << 1 | dir;
824
825 return new_iss;
826}
827
828void
830{
831 if (FullSystem) {
832 ArmFault::invoke(tc, inst);
833 return;
834 }
835
836 // Advance the PC since that won't happen automatically.
837 PCState pc = tc->pcState().as<PCState>();
838 assert(inst);
839 inst->advancePC(pc);
840 tc->pcState(pc);
841
842 // As of now, there isn't a 32 bit thumb version of this instruction.
843 assert(!machInst.bigThumb);
844 tc->getSystemPtr()->workload->syscall(tc);
845}
846
847bool
849{
851 return fromEL == EL2 ||
852 (EL2Enabled(tc) && fromEL == EL0 && hcr.tge);
853}
854
861
862uint32_t
864{
865 // Even if we have a 24 bit imm from an arm32 instruction then we only use
866 // the bottom 16 bits for the ISS value (it doesn't hurt for AArch64 SVC).
867 return issRaw & 0xFFFF;
868}
869
870uint32_t
872{
873 if (from64)
874 return bits(machInst, 20, 5);
875 return 0;
876}
877
880{
881 // If UndefinedInstruction is routed to hypervisor,
882 // HSR.EC field is 0.
883 if (hypRouted)
885 else
887}
888
889
891 ArmFaultVals<HypervisorCall>(mach_inst, _imm)
892{
893 bStep = true;
894}
895
896bool
898{
899 return from64 && fromEL == EL3;
900}
901
902bool
904{
905 return !from64 || fromEL != EL3;
906}
907
913
919
920template<class T>
923{
924 bool isHypTrap = false;
925
926 // Normally we just use the exception vector from the table at the top if
927 // this file, however if this exception has caused a transition to hype
928 // mode, and its an exception type that would only do this if it has been
929 // trapped then we use the hyp trap vector instead of the normal vector
930 if (vals.hypTrappable) {
931 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
932 if (cpsr.mode == MODE_HYP) {
933 CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP);
934 isHypTrap = spsr.mode != MODE_HYP;
935 }
936 }
937 return isHypTrap ? 0x14 : vals.offset;
938}
939
940template<class T>
943{
944 if (toEL == fromEL) {
945 if (opModeIsT(fromMode))
946 return vals.currELTOffset;
947 return vals.currELHOffset;
948 } else {
949 bool lower_32 = false;
950 if (toEL == EL3) {
951 if (EL2Enabled(tc))
952 lower_32 = ELIs32(tc, EL2);
953 else
954 lower_32 = ELIs32(tc, EL1);
955 } else if (ELIsInHost(tc, fromEL) && fromEL == EL0 && toEL == EL2) {
956 lower_32 = ELIs32(tc, EL0);
957 } else {
958 lower_32 = ELIs32(tc, static_cast<ExceptionLevel>(toEL - 1));
959 }
960
961 if (lower_32)
962 return vals.lowerEL32Offset;
963 return vals.lowerEL64Offset;
964 }
965}
966
967// void
968// SupervisorCall::setSyndrome64(ThreadContext *tc, MiscRegIndex esr_idx)
969// {
970// ESR esr = 0;
971// esr.ec = machInst.aarch64 ? SvcAArch64 : SvcAArch32;
972// esr.il = !machInst.thumb;
973// if (machInst.aarch64)
974// esr.imm16 = bits(machInst.instBits, 20, 5);
975// else if (machInst.thumb)
976// esr.imm16 = bits(machInst.instBits, 7, 0);
977// else
978// esr.imm16 = bits(machInst.instBits, 15, 0);
979// tc->setMiscReg(esr_idx, esr);
980// }
981
982void
984{
985 if (FullSystem) {
986 ArmFault::invoke(tc, inst);
987 return;
988 }
989}
990
996
997bool
999{
1000 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1001 return EL2Enabled(tc) && currEL(tc) <= EL1 && hcr.tge;
1002}
1003
1004uint32_t
1006{
1007 // If SupervisorTrap is routed to hypervisor, iss field is 0.
1008 if (hypRouted) {
1009 return 0;
1010 }
1011 return issRaw;
1012}
1013
1016{
1017 if (hypRouted)
1019 else
1021}
1022
1029
1030template<class T>
1031void
1033{
1035 tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0);
1036 }
1037 // Get effective fault source encoding
1038 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
1039
1040 // source must be determined BEFORE invoking generic routines which will
1041 // try to set hsr etc. and are based upon source!
1042 ArmFaultVals<T>::invoke(tc, inst);
1043
1044 if (!this->to64) { // AArch32
1045 FSR fsr = getFsr(tc);
1046 if (cpsr.mode == MODE_HYP) {
1047 tc->setMiscReg(T::HFarIndex, faultAddr);
1048 } else if (stage2) {
1049 tc->setMiscReg(MISCREG_HPFAR, (faultAddr >> 8) & ~0xf);
1050 tc->setMiscReg(T::HFarIndex, OVAddr);
1051 } else if (debugType > ArmFault::NODEBUG) {
1052 DBGDS32 Rext = tc->readMiscReg(MISCREG_DBGDSCRext);
1053 tc->setMiscReg(T::FarIndex, faultAddr);
1054 if (debugType == ArmFault::BRKPOINT){
1055 Rext.moe = 0x1;
1056 } else if (debugType == ArmFault::VECTORCATCH){
1057 Rext.moe = 0x5;
1058 } else if (debugType > ArmFault::VECTORCATCH) {
1059 Rext.moe = 0xa;
1060 fsr.cm = (debugType == ArmFault::WPOINT_CM)? 1 : 0;
1061 }
1062
1063 tc->setMiscReg(T::FsrIndex, fsr);
1064 tc->setMiscReg(MISCREG_DBGDSCRext, Rext);
1065
1066 } else {
1067 tc->setMiscReg(T::FsrIndex, fsr);
1068 tc->setMiscReg(T::FarIndex, faultAddr);
1069 }
1070 DPRINTF(Faults, "Abort Fault source=%#x fsr=%#x faultAddr=%#x\n",
1071 source, fsr, faultAddr);
1072 } else { // AArch64
1073 // Set the FAR register. Nothing else to do if we are in AArch64 state
1074 // because the syndrome register has already been set inside invoke64()
1075 if (stage2) {
1076 // stage 2 fault, set HPFAR_EL2 to the faulting IPA
1077 // and FAR_EL2 to the Original VA
1078 misc_regs::writeRegister<misc_regs::FarAccessor>(
1079 tc, OVAddr, this->toEL);
1080 tc->setMiscReg(MISCREG_HPFAR_EL2, bits(faultAddr, 47, 12) << 4);
1081
1082 DPRINTF(Faults, "Abort Fault (Stage 2) VA: 0x%x IPA: 0x%x\n",
1083 OVAddr, faultAddr);
1084 } else {
1085 misc_regs::writeRegister<misc_regs::FarAccessor>(
1086 tc, faultAddr, this->toEL);
1087 }
1088 }
1089}
1090
1091template<class T>
1092void
1094{
1095 if (tranMethod == TranMethod::UnknownTran) {
1096 tranMethod = longDescFormatInUse(tc) ? TranMethod::LpaeTran
1098
1099 if ((tranMethod == TranMethod::VmsaTran) && this->routeToMonitor(tc)) {
1100 // See ARM ARM B3-1416
1101 bool override_LPAE = false;
1102 TTBCR ttbcr_s = tc->readMiscReg(MISCREG_TTBCR_S);
1103 if (ttbcr_s.eae) {
1104 override_LPAE = true;
1105 } else {
1106 // Unimplemented code option, not seen in testing. May need
1107 // extension according to the manual exceprt above.
1108 DPRINTF(Faults, "Warning: Incomplete translation method "
1109 "override detected.\n");
1110 }
1111 if (override_LPAE)
1112 tranMethod = TranMethod::LpaeTran;
1113 }
1114 }
1115
1116 ArmFault::update(tc);
1117}
1118
1119template<class T>
1120void
1122{
1123 srcEncoded = getFaultStatusCode(tc);
1124 if (srcEncoded == ArmFault::FaultSourceInvalid) {
1125 panic("Invalid fault source\n");
1126 }
1127 ArmFault::setSyndrome(tc, syndrome_reg);
1128}
1129
1130template<class T>
1131uint8_t
1133{
1134
1135 panic_if(!this->faultUpdated,
1136 "Trying to use un-updated ArmFault internal variables\n");
1137
1138 uint8_t fsc = 0;
1139
1140 if (!this->to64) {
1141 // AArch32
1142 assert(tranMethod != TranMethod::UnknownTran);
1143 if (tranMethod == TranMethod::LpaeTran) {
1144 fsc = ArmFault::longDescFaultSources[source];
1145 } else {
1146 fsc = ArmFault::shortDescFaultSources[source];
1147 }
1148 } else {
1149 // AArch64
1150 fsc = ArmFault::aarch64FaultSources[source];
1151 }
1152
1153 return fsc;
1154}
1155
1156template<class T>
1157FSR
1159{
1160 FSR fsr = 0;
1161
1162 auto fsc = getFaultStatusCode(tc);
1163
1164 // AArch32
1165 assert(tranMethod != TranMethod::UnknownTran);
1166 if (tranMethod == TranMethod::LpaeTran) {
1167 fsr.status = fsc;
1168 fsr.lpae = 1;
1169 } else {
1170 fsr.fsLow = bits(fsc, 3, 0);
1171 fsr.fsHigh = bits(fsc, 4);
1172 fsr.domain = static_cast<uint8_t>(domain);
1173 }
1174
1175 fsr.wnr = (write ? 1 : 0);
1176 fsr.ext = 0;
1177
1178 return fsr;
1179}
1180
1181template<class T>
1182bool
1184{
1185 if (ArmSystem::haveEL(tc, EL3)) {
1186 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1187 return (!scr.ns || scr.aw);
1188 }
1189 return true;
1190}
1191
1192template<class T>
1193void
1195{
1196 switch (id)
1197 {
1198 case ArmFault::S1PTW:
1199 s1ptw = val;
1200 break;
1201 case ArmFault::OVA:
1202 OVAddr = val;
1203 break;
1204
1205 // Just ignore unknown ID's
1206 default:
1207 break;
1208 }
1209}
1210
1211template<class T>
1212bool
1214{
1215 // NOTE: Not relying on LL information being aligned to lowest bits here
1216 return
1217 (source == ArmFault::AlignmentFault) ||
1218 ((source >= ArmFault::TranslationLL) &&
1219 (source < ArmFault::TranslationLL + 4)) ||
1220 ((source >= ArmFault::AccessFlagLL) &&
1221 (source < ArmFault::AccessFlagLL + 4)) ||
1222 ((source >= ArmFault::DomainLL) &&
1223 (source < ArmFault::DomainLL + 4)) ||
1224 ((source >= ArmFault::PermissionLL) &&
1225 (source < ArmFault::PermissionLL + 4));
1226}
1227
1228template<class T>
1229bool
1238
1239template<class T>
1240bool
1242{
1243 va = (stage2 ? OVAddr : faultAddr);
1244 return true;
1245}
1246
1249{
1250 if (to64) {
1251 // AArch64
1252 if (toEL == fromEL)
1254 else
1256 } else {
1257 // AArch32
1258 // Abort faults have different EC codes depending on whether
1259 // the fault originated within HYP mode, or not. So override
1260 // the method and add the extra adjustment of the EC value.
1261
1263
1264 CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP);
1265 if (spsr.mode == MODE_HYP) {
1266 ec = ((ExceptionClass) (((uint32_t) ec) + 1));
1267 }
1268 return ec;
1269 }
1270}
1271
1272uint32_t
1274{
1275 ESR esr = 0;
1276 auto& iss = esr.instruction_abort_iss;
1277
1278 iss.ifsc = srcEncoded & 0x3F;
1279 iss.s1ptw = s1ptw;
1280
1281 return iss;
1282}
1283
1284bool
1286{
1287 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1288 return scr.ea && !isMMUFault();
1289}
1290
1291bool
1293{
1294 bool toHyp;
1295
1296 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1297 HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR);
1298
1299 toHyp = fromEL == EL2;
1300 toHyp |= ArmSystem::haveEL(tc, EL2) && !isSecure(tc) &&
1301 currEL(tc) <= EL1 && (hcr.tge || stage2 ||
1302 (source == DebugEvent && hdcr.tde));
1303 return toHyp;
1304}
1305
1308{
1309 if (to64) {
1310 // AArch64
1312 panic("Asynchronous External Abort should be handled with "
1313 "SystemErrors (SErrors)!");
1314 }
1315 if (toEL == fromEL)
1317 else
1319 } else {
1320 // AArch32
1321 // Abort faults have different EC codes depending on whether
1322 // the fault originated within HYP mode, or not. So override
1323 // the method and add the extra adjustment of the EC value.
1324
1326
1327 CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP);
1328 if (spsr.mode == MODE_HYP) {
1329 ec = ((ExceptionClass) (((uint32_t) ec) + 1));
1330 }
1331 return ec;
1332 }
1333}
1334
1335bool
1337{
1338 return !isv? true : AbortFault<DataAbort>::il(tc);
1339}
1340
1341bool
1343{
1344 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1345 return scr.ea && !isMMUFault();
1346}
1347
1348bool
1350{
1351 bool toHyp;
1352
1353 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1354 HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR);
1355
1356 bool amo = hcr.amo;
1357 if (hcr.tge == 1)
1358 amo = (!HaveExt(tc, ArmExtension::FEAT_VHE) || hcr.e2h == 0);
1359
1360 // if in Hyp mode then stay in Hyp mode
1361 toHyp = fromEL == EL2 ||
1362 (EL2Enabled(tc) && fromEL <= EL1
1363 && (hcr.tge || stage2 ||
1365 ((fromEL == EL0) && hcr.tge &&
1366 ((source == AlignmentFault) ||
1368 ((source == DebugEvent) && (hdcr.tde || hcr.tge))));
1369 return toHyp;
1370}
1371
1372uint32_t
1374{
1375 ESR esr = 0;
1376 auto& iss = esr.data_abort_iss;
1377
1378 iss.dfsc = srcEncoded & 0x3F;
1379 iss.wnr = write;
1380 iss.s1ptw = s1ptw;
1381 iss.cm = cm;
1382 iss.ea = isExternalAbort();
1383
1384 // ISS is valid if not caused by a stage 1 page table walk, and when taken
1385 // to AArch64 only when directed to EL2
1386 if (!s1ptw && stage2 && (!to64 || toEL == EL2)) {
1387 iss.isv = isv;
1388 if (isv) {
1389 iss.sas = sas;
1390 iss.sse = sse;
1391 iss.srt = srt;
1392 // AArch64 only. These assignments are safe on AArch32 as well
1393 // because these vars are initialized to false
1394 iss.sf = sf;
1395 iss.ar = ar;
1396 }
1397 }
1398 return iss;
1399}
1400
1401void
1403{
1405 switch (id)
1406 {
1407 case SAS:
1408 isv = true;
1409 sas = val;
1410 break;
1411 case SSE:
1412 isv = true;
1413 sse = val;
1414 break;
1415 case SRT:
1416 isv = true;
1417 srt = val;
1418 break;
1419 case SF:
1420 isv = true;
1421 sf = val;
1422 break;
1423 case AR:
1424 isv = true;
1425 ar = val;
1426 break;
1427 case CM:
1428 cm = val;
1429 break;
1430 case OFA:
1431 faultAddr = val;
1432 break;
1433 case WnR:
1434 write = val;
1435 break;
1436 // Just ignore unknown ID's
1437 default:
1438 break;
1439 }
1440}
1441
1442void
1444{
1446 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1447 hcr.va = 0;
1449}
1450
1451bool
1453{
1454 assert(ArmSystem::haveEL(tc, EL3));
1455 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1456 return scr.irq;
1457}
1458
1459bool
1461{
1462 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1463 return fromEL == EL2 ||
1464 (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || hcr.imo));
1465}
1466
1467bool
1469{
1470 if (ArmSystem::haveEL(tc, EL3)) {
1471 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1472 return (!scr.ns || scr.aw);
1473 }
1474 return true;
1475}
1476
1479
1480bool
1482{
1483 assert(ArmSystem::haveEL(tc, EL3));
1484 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1485 return scr.fiq;
1486}
1487
1488bool
1490{
1491 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1492 return fromEL == EL2 ||
1493 (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || hcr.fmo));
1494}
1495
1496bool
1498{
1499 if (ArmSystem::haveEL(tc, EL3)) {
1500 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1501 return (!scr.ns || scr.aw);
1502 }
1503 return true;
1504}
1505
1506bool
1508{
1509 if (ArmSystem::haveEL(tc, EL2)) {
1510 return true;
1511 } else if (ArmSystem::haveEL(tc, EL3)) {
1512 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1513 return (!scr.ns || scr.fw);
1514 }
1515 return true;
1516}
1517
1520
1521void
1523{
1525 assert(from64);
1526 // Set the FAR
1527 misc_regs::writeRegister<misc_regs::FarAccessor>(tc, faultPC, toEL);
1528}
1529
1530bool
1532{
1533 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1534 return fromEL == EL2 || (EL2Enabled(tc) && fromEL <= EL1 && hcr.tge);
1535}
1536
1539
1540bool
1542{
1543 assert(from64);
1544 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1545 return EL2Enabled(tc) && currEL(tc) <= EL1 && hcr.tge == 1;
1546}
1547
1550
1551void
1553{
1554 tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0);
1555 ArmFault::invoke(tc, inst);
1556}
1557
1558bool
1560{
1561 assert(ArmSystem::haveEL(tc, EL3));
1562 assert(from64);
1563 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1564 return scr.ea || fromEL == EL3;
1565}
1566
1567bool
1569{
1570 assert(from64);
1571
1572 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1573
1574 return fromEL == EL2 ||
1575 (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || hcr.amo));
1576}
1577
1578
1580 : ArmFaultVals<SoftwareBreakpoint>(mach_inst, _iss)
1581{}
1582
1583bool
1585{
1586 const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1587 const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
1588
1589 return fromEL == EL2 ||
1590 (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || mdcr.tde));
1591}
1592
1598
1602
1603bool
1605{
1606 const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1607 const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
1608
1609 return EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || mdcr.tde);
1610}
1611
1614{
1615 // AArch64
1616 if (toEL == fromEL)
1618 else
1620}
1621
1622void
1624{
1625
1627 MiscRegIndex elr_idx;
1628 switch (toEL) {
1629 case EL1:
1630 elr_idx = MISCREG_ELR_EL1;
1631 break;
1632 case EL2:
1633 assert(ArmSystem::haveEL(tc, EL2));
1634 elr_idx = MISCREG_ELR_EL2;
1635 break;
1636 case EL3:
1637 assert(ArmSystem::haveEL(tc, EL3));
1638 elr_idx = MISCREG_ELR_EL3;
1639 break;
1640 default:
1641 panic("Invalid target exception level");
1642 break;
1643 }
1644
1645 tc->setMiscReg(elr_idx, vAddr);
1646
1647}
1648
1650 bool _write, bool _cm)
1651 : ArmFaultVals<Watchpoint>(mach_inst), vAddr(_vaddr),
1652 write(_write), cm(_cm)
1653{}
1654
1655uint32_t
1657{
1658 ESR esr = 0;
1659 auto& iss = esr.watchpoint_iss;
1660 iss.dfsc = 0b100010;
1661 iss.cm = cm;
1662 iss.wnr = write;
1663 return iss;
1664}
1665
1666void
1668{
1670 // Set the FAR
1671 misc_regs::writeRegister<misc_regs::FarAccessor>(tc, vAddr, toEL);
1672}
1673
1674bool
1676{
1677 const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1678 const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
1679
1680 return fromEL == EL2 ||
1681 (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || mdcr.tde));
1682}
1683
1684void
1686{
1688 switch (id)
1689 {
1690 case OFA:
1691 vAddr = val;
1692 break;
1693 // Just ignore unknown ID's
1694 default:
1695 break;
1696 }
1697}
1698
1701{
1702 // AArch64
1703 if (toEL == fromEL)
1705 else
1707}
1708
1710 bool _stepped)
1711 : ArmFaultVals<SoftwareStepFault>(mach_inst), isldx(is_ldx),
1712 stepped(_stepped)
1713{
1714 bStep = true;
1715}
1716
1717bool
1719{
1720 const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1721 const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
1722
1723 return fromEL == EL2 ||
1724 (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || mdcr.tde));
1725}
1726
1729{
1730 // AArch64
1731 if (toEL == fromEL)
1733 else
1735}
1736
1737uint32_t
1739{
1740 ESR esr = 0;
1741 auto& iss = esr.software_step_iss;
1742 iss.ifsc = 0b100010;
1743 iss.isv = stepped;
1744 iss.ex = isldx;
1745 return iss;
1746}
1747
1748void
1750{
1751 DPRINTF(Faults, "Invoking ArmSev Fault\n");
1752 if (!FullSystem)
1753 return;
1754
1755 // Set sev_mailbox to 1, clear the pending interrupt from remote
1756 // SEV execution and let pipeline continue as pcState is still
1757 // valid.
1759 tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_SEV, 0);
1760}
1761
1762// Instantiate all the templates to make the linker happy
1763template class ArmFaultVals<Reset>;
1765template class ArmFaultVals<SupervisorCall>;
1766template class ArmFaultVals<SecureMonitorCall>;
1767template class ArmFaultVals<HypervisorCall>;
1768template class ArmFaultVals<PrefetchAbort>;
1769template class ArmFaultVals<DataAbort>;
1770template class ArmFaultVals<VirtualDataAbort>;
1771template class ArmFaultVals<HypervisorTrap>;
1772template class ArmFaultVals<Interrupt>;
1773template class ArmFaultVals<VirtualInterrupt>;
1774template class ArmFaultVals<FastInterrupt>;
1776template class ArmFaultVals<SupervisorTrap>;
1777template class ArmFaultVals<SecureMonitorTrap>;
1778template class ArmFaultVals<PCAlignmentFault>;
1779template class ArmFaultVals<SPAlignmentFault>;
1780template class ArmFaultVals<SystemError>;
1783template class ArmFaultVals<Watchpoint>;
1784template class ArmFaultVals<SoftwareStepFault>;
1785template class ArmFaultVals<ArmSev>;
1786template class AbortFault<PrefetchAbort>;
1787template class AbortFault<DataAbort>;
1788template class AbortFault<VirtualDataAbort>;
1789
1790
1793
1794bool
1796{
1797 const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1798 return EL2Enabled(tc) && fromEL == EL0 && hcr.tge;
1799}
1800
1801bool
1803{
1804 auto arm_fault = dynamic_cast<ArmFault *>(fault.get());
1805
1806 if (arm_fault) {
1807 return arm_fault->getFaultVAddr(va);
1808 } else {
1809 auto pgt_fault = dynamic_cast<GenericPageTableFault *>(fault.get());
1810 if (pgt_fault) {
1811 va = pgt_fault->getFaultVAddr();
1812 return true;
1813 }
1814
1815 auto align_fault = dynamic_cast<GenericAlignmentFault *>(fault.get());
1816 if (align_fault) {
1817 va = align_fault->getFaultVAddr();
1818 return true;
1819 }
1820
1821 // Return false since it's not an address triggered exception
1822 return false;
1823 }
1824}
1825
1826} // namespace ArmISA
1827} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
Addr faultAddr
The virtual address the fault occured at.
Definition faults.hh:470
void setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg) override
Definition faults.cc:1121
uint8_t getFaultStatusCode(ThreadContext *tc) const
Definition faults.cc:1132
void update(ThreadContext *tc) override
Definition faults.cc:1093
void annotate(ArmFault::AnnotationIDs id, uint64_t val) override
Definition faults.cc:1194
bool abortDisable(ThreadContext *tc) override
Definition faults.cc:1183
bool getFaultVAddr(Addr &va) const override
Definition faults.cc:1241
bool isExternalAbort() const override
Definition faults.cc:1230
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:1032
FSR getFsr(ThreadContext *tc) const override
Definition faults.cc:1158
bool isMMUFault() const
Definition faults.cc:1213
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.hh:297
FaultOffset offset64(ThreadContext *tc) override
Definition faults.cc:942
static FaultVals vals
Definition faults.hh:259
FaultOffset offset(ThreadContext *tc) override
Definition faults.cc:922
ExceptionLevel toEL
Definition faults.hh:75
OperatingMode toMode
Definition faults.hh:77
virtual bool routeToMonitor(ThreadContext *tc) const =0
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:462
virtual uint32_t iss() const =0
static uint8_t shortDescFaultSources[NumFaultSources]
Encodings of the fault sources when the short-desc.
Definition faults.hh:125
virtual bool routeToHyp(ThreadContext *tc) const
Definition faults.hh:236
void invoke32(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition faults.cc:489
virtual uint8_t thumbPcOffset(bool is_hyp)=0
MiscRegIndex getSyndromeReg64() const
Definition faults.cc:367
virtual void annotate(AnnotationIDs id, uint64_t val)
Definition faults.hh:231
virtual Addr getVector(ThreadContext *tc)
Definition faults.cc:312
virtual bool il(ThreadContext *tc) const =0
ArmStaticInst * instrAnnotate(const StaticInstPtr &inst)
Definition faults.cc:711
virtual FaultOffset offset64(ThreadContext *tc)=0
virtual bool abortDisable(ThreadContext *tc)=0
virtual void update(ThreadContext *tc)
Definition faults.cc:413
static uint8_t longDescFaultSources[NumFaultSources]
Encodings of the fault sources when the long-desc.
Definition faults.hh:128
void invoke64(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition faults.cc:616
virtual uint8_t armPcOffset(bool is_hyp)=0
virtual uint8_t thumbPcElrOffset()=0
ExtMachInst machInst
Definition faults.hh:67
virtual bool fiqDisable(ThreadContext *tc)=0
virtual bool getFaultVAddr(Addr &va) const
Definition faults.hh:250
static uint8_t aarch64FaultSources[NumFaultSources]
Encodings of the fault sources in AArch64 state.
Definition faults.hh:130
ExceptionLevel fromEL
Definition faults.hh:74
virtual uint8_t armPcElrOffset()=0
virtual OperatingMode nextMode()=0
Addr getVector64(ThreadContext *tc)
Definition faults.cc:344
virtual void setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg)
Definition faults.cc:383
OperatingMode fromMode
Definition faults.hh:76
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:1749
virtual void annotateFault(ArmFault *fault)
MachInst encoding() const
Returns the real encoding of the instruction: the machInst field is in fact always 64 bit wide and co...
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1349
uint32_t iss() const override
Definition faults.cc:1373
void annotate(AnnotationIDs id, uint64_t val) override
Definition faults.cc:1402
bool il(ThreadContext *tc) const override
Definition faults.cc:1336
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1307
bool routeToMonitor(ThreadContext *tc) const override
Definition faults.cc:1342
bool fiqDisable(ThreadContext *tc) override
Definition faults.cc:1507
bool abortDisable(ThreadContext *tc) override
Definition faults.cc:1497
bool routeToMonitor(ThreadContext *tc) const override
Definition faults.cc:1481
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1489
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:1623
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1604
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1613
HardwareBreakpoint(Addr _vaddr, uint32_t _iss)
Definition faults.cc:1599
bool routeToMonitor(ThreadContext *tc) const override
Definition faults.cc:897
HypervisorCall(ExtMachInst mach_inst, uint32_t _imm)
Definition faults.cc:890
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:903
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:909
ExceptionClass overrideEc
Definition faults.hh:447
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:915
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1795
bool abortDisable(ThreadContext *tc) override
Definition faults.cc:1468
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1460
bool routeToMonitor(ThreadContext *tc) const override
Definition faults.cc:1452
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:1522
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1531
Addr faultPC
The unaligned value of the PC.
Definition faults.hh:626
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1248
uint32_t iss() const override
Definition faults.cc:1273
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1292
bool routeToMonitor(ThreadContext *tc) const override
Definition faults.cc:1285
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:741
Addr getVector(ThreadContext *tc) override
Definition faults.cc:723
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1541
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:992
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:983
uint32_t iss() const override
Definition faults.cc:871
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1024
Software Breakpoint (AArch64 only)
Definition faults.hh:665
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1584
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1594
SoftwareBreakpoint(ExtMachInst mach_inst, uint32_t _iss)
Definition faults.cc:1579
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1718
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1728
uint32_t iss() const override
Definition faults.cc:1738
SoftwareStepFault(ExtMachInst mach_inst, bool is_ldx, bool stepped)
Definition faults.cc:1709
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:829
ExceptionClass overrideEc
Definition faults.hh:355
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:848
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:856
uint32_t iss() const override
Definition faults.cc:863
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:998
ExceptionClass overrideEc
Definition faults.hh:397
uint32_t iss() const override
Definition faults.cc:1005
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1015
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:1552
bool routeToMonitor(ThreadContext *tc) const override
Definition faults.cc:1559
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1568
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:769
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:792
uint32_t iss() const override
Definition faults.cc:800
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:879
void invoke(ThreadContext *tc, const StaticInstPtr &inst) override
Definition faults.cc:1443
Watchpoint(ExtMachInst mach_inst, Addr vaddr, bool _write, bool _cm)
Definition faults.cc:1649
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1675
void annotate(AnnotationIDs id, uint64_t val) override
Definition faults.cc:1685
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1700
uint32_t iss() const override
Definition faults.cc:1656
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:1667
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8)
Definition system.hh:187
Addr resetAddr() const
Returns the reset address if the highest implemented exception level is 64 bits (ARMv8)
Definition system.hh:202
static bool haveEL(ThreadContext *tc, ArmISA::ExceptionLevel el)
Return true if the system implements a specific exception level.
Definition system.cc:132
void clearInterrupts(ThreadID tid)
Definition base.hh:273
void clearInterrupt(ThreadID tid, int int_num, int index)
Definition base.hh:267
virtual FaultName name() const =0
virtual void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition faults.cc:58
Addr getFaultVAddr() const
Definition faults.hh:137
Addr getFaultVAddr() const
Definition faults.hh:125
Target & as()
Definition pcstate.hh:73
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
Definition pcstate.hh:108
T * get() const
Directly access the pointer itself without taking a reference.
Definition refcnt.hh:227
virtual void advancePC(PCStateBase &pc_state) const =0
Workload * workload
OS kernel.
Definition system.hh:326
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
virtual RegVal getReg(const RegId &reg) const
virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val)=0
virtual System * getSystemPtr()=0
virtual void clearArchRegs()=0
virtual BaseCPU * getCpuPtr()=0
virtual void setReg(const RegId &reg, RegVal val)
virtual const PCStateBase & pcState() const =0
virtual int threadId() const =0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
virtual void syscall(ThreadContext *tc)
Definition workload.hh:113
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition bitfield.hh:79
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:214
constexpr RegId V
Definition cc.hh:96
constexpr RegId C
Definition cc.hh:95
constexpr RegId Ge
Definition cc.hh:97
constexpr RegId Nz
Definition cc.hh:94
constexpr auto & Lr
Definition int.hh:275
bool ELIs32(ThreadContext *tc, ExceptionLevel el)
Definition utility.cc:283
@ MODE_UNDEFINED
Definition types.hh:332
static bool opModeIsT(OperatingMode mode)
Definition types.hh:422
bool getFaultVAddr(Fault fault, Addr &va)
Returns true if the fault passed as a first argument was triggered by a memory access,...
Definition faults.cc:1802
void syncVecRegsToElems(ThreadContext *tc)
Definition utility.cc:1335
bool ELIsInHost(ThreadContext *tc, ExceptionLevel el)
Returns true if the current exception level el is executing a Host OS or an application of a Host OS ...
Definition utility.cc:291
Bitfield< 4, 0 > mode
Definition misc_types.hh:74
ExceptionLevel currEL(const ThreadContext *tc)
Returns the current Exception Level (EL) of the provided ThreadContext.
Definition utility.cc:134
const uint32_t HighVecs
Definition faults.cc:64
bool isSecure(ThreadContext *tc)
Definition utility.cc:74
bool longDescFormatInUse(ThreadContext *tc)
Definition utility.cc:141
Bitfield< 20 > il
Definition misc_types.hh:61
Bitfield< 23, 0 > offset
Definition types.hh:144
Bitfield< 7, 4 > domain
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
Definition utility.cc:277
ConditionCode
Definition cc.hh:104
@ COND_UC
Definition cc.hh:120
@ COND_AL
Definition cc.hh:119
bool EL2Enabled(ThreadContext *tc)
Definition utility.cc:268
Bitfield< 55, 48 > itstate
Definition types.hh:70
Bitfield< 7 > s1ptw
@ MISCREG_SCTLR_EL2
Definition misc.hh:616
@ MISCREG_SPSR_HYP
Definition misc.hh:86
@ MISCREG_VBAR_EL3
Definition misc.hh:826
@ MISCREG_SPSR_EL2
Definition misc.hh:663
@ MISCREG_LOCKFLAG
Definition misc.hh:101
@ MISCREG_SCTLR
Definition misc.hh:253
@ MISCREG_SCR_EL3
Definition misc.hh:628
@ MISCREG_SPSR_SVC
Definition misc.hh:83
@ MISCREG_DBGDSCRext
Definition misc.hh:121
@ MISCREG_HDCR
Definition misc.hh:268
@ MISCREG_ESR_EL1
Definition misc.hh:677
@ MISCREG_VMPIDR
Definition misc.hh:252
@ MISCREG_SPSR_UND
Definition misc.hh:87
@ MISCREG_SPSR_IRQ
Definition misc.hh:82
@ MISCREG_SPSR_ABT
Definition misc.hh:85
@ MISCREG_SCTLR_EL1
Definition misc.hh:609
@ MISCREG_ELR_HYP
Definition misc.hh:88
@ MISCREG_CPSR
Definition misc.hh:79
@ MISCREG_SEV_MAILBOX
Definition misc.hh:109
@ MISCREG_ELR_EL2
Definition misc.hh:664
@ MISCREG_HPFAR
Definition misc.hh:309
@ MISCREG_SPSR_EL3
Definition misc.hh:670
@ MISCREG_ESR_EL3
Definition misc.hh:686
@ MISCREG_SPSR_EL1
Definition misc.hh:650
@ MISCREG_HCR_EL2
Definition misc.hh:619
@ MISCREG_ELR_EL3
Definition misc.hh:671
@ MISCREG_VBAR_EL2
Definition misc.hh:824
@ MISCREG_HPFAR_EL2
Definition misc.hh:690
@ MISCREG_MDCR_EL2
Definition misc.hh:621
@ MISCREG_VBAR
Definition misc.hh:421
@ MISCREG_VBAR_EL1
Definition misc.hh:820
@ MISCREG_HVBAR
Definition misc.hh:427
@ MISCREG_ELR_EL1
Definition misc.hh:652
@ MISCREG_SPSR_MON
Definition misc.hh:84
@ MISCREG_HSCTLR
Definition misc.hh:264
@ MISCREG_TTBCR_S
Definition misc.hh:280
@ MISCREG_HSR
Definition misc.hh:300
@ MISCREG_MVBAR
Definition misc.hh:424
@ MISCREG_ESR_EL2
Definition misc.hh:682
@ MISCREG_SPSR_FIQ
Definition misc.hh:81
RegVal getMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
This helper function is returning the value of MPIDR_EL1.
Definition utility.cc:174
void syncVecElemsToRegs(ThreadContext *tc)
Definition utility.cc:1347
static ExceptionLevel opModeToEL(OperatingMode mode)
Definition types.hh:429
Bitfield< 13 > cm
Bitfield< 5 > amo
bool HaveExt(ThreadContext *tc, ArmExtension ext)
Returns true if the provided ThreadContext supports the ArmExtension passed as a second argument.
Definition utility.cc:232
Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, TCR tcr, bool is_instr)
Removes the tag from tagged addresses if that mode is enabled.
Definition utility.cc:474
Addr FaultOffset
Definition faults.hh:60
Bitfield< 8 > va
Bitfield< 4 > pc
GenericISA::DelaySlotPCState< 4 > PCState
Definition pcstate.hh:40
Bitfield< 51, 12 > base
Definition pagetable.hh:141
Bitfield< 63 > val
Definition misc.hh:804
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
std::shared_ptr< FaultBase > Fault
Definition types.hh:249
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition root.cc:220
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
Overload hash function for BasicBlockRange type.
Definition binary32.hh:81
const ExceptionClass ec
Definition faults.hh:189

Generated on Mon Jan 13 2025 04:28:21 for gem5 by doxygen 1.9.8