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