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