faults.hh revision 12509
1/* 2 * Copyright (c) 2010, 2012-2013, 2016-2018 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 bool routeToHyp(ThreadContext *tc) const override; 339 uint32_t iss() const override; 340 ExceptionClass ec(ThreadContext *tc) const override; 341}; 342 343class SecureMonitorTrap : public ArmFaultVals<SecureMonitorTrap> 344{ 345 protected: 346 ExtMachInst machInst; 347 ExceptionClass overrideEc; 348 349 public: 350 SecureMonitorTrap(ExtMachInst _machInst, uint32_t _iss, 351 ExceptionClass _overrideEc = EC_INVALID) : 352 ArmFaultVals<SecureMonitorTrap>(_machInst, _iss), 353 overrideEc(_overrideEc) 354 {} 355 356 ExceptionClass ec(ThreadContext *tc) const override; 357}; 358 359class HypervisorCall : public ArmFaultVals<HypervisorCall> 360{ 361 public: 362 HypervisorCall(ExtMachInst _machInst, uint32_t _imm); 363 364 ExceptionClass ec(ThreadContext *tc) const override; 365}; 366 367class HypervisorTrap : public ArmFaultVals<HypervisorTrap> 368{ 369 protected: 370 ExtMachInst machInst; 371 ExceptionClass overrideEc; 372 373 public: 374 HypervisorTrap(ExtMachInst _machInst, uint32_t _iss, 375 ExceptionClass _overrideEc = EC_INVALID) : 376 ArmFaultVals<HypervisorTrap>(_machInst, _iss), 377 overrideEc(_overrideEc) 378 {} 379 380 ExceptionClass ec(ThreadContext *tc) const override; 381}; 382 383template <class T> 384class AbortFault : public ArmFaultVals<T> 385{ 386 protected: 387 /** 388 * The virtual address the fault occured at. If 2 stages of 389 * translation are being used then this is the intermediate 390 * physical address that is the starting point for the second 391 * stage of translation. 392 */ 393 Addr faultAddr; 394 /** 395 * Original virtual address. If the fault was generated on the 396 * second stage of translation then this variable stores the 397 * virtual address used in the original stage 1 translation. 398 */ 399 Addr OVAddr; 400 bool write; 401 TlbEntry::DomainType domain; 402 uint8_t source; 403 uint8_t srcEncoded; 404 bool stage2; 405 bool s1ptw; 406 ArmFault::TranMethod tranMethod; 407 408 public: 409 AbortFault(Addr _faultAddr, bool _write, TlbEntry::DomainType _domain, 410 uint8_t _source, bool _stage2, 411 ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran) : 412 faultAddr(_faultAddr), OVAddr(0), write(_write), 413 domain(_domain), source(_source), srcEncoded(0), 414 stage2(_stage2), s1ptw(false), tranMethod(_tranMethod) 415 {} 416 417 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 418 StaticInst::nullStaticInstPtr) override; 419 420 FSR getFsr(ThreadContext *tc) override; 421 bool abortDisable(ThreadContext *tc) override; 422 uint32_t iss() const override; 423 bool isStage2() const override { return stage2; } 424 void annotate(ArmFault::AnnotationIDs id, uint64_t val) override; 425 bool isMMUFault() const; 426}; 427 428class PrefetchAbort : public AbortFault<PrefetchAbort> 429{ 430 public: 431 static const MiscRegIndex FsrIndex = MISCREG_IFSR; 432 static const MiscRegIndex FarIndex = MISCREG_IFAR; 433 static const MiscRegIndex HFarIndex = MISCREG_HIFAR; 434 435 PrefetchAbort(Addr _addr, uint8_t _source, bool _stage2 = false, 436 ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran) : 437 AbortFault<PrefetchAbort>(_addr, false, TlbEntry::DomainType::NoAccess, 438 _source, _stage2, _tranMethod) 439 {} 440 441 ExceptionClass ec(ThreadContext *tc) const override; 442 // @todo: external aborts should be routed if SCR.EA == 1 443 bool routeToMonitor(ThreadContext *tc) const override; 444 bool routeToHyp(ThreadContext *tc) const override; 445}; 446 447class DataAbort : public AbortFault<DataAbort> 448{ 449 public: 450 static const MiscRegIndex FsrIndex = MISCREG_DFSR; 451 static const MiscRegIndex FarIndex = MISCREG_DFAR; 452 static const MiscRegIndex HFarIndex = MISCREG_HDFAR; 453 bool isv; 454 uint8_t sas; 455 uint8_t sse; 456 uint8_t srt; 457 458 // AArch64 only 459 bool sf; 460 bool ar; 461 462 DataAbort(Addr _addr, TlbEntry::DomainType _domain, bool _write, uint8_t _source, 463 bool _stage2 = false, ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran) : 464 AbortFault<DataAbort>(_addr, _write, _domain, _source, _stage2, 465 _tranMethod), 466 isv(false), sas (0), sse(0), srt(0), sf(false), ar(false) 467 {} 468 469 ExceptionClass ec(ThreadContext *tc) const override; 470 // @todo: external aborts should be routed if SCR.EA == 1 471 bool routeToMonitor(ThreadContext *tc) const override; 472 bool routeToHyp(ThreadContext *tc) const override; 473 uint32_t iss() const override; 474 void annotate(AnnotationIDs id, uint64_t val) override; 475}; 476 477class VirtualDataAbort : public AbortFault<VirtualDataAbort> 478{ 479 public: 480 static const MiscRegIndex FsrIndex = MISCREG_DFSR; 481 static const MiscRegIndex FarIndex = MISCREG_DFAR; 482 static const MiscRegIndex HFarIndex = MISCREG_HDFAR; 483 484 VirtualDataAbort(Addr _addr, TlbEntry::DomainType _domain, bool _write, 485 uint8_t _source) : 486 AbortFault<VirtualDataAbort>(_addr, _write, _domain, _source, false) 487 {} 488 489 void invoke(ThreadContext *tc, const StaticInstPtr &inst) override; 490}; 491 492class Interrupt : public ArmFaultVals<Interrupt> 493{ 494 public: 495 bool routeToMonitor(ThreadContext *tc) const override; 496 bool routeToHyp(ThreadContext *tc) const override; 497 bool abortDisable(ThreadContext *tc) override; 498}; 499 500class VirtualInterrupt : public ArmFaultVals<VirtualInterrupt> 501{ 502 public: 503 VirtualInterrupt(); 504}; 505 506class FastInterrupt : public ArmFaultVals<FastInterrupt> 507{ 508 public: 509 bool routeToMonitor(ThreadContext *tc) const override; 510 bool routeToHyp(ThreadContext *tc) const override; 511 bool abortDisable(ThreadContext *tc) override; 512 bool fiqDisable(ThreadContext *tc) override; 513}; 514 515class VirtualFastInterrupt : public ArmFaultVals<VirtualFastInterrupt> 516{ 517 public: 518 VirtualFastInterrupt(); 519}; 520 521/// PC alignment fault (AArch64 only) 522class PCAlignmentFault : public ArmFaultVals<PCAlignmentFault> 523{ 524 protected: 525 /// The unaligned value of the PC 526 Addr faultPC; 527 public: 528 PCAlignmentFault(Addr _faultPC) : faultPC(_faultPC) 529 {} 530 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 531 StaticInst::nullStaticInstPtr) override; 532}; 533 534/// Stack pointer alignment fault (AArch64 only) 535class SPAlignmentFault : public ArmFaultVals<SPAlignmentFault> 536{ 537 public: 538 SPAlignmentFault(); 539}; 540 541/// System error (AArch64 only) 542class SystemError : public ArmFaultVals<SystemError> 543{ 544 public: 545 SystemError(); 546 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 547 StaticInst::nullStaticInstPtr) override; 548 bool routeToMonitor(ThreadContext *tc) const override; 549 bool routeToHyp(ThreadContext *tc) const override; 550}; 551 552/// System error (AArch64 only) 553class SoftwareBreakpoint : public ArmFaultVals<SoftwareBreakpoint> 554{ 555 public: 556 SoftwareBreakpoint(ExtMachInst _mach_inst, uint32_t _iss); 557 558 bool routeToHyp(ThreadContext *tc) const override; 559}; 560 561// A fault that flushes the pipe, excluding the faulting instructions 562class ArmSev : public ArmFaultVals<ArmSev> 563{ 564 public: 565 ArmSev () {} 566 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 567 StaticInst::nullStaticInstPtr) override; 568}; 569 570/// Illegal Instruction Set State fault (AArch64 only) 571class IllegalInstSetStateFault : public ArmFaultVals<IllegalInstSetStateFault> 572{ 573 public: 574 IllegalInstSetStateFault(); 575}; 576 577/* 578 * Explicitly declare template static member variables to avoid warnings 579 * in some clang versions 580 */ 581template<> ArmFault::FaultVals ArmFaultVals<Reset>::vals; 582template<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals; 583template<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals; 584template<> ArmFault::FaultVals ArmFaultVals<SecureMonitorCall>::vals; 585template<> ArmFault::FaultVals ArmFaultVals<HypervisorCall>::vals; 586template<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals; 587template<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals; 588template<> ArmFault::FaultVals ArmFaultVals<VirtualDataAbort>::vals; 589template<> ArmFault::FaultVals ArmFaultVals<HypervisorTrap>::vals; 590template<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals; 591template<> ArmFault::FaultVals ArmFaultVals<VirtualInterrupt>::vals; 592template<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals; 593template<> ArmFault::FaultVals ArmFaultVals<VirtualFastInterrupt>::vals; 594template<> ArmFault::FaultVals ArmFaultVals<SupervisorTrap>::vals; 595template<> ArmFault::FaultVals ArmFaultVals<SecureMonitorTrap>::vals; 596template<> ArmFault::FaultVals ArmFaultVals<PCAlignmentFault>::vals; 597template<> ArmFault::FaultVals ArmFaultVals<SPAlignmentFault>::vals; 598template<> ArmFault::FaultVals ArmFaultVals<SystemError>::vals; 599template<> ArmFault::FaultVals ArmFaultVals<SoftwareBreakpoint>::vals; 600template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals; 601 602 603} // namespace ArmISA 604 605#endif // __ARM_FAULTS_HH__ 606