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

Generated on Fri Jun 9 2017 13:03:34 for gem5 by doxygen 1.8.6