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

Generated on Thu May 28 2020 16:11:01 for gem5 by doxygen 1.8.13