/*
+ * Copyright (c) 2010, 2012-2013 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* Copyright (c) 2007-2008 The Florida State University
* All rights reserved.
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * Authors: Gabe Black
- * Stephen Hines
+ * Authors: Ali Saidi
+ * Gabe Black
+ * Giacomo Gabrielli
+ * Thomas Grocutt
*/
#ifndef __ARM_FAULTS_HH__
#define __ARM_FAULTS_HH__
+#include "arch/arm/miscregs.hh"
+#include "arch/arm/pagetable.hh"
+#include "arch/arm/types.hh"
+#include "base/misc.hh"
#include "sim/faults.hh"
+#include "sim/full_system.hh"
// The design of the "name" and "vect" functions is in sim/faults.hh
namespace ArmISA
{
-typedef const Addr FaultVect;
+typedef Addr FaultOffset;
class ArmFault : public FaultBase
{
protected:
- virtual bool skipFaultingInstruction() {return false;}
- virtual bool setRestartAddress() {return true;}
- public:
- Addr BadVAddr;
- Addr EntryHi_Asid;
- Addr EntryHi_VPN2;
- Addr EntryHi_VPN2X;
- Addr Context_BadVPN2;
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc) {};
- void setExceptionState(ThreadContext *,uint8_t);
- void setHandlerPC(Addr,ThreadContext *);
-#endif
- virtual FaultVect vect() = 0;
- virtual FaultStat & countStat() = 0;
-};
-
-class MachineCheckFault : public ArmFault
+ ExtMachInst machInst;
+ uint32_t issRaw;
+
+ // Helper variables for ARMv8 exception handling
+ bool from64; // True if the exception is generated from the AArch64 state
+ bool to64; // True if the exception is taken in AArch64 state
+ ExceptionLevel fromEL; // Source exception level
+ ExceptionLevel toEL; // Target exception level
+ OperatingMode fromMode; // Source operating mode
+
+ Addr getVector(ThreadContext *tc);
+ Addr getVector64(ThreadContext *tc);
+
+ public:
+ /// Generic fault source enums used to index into
+ /// {short/long/aarch64}DescFaultSources[] to get the actual encodings based
+ /// on the current register width state and the translation table format in
+ /// use
+ enum FaultSource
+ {
+ AlignmentFault = 0,
+ InstructionCacheMaintenance, // Short-desc. format only
+ SynchExtAbtOnTranslTableWalkLL,
+ SynchPtyErrOnTranslTableWalkLL = SynchExtAbtOnTranslTableWalkLL + 4,
+ TranslationLL = SynchPtyErrOnTranslTableWalkLL + 4,
+ AccessFlagLL = TranslationLL + 4,
+ DomainLL = AccessFlagLL + 4,
+ PermissionLL = DomainLL + 4,
+ DebugEvent = PermissionLL + 4,
+ SynchronousExternalAbort,
+ TLBConflictAbort, // Requires LPAE
+ SynchPtyErrOnMemoryAccess,
+ AsynchronousExternalAbort,
+ AsynchPtyErrOnMemoryAccess,
+ AddressSizeLL, // AArch64 only
+
+ // Not real faults. These are faults to allow the translation function
+ // to inform the memory access function not to proceed for a prefetch
+ // that misses in the TLB or that targets an uncacheable address
+ PrefetchTLBMiss = AddressSizeLL + 4,
+ PrefetchUncacheable,
+
+ NumFaultSources,
+ FaultSourceInvalid = 0xff
+ };
+
+ /// Encodings of the fault sources when the short-desc. translation table
+ /// format is in use (ARM ARM Issue C B3.13.3)
+ static uint8_t shortDescFaultSources[NumFaultSources];
+ /// Encodings of the fault sources when the long-desc. translation table
+ /// format is in use (ARM ARM Issue C B3.13.3)
+ static uint8_t longDescFaultSources[NumFaultSources];
+ /// Encodings of the fault sources in AArch64 state
+ static uint8_t aarch64FaultSources[NumFaultSources];
+
+ enum AnnotationIDs
+ {
+ S1PTW, // DataAbort, PrefetchAbort: Stage 1 Page Table Walk,
+ OVA, // DataAbort, PrefetchAbort: stage 1 Virtual Address for stage 2 faults
+ SAS, // DataAbort: Syndrome Access Size
+ SSE, // DataAbort: Syndrome Sign Extend
+ SRT, // DataAbort: Syndrome Register Transfer
+
+ // AArch64 only
+ SF, // DataAbort: width of the accessed register is SixtyFour
+ AR // DataAbort: Acquire/Release semantics
+ };
+
+ enum TranMethod
+ {
+ LpaeTran,
+ VmsaTran,
+ UnknownTran
+ };
+
+ struct FaultVals
+ {
+ const FaultName name;
+
+ const FaultOffset offset;
+
+ // Offsets used for exceptions taken in AArch64 state
+ const uint16_t currELTOffset;
+ const uint16_t currELHOffset;
+ const uint16_t lowerEL64Offset;
+ const uint16_t lowerEL32Offset;
+
+ const OperatingMode nextMode;
+
+ const uint8_t armPcOffset;
+ const uint8_t thumbPcOffset;
+ // The following two values are used in place of armPcOffset and
+ // thumbPcOffset when the exception return address is saved into ELR
+ // registers (exceptions taken in HYP mode or in AArch64 state)
+ const uint8_t armPcElrOffset;
+ const uint8_t thumbPcElrOffset;
+
+ const bool hypTrappable;
+ const bool abortDisable;
+ const bool fiqDisable;
+
+ // Exception class used to appropriately set the syndrome register
+ // (exceptions taken in HYP mode or in AArch64 state)
+ const ExceptionClass ec;
+
+ FaultStat count;
+ };
+
+ ArmFault(ExtMachInst _machInst = 0, uint32_t _iss = 0) :
+ machInst(_machInst), issRaw(_iss), from64(false), to64(false),
+ fromEL(EL0), toEL(EL0), fromMode(MODE_UNDEFINED) {}
+
+ // Returns the actual syndrome register to use based on the target
+ // exception level
+ MiscRegIndex getSyndromeReg64() const;
+ // Returns the actual fault address register to use based on the target
+ // exception level
+ MiscRegIndex getFaultAddrReg64() const;
+
+ void invoke(ThreadContext *tc, const StaticInstPtr &inst =
+ StaticInst::nullStaticInstPtr);
+ void invoke64(ThreadContext *tc, const StaticInstPtr &inst =
+ StaticInst::nullStaticInstPtr);
+ virtual void annotate(AnnotationIDs id, uint64_t val) {}
+ virtual FaultStat& countStat() = 0;
+ virtual FaultOffset offset(ThreadContext *tc) = 0;
+ virtual FaultOffset offset64() = 0;
+ virtual OperatingMode nextMode() = 0;
+ virtual bool routeToMonitor(ThreadContext *tc) const = 0;
+ virtual bool routeToHyp(ThreadContext *tc) const { return false; }
+ virtual uint8_t armPcOffset(bool isHyp) = 0;
+ virtual uint8_t thumbPcOffset(bool isHyp) = 0;
+ virtual uint8_t armPcElrOffset() = 0;
+ virtual uint8_t thumbPcElrOffset() = 0;
+ virtual bool abortDisable(ThreadContext *tc) = 0;
+ virtual bool fiqDisable(ThreadContext *tc) = 0;
+ virtual ExceptionClass ec(ThreadContext *tc) const = 0;
+ virtual uint32_t iss() const = 0;
+ virtual bool isStage2() const { return false; }
+ virtual FSR getFsr(ThreadContext *tc) { return 0; }
+ virtual void setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg);
+};
+
+template<typename T>
+class ArmFaultVals : public ArmFault
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- bool isMachineCheckFault() {return true;}
-};
-
-class NonMaskableInterrupt : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- bool isNonMaskableInterrupt() {return true;}
-};
+ protected:
+ static FaultVals vals;
-class AlignmentFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- bool isAlignmentFault() {return true;}
-};
+ ArmFaultVals<T>(ExtMachInst _machInst = 0, uint32_t _iss = 0) :
+ ArmFault(_machInst, _iss) {}
+ FaultName name() const { return vals.name; }
+ FaultStat & countStat() { return vals.count; }
+ FaultOffset offset(ThreadContext *tc);
-class AddressErrorFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
+ FaultOffset
+ offset64()
+ {
+ if (toEL == fromEL) {
+ if (opModeIsT(fromMode))
+ return vals.currELTOffset;
+ return vals.currELHOffset;
+ } else {
+ if (from64)
+ return vals.lowerEL64Offset;
+ return vals.lowerEL32Offset;
+ }
+ }
+ OperatingMode nextMode() { return vals.nextMode; }
+ virtual bool routeToMonitor(ThreadContext *tc) const { return false; }
+ uint8_t armPcOffset(bool isHyp) { return isHyp ? vals.armPcElrOffset
+ : vals.armPcOffset; }
+ uint8_t thumbPcOffset(bool isHyp) { return isHyp ? vals.thumbPcElrOffset
+ : vals.thumbPcOffset; }
+ uint8_t armPcElrOffset() { return vals.armPcElrOffset; }
+ uint8_t thumbPcElrOffset() { return vals.thumbPcElrOffset; }
+ virtual bool abortDisable(ThreadContext* tc) { return vals.abortDisable; }
+ virtual bool fiqDisable(ThreadContext* tc) { return vals.fiqDisable; }
+ virtual ExceptionClass ec(ThreadContext *tc) const { return vals.ec; }
+ virtual uint32_t iss() const { return issRaw; }
};
-class StoreAddressErrorFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-};
-class UnimplementedOpcodeFault : public ArmFault
+class Reset : public ArmFaultVals<Reset>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
+ void invoke(ThreadContext *tc, const StaticInstPtr &inst =
+ StaticInst::nullStaticInstPtr);
};
-
-class TLBRefillIFetchFault : public ArmFault
+class UndefinedInstruction : public ArmFaultVals<UndefinedInstruction>
{
- private:
- Addr vaddr;
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-class TLBInvalidIFetchFault : public ArmFault
+ protected:
+ bool unknown;
+ bool disabled;
+ ExceptionClass overrideEc;
+ const char *mnemonic;
+
+ public:
+ UndefinedInstruction(ExtMachInst _machInst,
+ bool _unknown,
+ const char *_mnemonic = NULL,
+ bool _disabled = false) :
+ ArmFaultVals<UndefinedInstruction>(_machInst),
+ unknown(_unknown), disabled(_disabled),
+ overrideEc(EC_INVALID), mnemonic(_mnemonic)
+ {}
+ UndefinedInstruction(ExtMachInst _machInst, uint32_t _iss,
+ ExceptionClass _overrideEc, const char *_mnemonic = NULL) :
+ ArmFaultVals<UndefinedInstruction>(_machInst, _iss),
+ unknown(false), disabled(true), overrideEc(_overrideEc),
+ mnemonic(_mnemonic)
+ {}
+
+ void invoke(ThreadContext *tc, const StaticInstPtr &inst =
+ StaticInst::nullStaticInstPtr);
+ bool routeToHyp(ThreadContext *tc) const;
+ ExceptionClass ec(ThreadContext *tc) const;
+ uint32_t iss() const;
+};
+
+class SupervisorCall : public ArmFaultVals<SupervisorCall>
{
- private:
- Addr vaddr;
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
+ protected:
+ ExceptionClass overrideEc;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
+ SupervisorCall(ExtMachInst _machInst, uint32_t _iss,
+ ExceptionClass _overrideEc = EC_INVALID) :
+ ArmFaultVals<SupervisorCall>(_machInst, _iss),
+ overrideEc(_overrideEc)
+ {}
-class NDtbMissFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
+ void invoke(ThreadContext *tc, const StaticInstPtr &inst =
+ StaticInst::nullStaticInstPtr);
+ bool routeToHyp(ThreadContext *tc) const;
+ ExceptionClass ec(ThreadContext *tc) const;
+ uint32_t iss() const;
};
-class PDtbMissFault : public ArmFault
+class SecureMonitorCall : public ArmFaultVals<SecureMonitorCall>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
+ SecureMonitorCall(ExtMachInst _machInst) :
+ ArmFaultVals<SecureMonitorCall>(_machInst)
+ {}
-class DtbPageFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
+ void invoke(ThreadContext *tc, const StaticInstPtr &inst =
+ StaticInst::nullStaticInstPtr);
+ ExceptionClass ec(ThreadContext *tc) const;
+ uint32_t iss() const;
};
-class DtbAcvFault : public ArmFault
+class SupervisorTrap : public ArmFaultVals<SupervisorTrap>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-};
+ protected:
+ ExtMachInst machInst;
+ ExceptionClass overrideEc;
-class CacheErrorFault : public ArmFault
-{
- private:
- Addr vaddr;
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-
-
-
+ SupervisorTrap(ExtMachInst _machInst, uint32_t _iss,
+ ExceptionClass _overrideEc = EC_INVALID) :
+ ArmFaultVals<SupervisorTrap>(_machInst, _iss),
+ overrideEc(_overrideEc)
+ {}
-static inline Fault genMachineCheckFault()
-{
- return new MachineCheckFault;
-}
+ ExceptionClass ec(ThreadContext *tc) const;
+};
-static inline Fault genAlignmentFault()
+class SecureMonitorTrap : public ArmFaultVals<SecureMonitorTrap>
{
- return new AlignmentFault;
-}
+ protected:
+ ExtMachInst machInst;
+ ExceptionClass overrideEc;
-class ResetFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
+ SecureMonitorTrap(ExtMachInst _machInst, uint32_t _iss,
+ ExceptionClass _overrideEc = EC_INVALID) :
+ ArmFaultVals<SecureMonitorTrap>(_machInst, _iss),
+ overrideEc(_overrideEc)
+ {}
-};
-class SystemCallFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
+ ExceptionClass ec(ThreadContext *tc) const;
};
-class SoftResetFault : public ArmFault
+class HypervisorCall : public ArmFaultVals<HypervisorCall>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-class DebugSingleStep : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
-class DebugInterrupt : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
+ HypervisorCall(ExtMachInst _machInst, uint32_t _imm);
};
-class CoprocessorUnusableFault : public ArmFault
+class HypervisorTrap : public ArmFaultVals<HypervisorTrap>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- int coProcID;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
- CoprocessorUnusableFault(int _procid){ coProcID = _procid;}
-};
+ protected:
+ ExtMachInst machInst;
+ ExceptionClass overrideEc;
-class ReservedInstructionFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
-};
+ HypervisorTrap(ExtMachInst _machInst, uint32_t _iss,
+ ExceptionClass _overrideEc = EC_INVALID) :
+ ArmFaultVals<HypervisorTrap>(_machInst, _iss),
+ overrideEc(_overrideEc)
+ {}
-class ThreadFault : public ArmFault
-{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
+ ExceptionClass ec(ThreadContext *tc) const;
};
-
-class ArithmeticFault : public ArmFault
+template <class T>
+class AbortFault : public ArmFaultVals<T>
{
protected:
- bool skipFaultingInstruction() {return true;}
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
- public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-};
+ /**
+ * The virtual address the fault occured at. If 2 stages of
+ * translation are being used then this is the intermediate
+ * physical address that is the starting point for the second
+ * stage of translation.
+ */
+ Addr faultAddr;
+ /**
+ * Original virtual address. If the fault was generated on the
+ * second stage of translation then this variable stores the
+ * virtual address used in the original stage 1 translation.
+ */
+ Addr OVAddr;
+ bool write;
+ TlbEntry::DomainType domain;
+ uint8_t source;
+ uint8_t srcEncoded;
+ bool stage2;
+ bool s1ptw;
+ ArmFault::TranMethod tranMethod;
-class InterruptFault : public ArmFault
-{
- protected:
- bool setRestartAddress() {return false;}
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
+ AbortFault(Addr _faultAddr, bool _write, TlbEntry::DomainType _domain,
+ uint8_t _source, bool _stage2,
+ ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran) :
+ faultAddr(_faultAddr), OVAddr(0), write(_write),
+ domain(_domain), source(_source), srcEncoded(0),
+ stage2(_stage2), s1ptw(false), tranMethod(_tranMethod)
+ {}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
+ void invoke(ThreadContext *tc, const StaticInstPtr &inst =
+ StaticInst::nullStaticInstPtr);
- //void invoke(ThreadContext * tc);
+ FSR getFsr(ThreadContext *tc);
+ bool abortDisable(ThreadContext *tc);
+ uint32_t iss() const;
+ bool isStage2() const { return stage2; }
+ void annotate(ArmFault::AnnotationIDs id, uint64_t val);
+ bool isMMUFault() const;
};
-class TrapFault : public ArmFault
+class PrefetchAbort : public AbortFault<PrefetchAbort>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
+ static const MiscRegIndex FsrIndex = MISCREG_IFSR;
+ static const MiscRegIndex FarIndex = MISCREG_IFAR;
+ static const MiscRegIndex HFarIndex = MISCREG_HIFAR;
+
+ PrefetchAbort(Addr _addr, uint8_t _source, bool _stage2 = false,
+ ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran) :
+ AbortFault<PrefetchAbort>(_addr, false, TlbEntry::DomainType::NoAccess,
+ _source, _stage2, _tranMethod)
+ {}
+
+ ExceptionClass ec(ThreadContext *tc) const;
+ // @todo: external aborts should be routed if SCR.EA == 1
+ bool routeToMonitor(ThreadContext *tc) const;
+ bool routeToHyp(ThreadContext *tc) const;
};
-class BreakpointFault : public ArmFault
+class DataAbort : public AbortFault<DataAbort>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
+ static const MiscRegIndex FsrIndex = MISCREG_DFSR;
+ static const MiscRegIndex FarIndex = MISCREG_DFAR;
+ static const MiscRegIndex HFarIndex = MISCREG_HDFAR;
+ bool isv;
+ uint8_t sas;
+ uint8_t sse;
+ uint8_t srt;
+
+ // AArch64 only
+ bool sf;
+ bool ar;
+
+ DataAbort(Addr _addr, TlbEntry::DomainType _domain, bool _write, uint8_t _source,
+ bool _stage2 = false, ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran) :
+ AbortFault<DataAbort>(_addr, _write, _domain, _source, _stage2,
+ _tranMethod),
+ isv(false), sas (0), sse(0), srt(0), sf(false), ar(false)
+ {}
+
+ ExceptionClass ec(ThreadContext *tc) const;
+ // @todo: external aborts should be routed if SCR.EA == 1
+ bool routeToMonitor(ThreadContext *tc) const;
+ bool routeToHyp(ThreadContext *tc) const;
+ uint32_t iss() const;
+ void annotate(AnnotationIDs id, uint64_t val);
};
-class ItbRefillFault : public ArmFault
+class VirtualDataAbort : public AbortFault<VirtualDataAbort>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
+ static const MiscRegIndex FsrIndex = MISCREG_DFSR;
+ static const MiscRegIndex FarIndex = MISCREG_DFAR;
+ static const MiscRegIndex HFarIndex = MISCREG_HDFAR;
+
+ VirtualDataAbort(Addr _addr, TlbEntry::DomainType _domain, bool _write,
+ uint8_t _source) :
+ AbortFault<VirtualDataAbort>(_addr, _write, _domain, _source, false)
+ {}
+
+ void invoke(ThreadContext *tc, const StaticInstPtr &inst);
};
-class DtbRefillFault : public ArmFault
+
+class Interrupt : public ArmFaultVals<Interrupt>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
+ bool routeToMonitor(ThreadContext *tc) const;
+ bool routeToHyp(ThreadContext *tc) const;
+ bool abortDisable(ThreadContext *tc);
};
-class ItbPageFault : public ArmFault
+class VirtualInterrupt : public ArmFaultVals<VirtualInterrupt>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
+ VirtualInterrupt();
};
-class ItbInvalidFault : public ArmFault
+class FastInterrupt : public ArmFaultVals<FastInterrupt>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-
+ bool routeToMonitor(ThreadContext *tc) const;
+ bool routeToHyp(ThreadContext *tc) const;
+ bool abortDisable(ThreadContext *tc);
+ bool fiqDisable(ThreadContext *tc);
};
-class TLBModifiedFault : public ArmFault
+
+class VirtualFastInterrupt : public ArmFaultVals<VirtualFastInterrupt>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-
+ VirtualFastInterrupt();
};
-class DtbInvalidFault : public ArmFault
+/// PC alignment fault (AArch64 only)
+class PCAlignmentFault : public ArmFaultVals<PCAlignmentFault>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
+ protected:
+ /// The unaligned value of the PC
+ Addr faultPC;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
-#if FULL_SYSTEM
- void invoke(ThreadContext * tc);
-#endif
-
+ PCAlignmentFault(Addr _faultPC) : faultPC(_faultPC)
+ {}
+ void invoke(ThreadContext *tc, const StaticInstPtr &inst =
+ StaticInst::nullStaticInstPtr);
};
-class FloatEnableFault : public ArmFault
+/// Stack pointer alignment fault (AArch64 only)
+class SPAlignmentFault : public ArmFaultVals<SPAlignmentFault>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
+ SPAlignmentFault();
};
-class ItbMissFault : public ArmFault
+/// System error (AArch64 only)
+class SystemError : public ArmFaultVals<SystemError>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
+ SystemError();
+ void invoke(ThreadContext *tc, const StaticInstPtr &inst =
+ StaticInst::nullStaticInstPtr);
+ bool routeToMonitor(ThreadContext *tc) const;
+ bool routeToHyp(ThreadContext *tc) const;
};
-class ItbAcvFault : public ArmFault
+// A fault that flushes the pipe, excluding the faulting instructions
+class FlushPipe : public ArmFaultVals<FlushPipe>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
+ FlushPipe() {}
+ void invoke(ThreadContext *tc, const StaticInstPtr &inst =
+ StaticInst::nullStaticInstPtr);
};
-class IntegerOverflowFault : public ArmFault
+// A fault that flushes the pipe, excluding the faulting instructions
+class ArmSev : public ArmFaultVals<ArmSev>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
+ ArmSev () {}
+ void invoke(ThreadContext *tc, const StaticInstPtr &inst =
+ StaticInst::nullStaticInstPtr);
};
-class DspStateDisabledFault : public ArmFault
+/// Illegal Instruction Set State fault (AArch64 only)
+class IllegalInstSetStateFault : public ArmFaultVals<IllegalInstSetStateFault>
{
- private:
- static FaultName _name;
- static FaultVect _vect;
- static FaultStat _count;
public:
- FaultName name() const {return _name;}
- FaultVect vect() {return _vect;}
- FaultStat & countStat() {return _count;}
- void invoke(ThreadContext * tc);
+ IllegalInstSetStateFault();
};
-} // ArmISA namespace
+} // namespace ArmISA
#endif // __ARM_FAULTS_HH__