faults.hh revision 12511
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(ThreadContext *tc) = 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(ThreadContext *tc) override; 225 226 OperatingMode nextMode() override { return vals.nextMode; } 227 virtual bool routeToMonitor(ThreadContext *tc) const override { 228 return false; 229 } 230 uint8_t armPcOffset(bool isHyp) override { 231 return isHyp ? vals.armPcElrOffset 232 : vals.armPcOffset; 233 } 234 uint8_t thumbPcOffset(bool isHyp) override { 235 return isHyp ? vals.thumbPcElrOffset 236 : vals.thumbPcOffset; 237 } 238 uint8_t armPcElrOffset() override { return vals.armPcElrOffset; } 239 uint8_t thumbPcElrOffset() override { return vals.thumbPcElrOffset; } 240 bool abortDisable(ThreadContext* tc) override { return vals.abortDisable; } 241 bool fiqDisable(ThreadContext* tc) override { return vals.fiqDisable; } 242 ExceptionClass ec(ThreadContext *tc) const override { return vals.ec; } 243 uint32_t iss() const override { return issRaw; } 244}; 245 246class Reset : public ArmFaultVals<Reset> 247{ 248 public: 249 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 250 StaticInst::nullStaticInstPtr) override; 251}; 252 253class UndefinedInstruction : public ArmFaultVals<UndefinedInstruction> 254{ 255 protected: 256 bool unknown; 257 bool disabled; 258 ExceptionClass overrideEc; 259 const char *mnemonic; 260 261 public: 262 UndefinedInstruction(ExtMachInst _machInst, 263 bool _unknown, 264 const char *_mnemonic = NULL, 265 bool _disabled = false) : 266 ArmFaultVals<UndefinedInstruction>(_machInst), 267 unknown(_unknown), disabled(_disabled), 268 overrideEc(EC_INVALID), mnemonic(_mnemonic) 269 {} 270 UndefinedInstruction(ExtMachInst _machInst, uint32_t _iss, 271 ExceptionClass _overrideEc, const char *_mnemonic = NULL) : 272 ArmFaultVals<UndefinedInstruction>(_machInst, _iss), 273 unknown(false), disabled(true), overrideEc(_overrideEc), 274 mnemonic(_mnemonic) 275 {} 276 277 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 278 StaticInst::nullStaticInstPtr) override; 279 bool routeToHyp(ThreadContext *tc) const override; 280 ExceptionClass ec(ThreadContext *tc) const override; 281 uint32_t iss() const override; 282}; 283 284class SupervisorCall : public ArmFaultVals<SupervisorCall> 285{ 286 protected: 287 ExceptionClass overrideEc; 288 public: 289 SupervisorCall(ExtMachInst _machInst, uint32_t _iss, 290 ExceptionClass _overrideEc = EC_INVALID) : 291 ArmFaultVals<SupervisorCall>(_machInst, _iss), 292 overrideEc(_overrideEc) 293 {} 294 295 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 296 StaticInst::nullStaticInstPtr) override; 297 bool routeToHyp(ThreadContext *tc) const override; 298 ExceptionClass ec(ThreadContext *tc) const override; 299 uint32_t iss() const override; 300}; 301 302class SecureMonitorCall : public ArmFaultVals<SecureMonitorCall> 303{ 304 public: 305 SecureMonitorCall(ExtMachInst _machInst) : 306 ArmFaultVals<SecureMonitorCall>(_machInst) 307 {} 308 309 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 310 StaticInst::nullStaticInstPtr) override; 311 ExceptionClass ec(ThreadContext *tc) const override; 312 uint32_t iss() const override; 313}; 314 315class SupervisorTrap : public ArmFaultVals<SupervisorTrap> 316{ 317 protected: 318 ExtMachInst machInst; 319 ExceptionClass overrideEc; 320 321 public: 322 SupervisorTrap(ExtMachInst _machInst, uint32_t _iss, 323 ExceptionClass _overrideEc = EC_INVALID) : 324 ArmFaultVals<SupervisorTrap>(_machInst, _iss), 325 overrideEc(_overrideEc) 326 {} 327 328 bool routeToHyp(ThreadContext *tc) const override; 329 uint32_t iss() const override; 330 ExceptionClass ec(ThreadContext *tc) const override; 331}; 332 333class SecureMonitorTrap : public ArmFaultVals<SecureMonitorTrap> 334{ 335 protected: 336 ExtMachInst machInst; 337 ExceptionClass overrideEc; 338 339 public: 340 SecureMonitorTrap(ExtMachInst _machInst, uint32_t _iss, 341 ExceptionClass _overrideEc = EC_INVALID) : 342 ArmFaultVals<SecureMonitorTrap>(_machInst, _iss), 343 overrideEc(_overrideEc) 344 {} 345 346 ExceptionClass ec(ThreadContext *tc) const override; 347}; 348 349class HypervisorCall : public ArmFaultVals<HypervisorCall> 350{ 351 public: 352 HypervisorCall(ExtMachInst _machInst, uint32_t _imm); 353 354 ExceptionClass ec(ThreadContext *tc) const override; 355}; 356 357class HypervisorTrap : public ArmFaultVals<HypervisorTrap> 358{ 359 protected: 360 ExtMachInst machInst; 361 ExceptionClass overrideEc; 362 363 public: 364 HypervisorTrap(ExtMachInst _machInst, uint32_t _iss, 365 ExceptionClass _overrideEc = EC_INVALID) : 366 ArmFaultVals<HypervisorTrap>(_machInst, _iss), 367 overrideEc(_overrideEc) 368 {} 369 370 ExceptionClass ec(ThreadContext *tc) const override; 371}; 372 373template <class T> 374class AbortFault : public ArmFaultVals<T> 375{ 376 protected: 377 /** 378 * The virtual address the fault occured at. If 2 stages of 379 * translation are being used then this is the intermediate 380 * physical address that is the starting point for the second 381 * stage of translation. 382 */ 383 Addr faultAddr; 384 /** 385 * Original virtual address. If the fault was generated on the 386 * second stage of translation then this variable stores the 387 * virtual address used in the original stage 1 translation. 388 */ 389 Addr OVAddr; 390 bool write; 391 TlbEntry::DomainType domain; 392 uint8_t source; 393 uint8_t srcEncoded; 394 bool stage2; 395 bool s1ptw; 396 ArmFault::TranMethod tranMethod; 397 398 public: 399 AbortFault(Addr _faultAddr, bool _write, TlbEntry::DomainType _domain, 400 uint8_t _source, bool _stage2, 401 ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran) : 402 faultAddr(_faultAddr), OVAddr(0), write(_write), 403 domain(_domain), source(_source), srcEncoded(0), 404 stage2(_stage2), s1ptw(false), tranMethod(_tranMethod) 405 {} 406 407 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 408 StaticInst::nullStaticInstPtr) override; 409 410 FSR getFsr(ThreadContext *tc) override; 411 bool abortDisable(ThreadContext *tc) override; 412 uint32_t iss() const override; 413 bool isStage2() const override { return stage2; } 414 void annotate(ArmFault::AnnotationIDs id, uint64_t val) override; 415 bool isMMUFault() const; 416}; 417 418class PrefetchAbort : public AbortFault<PrefetchAbort> 419{ 420 public: 421 static const MiscRegIndex FsrIndex = MISCREG_IFSR; 422 static const MiscRegIndex FarIndex = MISCREG_IFAR; 423 static const MiscRegIndex HFarIndex = MISCREG_HIFAR; 424 425 PrefetchAbort(Addr _addr, uint8_t _source, bool _stage2 = false, 426 ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran) : 427 AbortFault<PrefetchAbort>(_addr, false, TlbEntry::DomainType::NoAccess, 428 _source, _stage2, _tranMethod) 429 {} 430 431 ExceptionClass ec(ThreadContext *tc) const override; 432 // @todo: external aborts should be routed if SCR.EA == 1 433 bool routeToMonitor(ThreadContext *tc) const override; 434 bool routeToHyp(ThreadContext *tc) const override; 435}; 436 437class DataAbort : public AbortFault<DataAbort> 438{ 439 public: 440 static const MiscRegIndex FsrIndex = MISCREG_DFSR; 441 static const MiscRegIndex FarIndex = MISCREG_DFAR; 442 static const MiscRegIndex HFarIndex = MISCREG_HDFAR; 443 bool isv; 444 uint8_t sas; 445 uint8_t sse; 446 uint8_t srt; 447 448 // AArch64 only 449 bool sf; 450 bool ar; 451 452 DataAbort(Addr _addr, TlbEntry::DomainType _domain, bool _write, uint8_t _source, 453 bool _stage2 = false, ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran) : 454 AbortFault<DataAbort>(_addr, _write, _domain, _source, _stage2, 455 _tranMethod), 456 isv(false), sas (0), sse(0), srt(0), sf(false), ar(false) 457 {} 458 459 ExceptionClass ec(ThreadContext *tc) const override; 460 // @todo: external aborts should be routed if SCR.EA == 1 461 bool routeToMonitor(ThreadContext *tc) const override; 462 bool routeToHyp(ThreadContext *tc) const override; 463 uint32_t iss() const override; 464 void annotate(AnnotationIDs id, uint64_t val) override; 465}; 466 467class VirtualDataAbort : public AbortFault<VirtualDataAbort> 468{ 469 public: 470 static const MiscRegIndex FsrIndex = MISCREG_DFSR; 471 static const MiscRegIndex FarIndex = MISCREG_DFAR; 472 static const MiscRegIndex HFarIndex = MISCREG_HDFAR; 473 474 VirtualDataAbort(Addr _addr, TlbEntry::DomainType _domain, bool _write, 475 uint8_t _source) : 476 AbortFault<VirtualDataAbort>(_addr, _write, _domain, _source, false) 477 {} 478 479 void invoke(ThreadContext *tc, const StaticInstPtr &inst) override; 480}; 481 482class Interrupt : public ArmFaultVals<Interrupt> 483{ 484 public: 485 bool routeToMonitor(ThreadContext *tc) const override; 486 bool routeToHyp(ThreadContext *tc) const override; 487 bool abortDisable(ThreadContext *tc) override; 488}; 489 490class VirtualInterrupt : public ArmFaultVals<VirtualInterrupt> 491{ 492 public: 493 VirtualInterrupt(); 494}; 495 496class FastInterrupt : public ArmFaultVals<FastInterrupt> 497{ 498 public: 499 bool routeToMonitor(ThreadContext *tc) const override; 500 bool routeToHyp(ThreadContext *tc) const override; 501 bool abortDisable(ThreadContext *tc) override; 502 bool fiqDisable(ThreadContext *tc) override; 503}; 504 505class VirtualFastInterrupt : public ArmFaultVals<VirtualFastInterrupt> 506{ 507 public: 508 VirtualFastInterrupt(); 509}; 510 511/// PC alignment fault (AArch64 only) 512class PCAlignmentFault : public ArmFaultVals<PCAlignmentFault> 513{ 514 protected: 515 /// The unaligned value of the PC 516 Addr faultPC; 517 public: 518 PCAlignmentFault(Addr _faultPC) : faultPC(_faultPC) 519 {} 520 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 521 StaticInst::nullStaticInstPtr) override; 522}; 523 524/// Stack pointer alignment fault (AArch64 only) 525class SPAlignmentFault : public ArmFaultVals<SPAlignmentFault> 526{ 527 public: 528 SPAlignmentFault(); 529}; 530 531/// System error (AArch64 only) 532class SystemError : public ArmFaultVals<SystemError> 533{ 534 public: 535 SystemError(); 536 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 537 StaticInst::nullStaticInstPtr) override; 538 bool routeToMonitor(ThreadContext *tc) const override; 539 bool routeToHyp(ThreadContext *tc) const override; 540}; 541 542/// System error (AArch64 only) 543class SoftwareBreakpoint : public ArmFaultVals<SoftwareBreakpoint> 544{ 545 public: 546 SoftwareBreakpoint(ExtMachInst _mach_inst, uint32_t _iss); 547 548 bool routeToHyp(ThreadContext *tc) const override; 549}; 550 551// A fault that flushes the pipe, excluding the faulting instructions 552class ArmSev : public ArmFaultVals<ArmSev> 553{ 554 public: 555 ArmSev () {} 556 void invoke(ThreadContext *tc, const StaticInstPtr &inst = 557 StaticInst::nullStaticInstPtr) override; 558}; 559 560/// Illegal Instruction Set State fault (AArch64 only) 561class IllegalInstSetStateFault : public ArmFaultVals<IllegalInstSetStateFault> 562{ 563 public: 564 IllegalInstSetStateFault(); 565}; 566 567/* 568 * Explicitly declare template static member variables to avoid warnings 569 * in some clang versions 570 */ 571template<> ArmFault::FaultVals ArmFaultVals<Reset>::vals; 572template<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals; 573template<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals; 574template<> ArmFault::FaultVals ArmFaultVals<SecureMonitorCall>::vals; 575template<> ArmFault::FaultVals ArmFaultVals<HypervisorCall>::vals; 576template<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals; 577template<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals; 578template<> ArmFault::FaultVals ArmFaultVals<VirtualDataAbort>::vals; 579template<> ArmFault::FaultVals ArmFaultVals<HypervisorTrap>::vals; 580template<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals; 581template<> ArmFault::FaultVals ArmFaultVals<VirtualInterrupt>::vals; 582template<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals; 583template<> ArmFault::FaultVals ArmFaultVals<VirtualFastInterrupt>::vals; 584template<> ArmFault::FaultVals ArmFaultVals<SupervisorTrap>::vals; 585template<> ArmFault::FaultVals ArmFaultVals<SecureMonitorTrap>::vals; 586template<> ArmFault::FaultVals ArmFaultVals<PCAlignmentFault>::vals; 587template<> ArmFault::FaultVals ArmFaultVals<SPAlignmentFault>::vals; 588template<> ArmFault::FaultVals ArmFaultVals<SystemError>::vals; 589template<> ArmFault::FaultVals ArmFaultVals<SoftwareBreakpoint>::vals; 590template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals; 591 592 593} // namespace ArmISA 594 595#endif // __ARM_FAULTS_HH__ 596