gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
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 // Save exception syndrome
693 MiscRegIndex syndrome_index = getSyndromeReg64();
694 if ((nextMode() != MODE_IRQ) && (nextMode() != MODE_FIQ))
695 setSyndrome(tc, syndrome_index);
696
697 // Set PC to start of exception handler
698 Addr new_pc = purifyTaggedAddr(vec_address, tc, toEL, true);
699 DPRINTF(Faults, "Invoking Fault (AArch64 target EL):%s cpsr:%#x PC:%#x "
700 "elr:%#x esr_el%d: %#x %s\n", name(), cpsr, curr_pc, ret_addr,
701 toEL, tc->readMiscRegNoEffect(syndrome_index), arm_inst ?
702 csprintf("inst: %#x", arm_inst->encoding()) : std::string());
703 PCState pc(new_pc);
704 pc.aarch64(!cpsr.width);
705 pc.nextAArch64(!cpsr.width);
706 pc.illegalExec(false);
707 pc.stepped(false);
708 tc->pcState(pc);
709}
710
713{
714 if (inst) {
715 auto arm_inst = static_cast<ArmStaticInst *>(inst.get());
716 arm_inst->annotateFault(this);
717 return arm_inst;
718 } else {
719 return nullptr;
720 }
721}
722
723Addr
725{
726 Addr base;
727
728 // Check for invalid modes
729 [[maybe_unused]] CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
730 assert(ArmSystem::haveEL(tc, EL3) || cpsr.mode != MODE_MON);
731 assert(ArmSystem::haveEL(tc, EL2) || cpsr.mode != MODE_HYP);
732
733 // RVBAR is aliased (implemented as) MVBAR in gem5, since the two
734 // are mutually exclusive; there is no need to check here for
735 // which register to use since they hold the same value
737
738 return base + offset(tc);
739}
740
741void
743{
744 if (FullSystem) {
745 tc->getCpuPtr()->clearInterrupts(tc->threadId());
746 tc->clearArchRegs();
747 }
748 if (!ArmSystem::highestELIs64(tc)) {
749 ArmFault::invoke(tc, inst);
751 getMPIDR(dynamic_cast<ArmSystem*>(tc->getSystemPtr()), tc));
752
753 // Unless we have SMC code to get us there, boot in HYP!
754 if (ArmSystem::haveEL(tc, EL2) &&
755 !ArmSystem::haveEL(tc, EL3)) {
756 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
757 cpsr.mode = MODE_HYP;
758 tc->setMiscReg(MISCREG_CPSR, cpsr);
759 }
760 } else {
761 // Advance the PC to the IMPLEMENTATION DEFINED reset value
763 pc.aarch64(true);
764 pc.nextAArch64(true);
765 tc->pcState(pc);
766 }
767}
768
769void
771{
772 if (FullSystem) {
773 ArmFault::invoke(tc, inst);
774 return;
775 }
776
777 // If the mnemonic isn't defined this has to be an unknown instruction.
778 assert(unknown || mnemonic != NULL);
779 auto arm_inst = static_cast<ArmStaticInst *>(inst.get());
780 if (disabled) {
781 panic("Attempted to execute disabled instruction "
782 "'%s' (inst 0x%08x)", mnemonic, arm_inst->encoding());
783 } else if (unknown) {
784 panic("Attempted to execute unknown instruction (inst 0x%08x)",
785 arm_inst->encoding());
786 } else {
787 panic("Attempted to execute unimplemented instruction "
788 "'%s' (inst 0x%08x)", mnemonic, arm_inst->encoding());
789 }
790}
791
792bool
794{
796 return fromEL == EL2 ||
797 (EL2Enabled(tc) && (fromEL == EL0) && hcr.tge);
798}
799
800uint32_t
802{
803
804 // If UndefinedInstruction is routed to hypervisor, iss field is 0.
805 if (hypRouted) {
806 return 0;
807 }
808
810 return issRaw;
811
812 uint32_t new_iss = 0;
813 uint32_t op0, op1, op2, CRn, CRm, Rt, dir;
814
815 dir = bits(machInst, 21, 21);
816 op0 = bits(machInst, 20, 19);
817 op1 = bits(machInst, 18, 16);
818 CRn = bits(machInst, 15, 12);
819 CRm = bits(machInst, 11, 8);
820 op2 = bits(machInst, 7, 5);
821 Rt = bits(machInst, 4, 0);
822
823 new_iss = op0 << 20 | op2 << 17 | op1 << 14 | CRn << 10 |
824 Rt << 5 | CRm << 1 | dir;
825
826 return new_iss;
827}
828
829void
831{
832 if (FullSystem) {
833 ArmFault::invoke(tc, inst);
834 return;
835 }
836
837 // Advance the PC since that won't happen automatically.
838 PCState pc = tc->pcState().as<PCState>();
839 assert(inst);
840 inst->advancePC(pc);
841 tc->pcState(pc);
842
843 // As of now, there isn't a 32 bit thumb version of this instruction.
844 assert(!machInst.bigThumb);
845 tc->getSystemPtr()->workload->syscall(tc);
846}
847
848bool
850{
852 return fromEL == EL2 ||
853 (EL2Enabled(tc) && fromEL == EL0 && hcr.tge);
854}
855
862
863uint32_t
865{
866 // Even if we have a 24 bit imm from an arm32 instruction then we only use
867 // the bottom 16 bits for the ISS value (it doesn't hurt for AArch64 SVC).
868 return issRaw & 0xFFFF;
869}
870
871uint32_t
873{
874 if (from64)
875 return bits(machInst, 20, 5);
876 return 0;
877}
878
881{
882 // If UndefinedInstruction is routed to hypervisor,
883 // HSR.EC field is 0.
884 if (hypRouted)
886 else
888}
889
890
892 ArmFaultVals<HypervisorCall>(mach_inst, _imm)
893{
894 bStep = true;
895}
896
897bool
899{
900 return from64 && fromEL == EL3;
901}
902
903bool
905{
906 return !from64 || fromEL != EL3;
907}
908
911{
912 return from64 ? ExceptionClass::HVC_64 : vals.ec;
913}
914
920
921template<class T>
924{
925 bool isHypTrap = false;
926
927 // Normally we just use the exception vector from the table at the top if
928 // this file, however if this exception has caused a transition to hype
929 // mode, and its an exception type that would only do this if it has been
930 // trapped then we use the hyp trap vector instead of the normal vector
931 if (vals.hypTrappable) {
932 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
933 if (cpsr.mode == MODE_HYP) {
934 CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP);
935 isHypTrap = spsr.mode != MODE_HYP;
936 }
937 }
938 return isHypTrap ? 0x14 : vals.offset;
939}
940
941template<class T>
944{
945 if (toEL == fromEL) {
946 if (opModeIsT(fromMode))
947 return vals.currELTOffset;
948 return vals.currELHOffset;
949 } else {
950 bool lower_32 = false;
951 if (toEL == EL3) {
952 if (EL2Enabled(tc))
953 lower_32 = ELIs32(tc, EL2);
954 else
955 lower_32 = ELIs32(tc, EL1);
956 } else if (ELIsInHost(tc, fromEL) && fromEL == EL0 && toEL == EL2) {
957 lower_32 = ELIs32(tc, EL0);
958 } else {
959 lower_32 = ELIs32(tc, static_cast<ExceptionLevel>(toEL - 1));
960 }
961
962 if (lower_32)
963 return vals.lowerEL32Offset;
964 return vals.lowerEL64Offset;
965 }
966}
967
968// void
969// SupervisorCall::setSyndrome64(ThreadContext *tc, MiscRegIndex esr_idx)
970// {
971// ESR esr = 0;
972// esr.ec = machInst.aarch64 ? SvcAArch64 : SvcAArch32;
973// esr.il = !machInst.thumb;
974// if (machInst.aarch64)
975// esr.imm16 = bits(machInst.instBits, 20, 5);
976// else if (machInst.thumb)
977// esr.imm16 = bits(machInst.instBits, 7, 0);
978// else
979// esr.imm16 = bits(machInst.instBits, 15, 0);
980// tc->setMiscReg(esr_idx, esr);
981// }
982
983void
985{
986 if (FullSystem) {
987 ArmFault::invoke(tc, inst);
988 return;
989 }
990}
991
994{
995 return (from64 ? ExceptionClass::SMC_64 : vals.ec);
996}
997
998bool
1000{
1001 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1002 return EL2Enabled(tc) && currEL(tc) <= EL1 && hcr.tge;
1003}
1004
1005uint32_t
1007{
1008 // If SupervisorTrap is routed to hypervisor, iss field is 0.
1009 if (hypRouted) {
1010 return 0;
1011 }
1012 return issRaw;
1013}
1014
1017{
1018 if (hypRouted)
1020 else
1022}
1023
1030
1031template<class T>
1032void
1034{
1036 tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0);
1037 }
1038 // Get effective fault source encoding
1039 CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
1040
1041 // source must be determined BEFORE invoking generic routines which will
1042 // try to set hsr etc. and are based upon source!
1043 ArmFaultVals<T>::invoke(tc, inst);
1044
1045 if (!this->to64) { // AArch32
1046 FSR fsr = getFsr(tc);
1047 if (cpsr.mode == MODE_HYP) {
1048 tc->setMiscReg(T::HFarIndex, faultAddr);
1049 } else if (stage2) {
1050 tc->setMiscReg(MISCREG_HPFAR, (faultAddr >> 8) & ~0xf);
1051 tc->setMiscReg(T::HFarIndex, OVAddr);
1052 } else if (debugType > ArmFault::NODEBUG) {
1053 DBGDS32 Rext = tc->readMiscReg(MISCREG_DBGDSCRext);
1054 tc->setMiscReg(T::FarIndex, faultAddr);
1056 Rext.moe = 0x1;
1057 } else if (debugType == ArmFault::VECTORCATCH){
1058 Rext.moe = 0x5;
1059 } else if (debugType > ArmFault::VECTORCATCH) {
1060 Rext.moe = 0xa;
1061 fsr.cm = (debugType == ArmFault::WPOINT_CM)? 1 : 0;
1062 }
1063
1064 tc->setMiscReg(T::FsrIndex, fsr);
1065 tc->setMiscReg(MISCREG_DBGDSCRext, Rext);
1066
1067 } else {
1068 tc->setMiscReg(T::FsrIndex, fsr);
1069 tc->setMiscReg(T::FarIndex, faultAddr);
1070 }
1071 DPRINTF(Faults, "Abort Fault source=%#x fsr=%#x faultAddr=%#x\n",
1072 source, fsr, faultAddr);
1073 } else { // AArch64
1074 // Set the FAR register. Nothing else to do if we are in AArch64 state
1075 // because the syndrome register has already been set inside invoke64()
1076 if (stage2) {
1077 // stage 2 fault, set HPFAR_EL2 to the faulting IPA
1078 // and FAR_EL2 to the Original VA
1080 tc, OVAddr, this->toEL);
1081 tc->setMiscReg(MISCREG_HPFAR_EL2, bits(faultAddr, 47, 12) << 4);
1082
1083 DPRINTF(Faults, "Abort Fault (Stage 2) VA: 0x%x IPA: 0x%x\n",
1084 OVAddr, faultAddr);
1085 } else {
1087 tc, faultAddr, this->toEL);
1088 }
1089 }
1090}
1091
1092template<class T>
1093void
1095{
1099
1100 if ((tranMethod == TranMethod::VmsaTran) && this->routeToMonitor(tc)) {
1101 // See ARM ARM B3-1416
1102 bool override_LPAE = false;
1103 TTBCR ttbcr_s = tc->readMiscReg(MISCREG_TTBCR_S);
1104 if (ttbcr_s.eae) {
1105 override_LPAE = true;
1106 } else {
1107 // Unimplemented code option, not seen in testing. May need
1108 // extension according to the manual exceprt above.
1109 DPRINTF(Faults, "Warning: Incomplete translation method "
1110 "override detected.\n");
1111 }
1112 if (override_LPAE)
1114 }
1115 }
1116
1117 ArmFault::update(tc);
1118}
1119
1120template<class T>
1121void
1123{
1126 panic("Invalid fault source\n");
1127 }
1128 ArmFault::setSyndrome(tc, syndrome_reg);
1129}
1130
1131template<class T>
1132uint8_t
1134{
1135
1136 panic_if(!this->faultUpdated,
1137 "Trying to use un-updated ArmFault internal variables\n");
1138
1139 uint8_t fsc = 0;
1140
1141 if (!this->to64) {
1142 // AArch32
1146 } else {
1148 }
1149 } else {
1150 // AArch64
1152 }
1153
1154 return fsc;
1155}
1156
1157template<class T>
1158FSR
1160{
1161 FSR fsr = 0;
1162
1163 auto fsc = getFaultStatusCode(tc);
1164
1165 // AArch32
1168 fsr.status = fsc;
1169 fsr.lpae = 1;
1170 } else {
1171 fsr.fsLow = bits(fsc, 3, 0);
1172 fsr.fsHigh = bits(fsc, 4);
1173 fsr.domain = static_cast<uint8_t>(domain);
1174 }
1175
1176 fsr.wnr = (write ? 1 : 0);
1177 fsr.ext = 0;
1178
1179 return fsr;
1180}
1181
1182template<class T>
1183bool
1185{
1186 if (ArmSystem::haveEL(tc, EL3)) {
1187 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1188 return (!scr.ns || scr.aw);
1189 }
1190 return true;
1191}
1192
1193template<class T>
1194void
1196{
1197 switch (id)
1198 {
1199 case ArmFault::S1PTW:
1200 s1ptw = val;
1201 break;
1202 case ArmFault::OVA:
1203 OVAddr = val;
1204 break;
1205
1206 // Just ignore unknown ID's
1207 default:
1208 break;
1209 }
1210}
1211
1212template<class T>
1213bool
1215{
1216 // NOTE: Not relying on LL information being aligned to lowest bits here
1217 return
1222 (source < ArmFault::AccessFlagLL + 4)) ||
1223 ((source >= ArmFault::DomainLL) &&
1224 (source < ArmFault::DomainLL + 4)) ||
1227}
1228
1229template<class T>
1230bool
1239
1240template<class T>
1241bool
1243{
1244 va = (stage2 ? OVAddr : faultAddr);
1245 return true;
1246}
1247
1250{
1251 if (to64) {
1252 // AArch64
1253 if (toEL == fromEL)
1255 else
1257 } else {
1258 // AArch32
1259 // Abort faults have different EC codes depending on whether
1260 // the fault originated within HYP mode, or not. So override
1261 // the method and add the extra adjustment of the EC value.
1262
1264
1265 CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP);
1266 if (spsr.mode == MODE_HYP) {
1267 ec = ((ExceptionClass) (((uint32_t) ec) + 1));
1268 }
1269 return ec;
1270 }
1271}
1272
1273uint32_t
1275{
1276 ESR esr = 0;
1277 auto& iss = esr.instruction_abort_iss;
1278
1279 iss.ifsc = srcEncoded & 0x3F;
1280 iss.s1ptw = s1ptw;
1281
1282 return iss;
1283}
1284
1285bool
1287{
1288 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1289 return scr.ea && !isMMUFault();
1290}
1291
1292bool
1294{
1295 bool toHyp;
1296
1297 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1298 HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR);
1299
1300 toHyp = fromEL == EL2;
1301 toHyp |= ArmSystem::haveEL(tc, EL2) && !isSecure(tc) &&
1302 currEL(tc) <= EL1 && (hcr.tge || stage2 ||
1303 (source == DebugEvent && hdcr.tde));
1304 return toHyp;
1305}
1306
1309{
1310 if (to64) {
1311 // AArch64
1313 panic("Asynchronous External Abort should be handled with "
1314 "SystemErrors (SErrors)!");
1315 }
1316 if (toEL == fromEL)
1318 else
1320 } else {
1321 // AArch32
1322 // Abort faults have different EC codes depending on whether
1323 // the fault originated within HYP mode, or not. So override
1324 // the method and add the extra adjustment of the EC value.
1325
1327
1328 CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP);
1329 if (spsr.mode == MODE_HYP) {
1330 ec = ((ExceptionClass) (((uint32_t) ec) + 1));
1331 }
1332 return ec;
1333 }
1334}
1335
1336bool
1338{
1339 return !isv? true : AbortFault<DataAbort>::il(tc);
1340}
1341
1342bool
1344{
1345 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1346 return scr.ea && !isMMUFault();
1347}
1348
1349bool
1351{
1352 bool toHyp;
1353
1354 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1355 HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR);
1356
1357 bool amo = hcr.amo;
1358 if (hcr.tge == 1)
1359 amo = (!HaveExt(tc, ArmExtension::FEAT_VHE) || hcr.e2h == 0);
1360
1361 // if in Hyp mode then stay in Hyp mode
1362 toHyp = fromEL == EL2 ||
1363 (EL2Enabled(tc) && fromEL <= EL1
1364 && (hcr.tge || stage2 ||
1366 ((fromEL == EL0) && hcr.tge &&
1367 ((source == AlignmentFault) ||
1369 ((source == DebugEvent) && (hdcr.tde || hcr.tge))));
1370 return toHyp;
1371}
1372
1373uint32_t
1375{
1376 ESR esr = 0;
1377 auto& iss = esr.data_abort_iss;
1378
1379 iss.dfsc = srcEncoded & 0x3F;
1380 iss.wnr = write;
1381 iss.s1ptw = s1ptw;
1382 iss.cm = cm;
1383 iss.ea = isExternalAbort();
1384
1385 // ISS is valid if not caused by a stage 1 page table walk, and when taken
1386 // to AArch64 only when directed to EL2
1387 if (!s1ptw && stage2 && (!to64 || toEL == EL2)) {
1388 iss.isv = isv;
1389 if (isv) {
1390 iss.sas = sas;
1391 iss.sse = sse;
1392 iss.srt = srt;
1393 // AArch64 only. These assignments are safe on AArch32 as well
1394 // because these vars are initialized to false
1395 iss.sf = sf;
1396 iss.ar = ar;
1397 }
1398 }
1399 return iss;
1400}
1401
1402void
1404{
1406 switch (id)
1407 {
1408 case SAS:
1409 isv = true;
1410 sas = val;
1411 break;
1412 case SSE:
1413 isv = true;
1414 sse = val;
1415 break;
1416 case SRT:
1417 isv = true;
1418 srt = val;
1419 break;
1420 case SF:
1421 isv = true;
1422 sf = val;
1423 break;
1424 case AR:
1425 isv = true;
1426 ar = val;
1427 break;
1428 case CM:
1429 cm = val;
1430 break;
1431 case OFA:
1432 faultAddr = val;
1433 break;
1434 case WnR:
1435 write = val;
1436 break;
1437 // Just ignore unknown ID's
1438 default:
1439 break;
1440 }
1441}
1442
1443void
1445{
1447 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1448 hcr.va = 0;
1450}
1451
1452bool
1454{
1455 assert(ArmSystem::haveEL(tc, EL3));
1456 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1457 return scr.irq;
1458}
1459
1460bool
1462{
1463 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1464 return fromEL == EL2 ||
1465 (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || hcr.imo));
1466}
1467
1468bool
1470{
1471 if (ArmSystem::haveEL(tc, EL3)) {
1472 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1473 return (!scr.ns || scr.aw);
1474 }
1475 return true;
1476}
1477
1480
1481bool
1483{
1484 assert(ArmSystem::haveEL(tc, EL3));
1485 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1486 return scr.fiq;
1487}
1488
1489bool
1491{
1492 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1493 return fromEL == EL2 ||
1494 (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || hcr.fmo));
1495}
1496
1497bool
1499{
1500 if (ArmSystem::haveEL(tc, EL3)) {
1501 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1502 return (!scr.ns || scr.aw);
1503 }
1504 return true;
1505}
1506
1507bool
1509{
1510 if (ArmSystem::haveEL(tc, EL2)) {
1511 return true;
1512 } else if (ArmSystem::haveEL(tc, EL3)) {
1513 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1514 return (!scr.ns || scr.fw);
1515 }
1516 return true;
1517}
1518
1521
1522void
1530
1531bool
1533{
1534 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1535 return fromEL == EL2 || (EL2Enabled(tc) && fromEL <= EL1 && hcr.tge);
1536}
1537
1540
1541bool
1543{
1544 assert(from64);
1545 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1546 return EL2Enabled(tc) && currEL(tc) <= EL1 && hcr.tge == 1;
1547}
1548
1551
1552void
1554{
1555 tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0);
1556 ArmFault::invoke(tc, inst);
1557}
1558
1559bool
1561{
1562 assert(ArmSystem::haveEL(tc, EL3));
1563 assert(from64);
1564 SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1565 return scr.ea || fromEL == EL3;
1566}
1567
1568bool
1570{
1571 assert(from64);
1572
1573 HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1574
1575 return fromEL == EL2 ||
1576 (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || hcr.amo));
1577}
1578
1579
1581 : ArmFaultVals<SoftwareBreakpoint>(mach_inst, _iss)
1582{}
1583
1584bool
1586{
1587 const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1588 const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
1589
1590 return fromEL == EL2 ||
1591 (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || mdcr.tde));
1592}
1593
1599
1603
1604bool
1606{
1607 const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1608 const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
1609
1610 return EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || mdcr.tde);
1611}
1612
1615{
1616 // AArch64
1617 if (toEL == fromEL)
1619 else
1621}
1622
1623void
1625{
1626
1628 MiscRegIndex elr_idx;
1629 switch (toEL) {
1630 case EL1:
1631 elr_idx = MISCREG_ELR_EL1;
1632 break;
1633 case EL2:
1634 assert(ArmSystem::haveEL(tc, EL2));
1635 elr_idx = MISCREG_ELR_EL2;
1636 break;
1637 case EL3:
1638 assert(ArmSystem::haveEL(tc, EL3));
1639 elr_idx = MISCREG_ELR_EL3;
1640 break;
1641 default:
1642 panic("Invalid target exception level");
1643 break;
1644 }
1645
1646 tc->setMiscReg(elr_idx, vAddr);
1647
1648}
1649
1651 bool _write, bool _cm)
1652 : ArmFaultVals<Watchpoint>(mach_inst), vAddr(_vaddr),
1653 write(_write), cm(_cm)
1654{}
1655
1656uint32_t
1658{
1659 ESR esr = 0;
1660 auto& iss = esr.watchpoint_iss;
1661 iss.dfsc = 0b100010;
1662 iss.cm = cm;
1663 iss.wnr = write;
1664 return iss;
1665}
1666
1667void
1674
1675bool
1677{
1678 const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1679 const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
1680
1681 return fromEL == EL2 ||
1682 (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || mdcr.tde));
1683}
1684
1685void
1687{
1689 switch (id)
1690 {
1691 case OFA:
1692 vAddr = val;
1693 break;
1694 // Just ignore unknown ID's
1695 default:
1696 break;
1697 }
1698}
1699
1702{
1703 // AArch64
1704 if (toEL == fromEL)
1706 else
1708}
1709
1711 bool _stepped)
1712 : ArmFaultVals<SoftwareStepFault>(mach_inst), isldx(is_ldx),
1713 stepped(_stepped)
1714{
1715 bStep = true;
1716}
1717
1718bool
1720{
1721 const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1722 const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
1723
1724 return fromEL == EL2 ||
1725 (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || mdcr.tde));
1726}
1727
1730{
1731 // AArch64
1732 if (toEL == fromEL)
1734 else
1736}
1737
1738uint32_t
1740{
1741 ESR esr = 0;
1742 auto& iss = esr.software_step_iss;
1743 iss.ifsc = 0b100010;
1744 iss.isv = stepped;
1745 iss.ex = isldx;
1746 return iss;
1747}
1748
1749void
1751{
1752 DPRINTF(Faults, "Invoking ArmSev Fault\n");
1753 if (!FullSystem)
1754 return;
1755
1756 // Set sev_mailbox to 1, clear the pending interrupt from remote
1757 // SEV execution and let pipeline continue as pcState is still
1758 // valid.
1760 tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_SEV, 0);
1761}
1762
1763// Instantiate all the templates to make the linker happy
1764template class ArmFaultVals<Reset>;
1766template class ArmFaultVals<SupervisorCall>;
1767template class ArmFaultVals<SecureMonitorCall>;
1768template class ArmFaultVals<HypervisorCall>;
1769template class ArmFaultVals<PrefetchAbort>;
1770template class ArmFaultVals<DataAbort>;
1771template class ArmFaultVals<VirtualDataAbort>;
1772template class ArmFaultVals<HypervisorTrap>;
1773template class ArmFaultVals<Interrupt>;
1774template class ArmFaultVals<VirtualInterrupt>;
1775template class ArmFaultVals<FastInterrupt>;
1777template class ArmFaultVals<SupervisorTrap>;
1778template class ArmFaultVals<SecureMonitorTrap>;
1779template class ArmFaultVals<PCAlignmentFault>;
1780template class ArmFaultVals<SPAlignmentFault>;
1781template class ArmFaultVals<SystemError>;
1784template class ArmFaultVals<Watchpoint>;
1785template class ArmFaultVals<SoftwareStepFault>;
1786template class ArmFaultVals<ArmSev>;
1787template class AbortFault<PrefetchAbort>;
1788template class AbortFault<DataAbort>;
1789template class AbortFault<VirtualDataAbort>;
1790
1791
1794
1795bool
1797{
1798 const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
1799 return EL2Enabled(tc) && fromEL == EL0 && hcr.tge;
1800}
1801
1802bool
1804{
1805 auto arm_fault = dynamic_cast<ArmFault *>(fault.get());
1806
1807 if (arm_fault) {
1808 return arm_fault->getFaultVAddr(va);
1809 } else {
1810 auto pgt_fault = dynamic_cast<GenericPageTableFault *>(fault.get());
1811 if (pgt_fault) {
1812 va = pgt_fault->getFaultVAddr();
1813 return true;
1814 }
1815
1816 auto align_fault = dynamic_cast<GenericAlignmentFault *>(fault.get());
1817 if (align_fault) {
1818 va = align_fault->getFaultVAddr();
1819 return true;
1820 }
1821
1822 // Return false since it's not an address triggered exception
1823 return false;
1824 }
1825}
1826
1827} // namespace ArmISA
1828} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
Addr OVAddr
Original virtual address.
Definition faults.hh:476
Addr faultAddr
The virtual address the fault occured at.
Definition faults.hh:470
void setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg) override
Definition faults.cc:1122
uint8_t getFaultStatusCode(ThreadContext *tc) const
Definition faults.cc:1133
void update(ThreadContext *tc) override
Definition faults.cc:1094
ArmFault::DebugType debugType
Definition faults.hh:484
void annotate(ArmFault::AnnotationIDs id, uint64_t val) override
Definition faults.cc:1195
bool abortDisable(ThreadContext *tc) override
Definition faults.cc:1184
bool getFaultVAddr(Addr &va) const override
Definition faults.cc:1242
bool isExternalAbort() const override
Definition faults.cc:1231
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:1033
FSR getFsr(ThreadContext *tc) const override
Definition faults.cc:1159
bool isMMUFault() const
Definition faults.cc:1214
virtual bool routeToMonitor(ThreadContext *tc) const override
Definition faults.hh:272
ArmFaultVals(ExtMachInst mach_inst=0, uint32_t _iss=0)
Definition faults.hh:262
FaultOffset offset64(ThreadContext *tc) override
Definition faults.cc:943
static FaultVals vals
Definition faults.hh:259
FaultOffset offset(ThreadContext *tc) override
Definition faults.cc:923
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:712
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
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:1750
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:1350
uint32_t iss() const override
Definition faults.cc:1374
void annotate(AnnotationIDs id, uint64_t val) override
Definition faults.cc:1403
bool il(ThreadContext *tc) const override
Definition faults.cc:1337
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1308
bool routeToMonitor(ThreadContext *tc) const override
Definition faults.cc:1343
bool fiqDisable(ThreadContext *tc) override
Definition faults.cc:1508
bool abortDisable(ThreadContext *tc) override
Definition faults.cc:1498
bool routeToMonitor(ThreadContext *tc) const override
Definition faults.cc:1482
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1490
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:1624
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1605
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1614
HardwareBreakpoint(Addr _vaddr, uint32_t _iss)
Definition faults.cc:1600
bool routeToMonitor(ThreadContext *tc) const override
Definition faults.cc:898
HypervisorCall(ExtMachInst mach_inst, uint32_t _imm)
Definition faults.cc:891
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:904
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:910
ExceptionClass overrideEc
Definition faults.hh:447
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:916
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1796
bool abortDisable(ThreadContext *tc) override
Definition faults.cc:1469
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1461
bool routeToMonitor(ThreadContext *tc) const override
Definition faults.cc:1453
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:1523
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1532
Addr faultPC
The unaligned value of the PC.
Definition faults.hh:626
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1249
uint32_t iss() const override
Definition faults.cc:1274
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1293
bool routeToMonitor(ThreadContext *tc) const override
Definition faults.cc:1286
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:742
Addr getVector(ThreadContext *tc) override
Definition faults.cc:724
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1542
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:993
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:984
uint32_t iss() const override
Definition faults.cc:872
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1025
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1585
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1595
SoftwareBreakpoint(ExtMachInst mach_inst, uint32_t _iss)
Definition faults.cc:1580
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1719
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1729
uint32_t iss() const override
Definition faults.cc:1739
SoftwareStepFault(ExtMachInst mach_inst, bool is_ldx, bool stepped)
Definition faults.cc:1710
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:830
ExceptionClass overrideEc
Definition faults.hh:355
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:849
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:857
uint32_t iss() const override
Definition faults.cc:864
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:999
ExceptionClass overrideEc
Definition faults.hh:397
uint32_t iss() const override
Definition faults.cc:1006
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1016
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:1553
bool routeToMonitor(ThreadContext *tc) const override
Definition faults.cc:1560
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1569
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:770
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:793
uint32_t iss() const override
Definition faults.cc:801
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:880
void invoke(ThreadContext *tc, const StaticInstPtr &inst) override
Definition faults.cc:1444
Watchpoint(ExtMachInst mach_inst, Addr vaddr, bool _write, bool _cm)
Definition faults.cc:1650
bool routeToHyp(ThreadContext *tc) const override
Definition faults.cc:1676
void annotate(AnnotationIDs id, uint64_t val) override
Definition faults.cc:1686
ExceptionClass ec(ThreadContext *tc) const override
Syndrome methods.
Definition faults.cc:1701
uint32_t iss() const override
Definition faults.cc:1657
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:1668
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
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:331
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:220
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:246
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
void writeRegister(ThreadContext *tc, RegVal val, ExceptionLevel el)
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:1803
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
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
@ 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< 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< 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
RefCountingPtr< StaticInst > StaticInstPtr
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161

Generated on Mon May 26 2025 09:18:59 for gem5 by doxygen 1.13.2