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

Generated on Wed Dec 21 2022 10:22:23 for gem5 by doxygen 1.9.1