faults.hh revision 12402:a90842ce2303
1/* 2 * Copyright (c) 2010, 2012-2013, 2016-2017 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#ifndef __ARM_FAULTS_HH__ 48#define __ARM_FAULTS_HH__ 49 50#include "arch/arm/miscregs.hh" 51#include "arch/arm/pagetable.hh" 52#include "arch/arm/types.hh" 53#include "base/logging.hh" 54#include "sim/faults.hh" 55#include "sim/full_system.hh" 56 57// The design of the "name" and "vect" functions is in sim/faults.hh 58 59namespace ArmISA 60{ 61typedef Addr FaultOffset; 62 63class ArmFault : public FaultBase 64{ 65 protected: 66 ExtMachInst machInst; 67 uint32_t issRaw; 68 69 // Helper variables for ARMv8 exception handling 70 bool from64; // True if the exception is generated from the AArch64 state 71 bool to64; // True if the exception is taken in AArch64 state 72 ExceptionLevel fromEL; // Source exception level 73 ExceptionLevel toEL; // Target exception level 74 OperatingMode fromMode; // Source operating mode 75 76 bool hypRouted; // True if the fault has been routed to Hypervisor 77 78 Addr getVector(ThreadContext *tc); 79 Addr getVector64(ThreadContext *tc); 80 81 public: 82 /// Generic fault source enums used to index into 83 /// {short/long/aarch64}DescFaultSources[] to get the actual encodings based 84 /// on the current register width state and the translation table format in 85 /// use 86 enum FaultSource 87 { 88 AlignmentFault = 0, 89 InstructionCacheMaintenance, // Short-desc. format only 90 SynchExtAbtOnTranslTableWalkLL, 91 SynchPtyErrOnTranslTableWalkLL = SynchExtAbtOnTranslTableWalkLL + 4, 92 TranslationLL = SynchPtyErrOnTranslTableWalkLL + 4, 93 AccessFlagLL = TranslationLL + 4, 94 DomainLL = AccessFlagLL + 4, 95 PermissionLL = DomainLL + 4, 96 DebugEvent = PermissionLL + 4, 97 SynchronousExternalAbort, 98 TLBConflictAbort, // Requires LPAE 99 SynchPtyErrOnMemoryAccess, 100 AsynchronousExternalAbort, 101 AsynchPtyErrOnMemoryAccess, 102 AddressSizeLL, // AArch64 only 103 104 // Not real faults. These are faults to allow the translation function 105 // to inform the memory access function not to proceed for a prefetch 106 // that misses in the TLB or that targets an uncacheable address 107 PrefetchTLBMiss = AddressSizeLL + 4, 108 PrefetchUncacheable, 109 110 NumFaultSources, 111 FaultSourceInvalid = 0xff 112 }; 113 114 /// Encodings of the fault sources when the short-desc. translation table 115 /// format is in use (ARM ARM Issue C B3.13.3) 116 static uint8_t shortDescFaultSources[NumFaultSources]; 117 /// Encodings of the fault sources when the long-desc. translation table 118 /// format is in use (ARM ARM Issue C B3.13.3) 119 static uint8_t longDescFaultSources[NumFaultSources]; 120 /// Encodings of the fault sources in AArch64 state 121 static uint8_t aarch64FaultSources[NumFaultSources]; 122 123 enum AnnotationIDs 124 { 125 S1PTW, // DataAbort, PrefetchAbort: Stage 1 Page Table Walk, 126 OVA, // DataAbort, PrefetchAbort: stage 1 Virtual Address for stage 2 faults 127 SAS, // DataAbort: Syndrome Access Size 128 SSE, // DataAbort: Syndrome Sign Extend 129 SRT, // DataAbort: Syndrome Register Transfer 130 131 // AArch64 only 132 SF, // DataAbort: width of the accessed register is SixtyFour 133 AR // DataAbort: Acquire/Release semantics 134 }; 135 136 enum TranMethod 137 { 138 LpaeTran, 139 VmsaTran, 140 UnknownTran 141 }; 142 143 struct FaultVals 144 { 145 const FaultName name; 146 147 const FaultOffset offset; 148 149 // Offsets used for exceptions taken in AArch64 state 150 const uint16_t currELTOffset; 151 const uint16_t currELHOffset; 152 const uint16_t lowerEL64Offset; 153 const uint16_t lowerEL32Offset; 154 155 const OperatingMode nextMode; 156 157 const uint8_t armPcOffset; 158 const uint8_t thumbPcOffset; 159 // The following two values are used in place of armPcOffset and 160 // thumbPcOffset when the exception return address is saved into ELR 161 // registers (exceptions taken in HYP mode or in AArch64 state) 162 const uint8_t armPcElrOffset; 163 const uint8_t thumbPcElrOffset; 164 165 const bool hypTrappable; 166 const bool abortDisable; 167 const bool fiqDisable; 168 169 // Exception class used to appropriately set the syndrome register 170 // (exceptions taken in HYP mode or in AArch64 state) 171 const ExceptionClass ec; 172 173 FaultStat count; 174 }; 175 176 ArmFault(ExtMachInst _machInst = 0, uint32_t _iss = 0) : 177 machInst(_machInst), issRaw(_iss), from64(false), to64(false), 178 fromEL(EL0), toEL(EL0), fromMode(MODE_UNDEFINED), hypRouted(false) {} 179 180 // Returns the actual syndrome register to use based on the target 181 // exception level 182 MiscRegIndex getSyndromeReg64() const; 183 // Returns the actual fault address register to use based on the target 184 // exception level 185 MiscRegIndex getFaultAddrReg64() const; 186 187 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 188 StaticInst::nullStaticInstPtr) override; 189 void invoke64(ThreadContext *tc, const StaticInstPtr &inst = 190 StaticInst::nullStaticInstPtr); 191 virtual void annotate(AnnotationIDs id, uint64_t val) {} 192 virtual FaultStat& countStat() = 0; 193 virtual FaultOffset offset(ThreadContext *tc) = 0; 194 virtual FaultOffset offset64() = 0; 195 virtual OperatingMode nextMode() = 0; 196 virtual bool routeToMonitor(ThreadContext *tc) const = 0; 197 virtual bool routeToHyp(ThreadContext *tc) const { return false; } 198 virtual uint8_t armPcOffset(bool isHyp) = 0; 199 virtual uint8_t thumbPcOffset(bool isHyp) = 0; 200 virtual uint8_t armPcElrOffset() = 0; 201 virtual uint8_t thumbPcElrOffset() = 0; 202 virtual bool abortDisable(ThreadContext *tc) = 0; 203 virtual bool fiqDisable(ThreadContext *tc) = 0; 204 virtual ExceptionClass ec(ThreadContext *tc) const = 0; 205 virtual uint32_t iss() const = 0; 206 virtual bool isStage2() const { return false; } 207 virtual FSR getFsr(ThreadContext *tc) { return 0; } 208 virtual void setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg); 209}; 210 211template<typename T> 212class ArmFaultVals : public ArmFault 213{ 214 protected: 215 static FaultVals vals; 216 217 public: 218 ArmFaultVals<T>(ExtMachInst _machInst = 0, uint32_t _iss = 0) : 219 ArmFault(_machInst, _iss) {} 220 FaultName name() const override { return vals.name; } 221 FaultStat & countStat() override { return vals.count; } 222 FaultOffset offset(ThreadContext *tc) override; 223 224 FaultOffset offset64() override { 225 if (toEL == fromEL) { 226 if (opModeIsT(fromMode)) 227 return vals.currELTOffset; 228 return vals.currELHOffset; 229 } else { 230 if (from64) 231 return vals.lowerEL64Offset; 232 return vals.lowerEL32Offset; 233 } 234 } 235 236 OperatingMode nextMode() override { return vals.nextMode; } 237 virtual bool routeToMonitor(ThreadContext *tc) const override { 238 return false; 239 } 240 uint8_t armPcOffset(bool isHyp) override { 241 return isHyp ? vals.armPcElrOffset 242 : vals.armPcOffset; 243 } 244 uint8_t thumbPcOffset(bool isHyp) override { 245 return isHyp ? vals.thumbPcElrOffset 246 : vals.thumbPcOffset; 247 } 248 uint8_t armPcElrOffset() override { return vals.armPcElrOffset; } 249 uint8_t thumbPcElrOffset() override { return vals.thumbPcElrOffset; } 250 bool abortDisable(ThreadContext* tc) override { return vals.abortDisable; } 251 bool fiqDisable(ThreadContext* tc) override { return vals.fiqDisable; } 252 ExceptionClass ec(ThreadContext *tc) const override { return vals.ec; } 253 uint32_t iss() const override { return issRaw; } 254}; 255 256class Reset : public ArmFaultVals<Reset> 257{ 258 public: 259 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 260 StaticInst::nullStaticInstPtr) override; 261}; 262 263class UndefinedInstruction : public ArmFaultVals<UndefinedInstruction> 264{ 265 protected: 266 bool unknown; 267 bool disabled; 268 ExceptionClass overrideEc; 269 const char *mnemonic; 270 271 public: 272 UndefinedInstruction(ExtMachInst _machInst, 273 bool _unknown, 274 const char *_mnemonic = NULL, 275 bool _disabled = false) : 276 ArmFaultVals<UndefinedInstruction>(_machInst), 277 unknown(_unknown), disabled(_disabled), 278 overrideEc(EC_INVALID), mnemonic(_mnemonic) 279 {} 280 UndefinedInstruction(ExtMachInst _machInst, uint32_t _iss, 281 ExceptionClass _overrideEc, const char *_mnemonic = NULL) : 282 ArmFaultVals<UndefinedInstruction>(_machInst, _iss), 283 unknown(false), disabled(true), overrideEc(_overrideEc), 284 mnemonic(_mnemonic) 285 {} 286 287 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 288 StaticInst::nullStaticInstPtr) override; 289 bool routeToHyp(ThreadContext *tc) const override; 290 ExceptionClass ec(ThreadContext *tc) const override; 291 uint32_t iss() const override; 292}; 293 294class SupervisorCall : public ArmFaultVals<SupervisorCall> 295{ 296 protected: 297 ExceptionClass overrideEc; 298 public: 299 SupervisorCall(ExtMachInst _machInst, uint32_t _iss, 300 ExceptionClass _overrideEc = EC_INVALID) : 301 ArmFaultVals<SupervisorCall>(_machInst, _iss), 302 overrideEc(_overrideEc) 303 {} 304 305 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 306 StaticInst::nullStaticInstPtr) override; 307 bool routeToHyp(ThreadContext *tc) const override; 308 ExceptionClass ec(ThreadContext *tc) const override; 309 uint32_t iss() const override; 310}; 311 312class SecureMonitorCall : public ArmFaultVals<SecureMonitorCall> 313{ 314 public: 315 SecureMonitorCall(ExtMachInst _machInst) : 316 ArmFaultVals<SecureMonitorCall>(_machInst) 317 {} 318 319 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 320 StaticInst::nullStaticInstPtr) override; 321 ExceptionClass ec(ThreadContext *tc) const override; 322 uint32_t iss() const override; 323}; 324 325class SupervisorTrap : public ArmFaultVals<SupervisorTrap> 326{ 327 protected: 328 ExtMachInst machInst; 329 ExceptionClass overrideEc; 330 331 public: 332 SupervisorTrap(ExtMachInst _machInst, uint32_t _iss, 333 ExceptionClass _overrideEc = EC_INVALID) : 334 ArmFaultVals<SupervisorTrap>(_machInst, _iss), 335 overrideEc(_overrideEc) 336 {} 337 338 ExceptionClass ec(ThreadContext *tc) const override; 339}; 340 341class SecureMonitorTrap : public ArmFaultVals<SecureMonitorTrap> 342{ 343 protected: 344 ExtMachInst machInst; 345 ExceptionClass overrideEc; 346 347 public: 348 SecureMonitorTrap(ExtMachInst _machInst, uint32_t _iss, 349 ExceptionClass _overrideEc = EC_INVALID) : 350 ArmFaultVals<SecureMonitorTrap>(_machInst, _iss), 351 overrideEc(_overrideEc) 352 {} 353 354 ExceptionClass ec(ThreadContext *tc) const override; 355}; 356 357class HypervisorCall : public ArmFaultVals<HypervisorCall> 358{ 359 public: 360 HypervisorCall(ExtMachInst _machInst, uint32_t _imm); 361 362 ExceptionClass ec(ThreadContext *tc) const override; 363}; 364 365class HypervisorTrap : public ArmFaultVals<HypervisorTrap> 366{ 367 protected: 368 ExtMachInst machInst; 369 ExceptionClass overrideEc; 370 371 public: 372 HypervisorTrap(ExtMachInst _machInst, uint32_t _iss, 373 ExceptionClass _overrideEc = EC_INVALID) : 374 ArmFaultVals<HypervisorTrap>(_machInst, _iss), 375 overrideEc(_overrideEc) 376 {} 377 378 ExceptionClass ec(ThreadContext *tc) const override; 379}; 380 381template <class T> 382class AbortFault : public ArmFaultVals<T> 383{ 384 protected: 385 /** 386 * The virtual address the fault occured at. If 2 stages of 387 * translation are being used then this is the intermediate 388 * physical address that is the starting point for the second 389 * stage of translation. 390 */ 391 Addr faultAddr; 392 /** 393 * Original virtual address. If the fault was generated on the 394 * second stage of translation then this variable stores the 395 * virtual address used in the original stage 1 translation. 396 */ 397 Addr OVAddr; 398 bool write; 399 TlbEntry::DomainType domain; 400 uint8_t source; 401 uint8_t srcEncoded; 402 bool stage2; 403 bool s1ptw; 404 ArmFault::TranMethod tranMethod; 405 406 public: 407 AbortFault(Addr _faultAddr, bool _write, TlbEntry::DomainType _domain, 408 uint8_t _source, bool _stage2, 409 ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran) : 410 faultAddr(_faultAddr), OVAddr(0), write(_write), 411 domain(_domain), source(_source), srcEncoded(0), 412 stage2(_stage2), s1ptw(false), tranMethod(_tranMethod) 413 {} 414 415 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 416 StaticInst::nullStaticInstPtr) override; 417 418 FSR getFsr(ThreadContext *tc) override; 419 bool abortDisable(ThreadContext *tc) override; 420 uint32_t iss() const override; 421 bool isStage2() const override { return stage2; } 422 void annotate(ArmFault::AnnotationIDs id, uint64_t val) override; 423 bool isMMUFault() const; 424}; 425 426class PrefetchAbort : public AbortFault<PrefetchAbort> 427{ 428 public: 429 static const MiscRegIndex FsrIndex = MISCREG_IFSR; 430 static const MiscRegIndex FarIndex = MISCREG_IFAR; 431 static const MiscRegIndex HFarIndex = MISCREG_HIFAR; 432 433 PrefetchAbort(Addr _addr, uint8_t _source, bool _stage2 = false, 434 ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran) : 435 AbortFault<PrefetchAbort>(_addr, false, TlbEntry::DomainType::NoAccess, 436 _source, _stage2, _tranMethod) 437 {} 438 439 ExceptionClass ec(ThreadContext *tc) const override; 440 // @todo: external aborts should be routed if SCR.EA == 1 441 bool routeToMonitor(ThreadContext *tc) const override; 442 bool routeToHyp(ThreadContext *tc) const override; 443}; 444 445class DataAbort : public AbortFault<DataAbort> 446{ 447 public: 448 static const MiscRegIndex FsrIndex = MISCREG_DFSR; 449 static const MiscRegIndex FarIndex = MISCREG_DFAR; 450 static const MiscRegIndex HFarIndex = MISCREG_HDFAR; 451 bool isv; 452 uint8_t sas; 453 uint8_t sse; 454 uint8_t srt; 455 456 // AArch64 only 457 bool sf; 458 bool ar; 459 460 DataAbort(Addr _addr, TlbEntry::DomainType _domain, bool _write, uint8_t _source, 461 bool _stage2 = false, ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran) : 462 AbortFault<DataAbort>(_addr, _write, _domain, _source, _stage2, 463 _tranMethod), 464 isv(false), sas (0), sse(0), srt(0), sf(false), ar(false) 465 {} 466 467 ExceptionClass ec(ThreadContext *tc) const override; 468 // @todo: external aborts should be routed if SCR.EA == 1 469 bool routeToMonitor(ThreadContext *tc) const override; 470 bool routeToHyp(ThreadContext *tc) const override; 471 uint32_t iss() const override; 472 void annotate(AnnotationIDs id, uint64_t val) override; 473}; 474 475class VirtualDataAbort : public AbortFault<VirtualDataAbort> 476{ 477 public: 478 static const MiscRegIndex FsrIndex = MISCREG_DFSR; 479 static const MiscRegIndex FarIndex = MISCREG_DFAR; 480 static const MiscRegIndex HFarIndex = MISCREG_HDFAR; 481 482 VirtualDataAbort(Addr _addr, TlbEntry::DomainType _domain, bool _write, 483 uint8_t _source) : 484 AbortFault<VirtualDataAbort>(_addr, _write, _domain, _source, false) 485 {} 486 487 void invoke(ThreadContext *tc, const StaticInstPtr &inst) override; 488}; 489 490class Interrupt : public ArmFaultVals<Interrupt> 491{ 492 public: 493 bool routeToMonitor(ThreadContext *tc) const override; 494 bool routeToHyp(ThreadContext *tc) const override; 495 bool abortDisable(ThreadContext *tc) override; 496}; 497 498class VirtualInterrupt : public ArmFaultVals<VirtualInterrupt> 499{ 500 public: 501 VirtualInterrupt(); 502}; 503 504class FastInterrupt : public ArmFaultVals<FastInterrupt> 505{ 506 public: 507 bool routeToMonitor(ThreadContext *tc) const override; 508 bool routeToHyp(ThreadContext *tc) const override; 509 bool abortDisable(ThreadContext *tc) override; 510 bool fiqDisable(ThreadContext *tc) override; 511}; 512 513class VirtualFastInterrupt : public ArmFaultVals<VirtualFastInterrupt> 514{ 515 public: 516 VirtualFastInterrupt(); 517}; 518 519/// PC alignment fault (AArch64 only) 520class PCAlignmentFault : public ArmFaultVals<PCAlignmentFault> 521{ 522 protected: 523 /// The unaligned value of the PC 524 Addr faultPC; 525 public: 526 PCAlignmentFault(Addr _faultPC) : faultPC(_faultPC) 527 {} 528 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 529 StaticInst::nullStaticInstPtr) override; 530}; 531 532/// Stack pointer alignment fault (AArch64 only) 533class SPAlignmentFault : public ArmFaultVals<SPAlignmentFault> 534{ 535 public: 536 SPAlignmentFault(); 537}; 538 539/// System error (AArch64 only) 540class SystemError : public ArmFaultVals<SystemError> 541{ 542 public: 543 SystemError(); 544 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 545 StaticInst::nullStaticInstPtr) override; 546 bool routeToMonitor(ThreadContext *tc) const override; 547 bool routeToHyp(ThreadContext *tc) const override; 548}; 549 550/// System error (AArch64 only) 551class SoftwareBreakpoint : public ArmFaultVals<SoftwareBreakpoint> 552{ 553 public: 554 SoftwareBreakpoint(ExtMachInst _mach_inst, uint32_t _iss); 555 556 bool routeToHyp(ThreadContext *tc) const override; 557}; 558 559// A fault that flushes the pipe, excluding the faulting instructions 560class ArmSev : public ArmFaultVals<ArmSev> 561{ 562 public: 563 ArmSev () {} 564 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 565 StaticInst::nullStaticInstPtr) override; 566}; 567 568/// Illegal Instruction Set State fault (AArch64 only) 569class IllegalInstSetStateFault : public ArmFaultVals<IllegalInstSetStateFault> 570{ 571 public: 572 IllegalInstSetStateFault(); 573}; 574 575/* 576 * Explicitly declare template static member variables to avoid warnings 577 * in some clang versions 578 */ 579template<> ArmFault::FaultVals ArmFaultVals<Reset>::vals; 580template<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals; 581template<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals; 582template<> ArmFault::FaultVals ArmFaultVals<SecureMonitorCall>::vals; 583template<> ArmFault::FaultVals ArmFaultVals<HypervisorCall>::vals; 584template<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals; 585template<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals; 586template<> ArmFault::FaultVals ArmFaultVals<VirtualDataAbort>::vals; 587template<> ArmFault::FaultVals ArmFaultVals<HypervisorTrap>::vals; 588template<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals; 589template<> ArmFault::FaultVals ArmFaultVals<VirtualInterrupt>::vals; 590template<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals; 591template<> ArmFault::FaultVals ArmFaultVals<VirtualFastInterrupt>::vals; 592template<> ArmFault::FaultVals ArmFaultVals<SupervisorTrap>::vals; 593template<> ArmFault::FaultVals ArmFaultVals<SecureMonitorTrap>::vals; 594template<> ArmFault::FaultVals ArmFaultVals<PCAlignmentFault>::vals; 595template<> ArmFault::FaultVals ArmFaultVals<SPAlignmentFault>::vals; 596template<> ArmFault::FaultVals ArmFaultVals<SystemError>::vals; 597template<> ArmFault::FaultVals ArmFaultVals<SoftwareBreakpoint>::vals; 598template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals; 599 600 601} // namespace ArmISA 602 603#endif // __ARM_FAULTS_HH__ 604