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
| 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 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),
| 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),
|
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/// System error (AArch64 only) 549class SoftwareBreakpoint : public ArmFaultVals<SoftwareBreakpoint> 550{ 551 public: 552 SoftwareBreakpoint(ExtMachInst _mach_inst, uint32_t _iss); 553 554 bool routeToHyp(ThreadContext *tc) const 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<SoftwareBreakpoint>::vals; 596template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals; 597 598 599} // namespace ArmISA 600 601#endif // __ARM_FAULTS_HH__
| 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__
|