+uint8_t ArmFault::shortDescFaultSources[] = {
+ 0x01, // AlignmentFault
+ 0x04, // InstructionCacheMaintenance
+ 0xff, // SynchExtAbtOnTranslTableWalkL0 (INVALID)
+ 0x0c, // SynchExtAbtOnTranslTableWalkL1
+ 0x0e, // SynchExtAbtOnTranslTableWalkL2
+ 0xff, // SynchExtAbtOnTranslTableWalkL3 (INVALID)
+ 0xff, // SynchPtyErrOnTranslTableWalkL0 (INVALID)
+ 0x1c, // SynchPtyErrOnTranslTableWalkL1
+ 0x1e, // SynchPtyErrOnTranslTableWalkL2
+ 0xff, // SynchPtyErrOnTranslTableWalkL3 (INVALID)
+ 0xff, // TranslationL0 (INVALID)
+ 0x05, // TranslationL1
+ 0x07, // TranslationL2
+ 0xff, // TranslationL3 (INVALID)
+ 0xff, // AccessFlagL0 (INVALID)
+ 0x03, // AccessFlagL1
+ 0x06, // AccessFlagL2
+ 0xff, // AccessFlagL3 (INVALID)
+ 0xff, // DomainL0 (INVALID)
+ 0x09, // DomainL1
+ 0x0b, // DomainL2
+ 0xff, // DomainL3 (INVALID)
+ 0xff, // PermissionL0 (INVALID)
+ 0x0d, // PermissionL1
+ 0x0f, // PermissionL2
+ 0xff, // PermissionL3 (INVALID)
+ 0x02, // DebugEvent
+ 0x08, // SynchronousExternalAbort
+ 0x10, // TLBConflictAbort
+ 0x19, // SynchPtyErrOnMemoryAccess
+ 0x16, // AsynchronousExternalAbort
+ 0x18, // AsynchPtyErrOnMemoryAccess
+ 0xff, // AddressSizeL0 (INVALID)
+ 0xff, // AddressSizeL1 (INVALID)
+ 0xff, // AddressSizeL2 (INVALID)
+ 0xff, // AddressSizeL3 (INVALID)
+ 0x40, // PrefetchTLBMiss
+ 0x80 // PrefetchUncacheable
+};
+
+static_assert(sizeof(ArmFault::shortDescFaultSources) ==
+ ArmFault::NumFaultSources,
+ "Invalid size of ArmFault::shortDescFaultSources[]");
+
+uint8_t ArmFault::longDescFaultSources[] = {
+ 0x21, // AlignmentFault
+ 0xff, // InstructionCacheMaintenance (INVALID)
+ 0xff, // SynchExtAbtOnTranslTableWalkL0 (INVALID)
+ 0x15, // SynchExtAbtOnTranslTableWalkL1
+ 0x16, // SynchExtAbtOnTranslTableWalkL2
+ 0x17, // SynchExtAbtOnTranslTableWalkL3
+ 0xff, // SynchPtyErrOnTranslTableWalkL0 (INVALID)
+ 0x1d, // SynchPtyErrOnTranslTableWalkL1
+ 0x1e, // SynchPtyErrOnTranslTableWalkL2
+ 0x1f, // SynchPtyErrOnTranslTableWalkL3
+ 0xff, // TranslationL0 (INVALID)
+ 0x05, // TranslationL1
+ 0x06, // TranslationL2
+ 0x07, // TranslationL3
+ 0xff, // AccessFlagL0 (INVALID)
+ 0x09, // AccessFlagL1
+ 0x0a, // AccessFlagL2
+ 0x0b, // AccessFlagL3
+ 0xff, // DomainL0 (INVALID)
+ 0x3d, // DomainL1
+ 0x3e, // DomainL2
+ 0xff, // DomainL3 (RESERVED)
+ 0xff, // PermissionL0 (INVALID)
+ 0x0d, // PermissionL1
+ 0x0e, // PermissionL2
+ 0x0f, // PermissionL3
+ 0x22, // DebugEvent
+ 0x10, // SynchronousExternalAbort
+ 0x30, // TLBConflictAbort
+ 0x18, // SynchPtyErrOnMemoryAccess
+ 0x11, // AsynchronousExternalAbort
+ 0x19, // AsynchPtyErrOnMemoryAccess
+ 0xff, // AddressSizeL0 (INVALID)
+ 0xff, // AddressSizeL1 (INVALID)
+ 0xff, // AddressSizeL2 (INVALID)
+ 0xff, // AddressSizeL3 (INVALID)
+ 0x40, // PrefetchTLBMiss
+ 0x80 // PrefetchUncacheable
+};
+
+static_assert(sizeof(ArmFault::longDescFaultSources) ==
+ ArmFault::NumFaultSources,
+ "Invalid size of ArmFault::longDescFaultSources[]");
+
+uint8_t ArmFault::aarch64FaultSources[] = {
+ 0x21, // AlignmentFault
+ 0xff, // InstructionCacheMaintenance (INVALID)
+ 0x14, // SynchExtAbtOnTranslTableWalkL0
+ 0x15, // SynchExtAbtOnTranslTableWalkL1
+ 0x16, // SynchExtAbtOnTranslTableWalkL2
+ 0x17, // SynchExtAbtOnTranslTableWalkL3
+ 0x1c, // SynchPtyErrOnTranslTableWalkL0
+ 0x1d, // SynchPtyErrOnTranslTableWalkL1
+ 0x1e, // SynchPtyErrOnTranslTableWalkL2
+ 0x1f, // SynchPtyErrOnTranslTableWalkL3
+ 0x04, // TranslationL0
+ 0x05, // TranslationL1
+ 0x06, // TranslationL2
+ 0x07, // TranslationL3
+ 0x08, // AccessFlagL0
+ 0x09, // AccessFlagL1
+ 0x0a, // AccessFlagL2
+ 0x0b, // AccessFlagL3
+ // @todo: Section & Page Domain Fault in AArch64?
+ 0xff, // DomainL0 (INVALID)
+ 0xff, // DomainL1 (INVALID)
+ 0xff, // DomainL2 (INVALID)
+ 0xff, // DomainL3 (INVALID)
+ 0x0c, // PermissionL0
+ 0x0d, // PermissionL1
+ 0x0e, // PermissionL2
+ 0x0f, // PermissionL3
+ 0xff, // DebugEvent (INVALID)
+ 0x10, // SynchronousExternalAbort
+ 0x30, // TLBConflictAbort
+ 0x18, // SynchPtyErrOnMemoryAccess
+ 0xff, // AsynchronousExternalAbort (INVALID)
+ 0xff, // AsynchPtyErrOnMemoryAccess (INVALID)
+ 0x00, // AddressSizeL0
+ 0x01, // AddressSizeL1
+ 0x02, // AddressSizeL2
+ 0x03, // AddressSizeL3
+ 0x40, // PrefetchTLBMiss
+ 0x80 // PrefetchUncacheable
+};
+
+static_assert(sizeof(ArmFault::aarch64FaultSources) ==
+ ArmFault::NumFaultSources,
+ "Invalid size of ArmFault::aarch64FaultSources[]");
+
+// Fields: name, offset, cur{ELT,ELH}Offset, lowerEL{64,32}Offset, next mode,
+// {ARM, Thumb, ARM_ELR, Thumb_ELR} PC offset, hyp trap,
+// {A, F} disable, class, stat
+template<> ArmFault::FaultVals ArmFaultVals<Reset>::vals = {
+ // Some dummy values (the reset vector has an IMPLEMENTATION DEFINED
+ // location in AArch64)
+ "Reset", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC,
+ 0, 0, 0, 0, false, true, true, EC_UNKNOWN, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals = {
+ "Undefined Instruction", 0x004, 0x000, 0x200, 0x400, 0x600, MODE_UNDEFINED,
+ 4, 2, 0, 0, true, false, false, EC_UNKNOWN, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals = {
+ "Supervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
+ 4, 2, 4, 2, true, false, false, EC_SVC_TO_HYP, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<SecureMonitorCall>::vals = {
+ "Secure Monitor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_MON,
+ 4, 4, 4, 4, false, true, true, EC_SMC_TO_HYP, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<HypervisorCall>::vals = {
+ "Hypervisor Call", 0x008, 0x000, 0x200, 0x400, 0x600, MODE_HYP,
+ 4, 4, 4, 4, true, false, false, EC_HVC, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals = {
+ "Prefetch Abort", 0x00C, 0x000, 0x200, 0x400, 0x600, MODE_ABORT,
+ 4, 4, 0, 0, true, true, false, EC_PREFETCH_ABORT_TO_HYP, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals = {
+ "Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600, MODE_ABORT,
+ 8, 8, 0, 0, true, true, false, EC_DATA_ABORT_TO_HYP, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<VirtualDataAbort>::vals = {
+ "Virtual Data Abort", 0x010, 0x000, 0x200, 0x400, 0x600, MODE_ABORT,
+ 8, 8, 0, 0, true, true, false, EC_INVALID, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<HypervisorTrap>::vals = {
+ // @todo: double check these values
+ "Hypervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_HYP,
+ 0, 0, 0, 0, false, false, false, EC_UNKNOWN, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals = {
+ "IRQ", 0x018, 0x080, 0x280, 0x480, 0x680, MODE_IRQ,
+ 4, 4, 0, 0, false, true, false, EC_UNKNOWN, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<VirtualInterrupt>::vals = {
+ "Virtual IRQ", 0x018, 0x080, 0x280, 0x480, 0x680, MODE_IRQ,
+ 4, 4, 0, 0, false, true, false, EC_INVALID, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals = {
+ "FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700, MODE_FIQ,
+ 4, 4, 0, 0, false, true, true, EC_UNKNOWN, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<VirtualFastInterrupt>::vals = {
+ "Virtual FIQ", 0x01C, 0x100, 0x300, 0x500, 0x700, MODE_FIQ,
+ 4, 4, 0, 0, false, true, true, EC_INVALID, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<SupervisorTrap>::vals = {
+ // Some dummy values (SupervisorTrap is AArch64-only)
+ "Supervisor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
+ 0, 0, 0, 0, false, false, false, EC_UNKNOWN, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<SecureMonitorTrap>::vals = {
+ // Some dummy values (SecureMonitorTrap is AArch64-only)
+ "Secure Monitor Trap", 0x014, 0x000, 0x200, 0x400, 0x600, MODE_MON,
+ 0, 0, 0, 0, false, false, false, EC_UNKNOWN, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<PCAlignmentFault>::vals = {
+ // Some dummy values (PCAlignmentFault is AArch64-only)
+ "PC Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
+ 0, 0, 0, 0, true, false, false, EC_PC_ALIGNMENT, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<SPAlignmentFault>::vals = {
+ // Some dummy values (SPAlignmentFault is AArch64-only)
+ "SP Alignment Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
+ 0, 0, 0, 0, true, false, false, EC_STACK_PTR_ALIGNMENT, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<SystemError>::vals = {
+ // Some dummy values (SError is AArch64-only)
+ "SError", 0x000, 0x180, 0x380, 0x580, 0x780, MODE_SVC,
+ 0, 0, 0, 0, false, true, true, EC_SERROR, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<FlushPipe>::vals = {
+ // Some dummy values
+ "Pipe Flush", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC,
+ 0, 0, 0, 0, false, true, true, EC_UNKNOWN, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals = {
+ // Some dummy values
+ "ArmSev Flush", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC,
+ 0, 0, 0, 0, false, true, true, EC_UNKNOWN, FaultStat()
+};
+template<> ArmFault::FaultVals ArmFaultVals<IllegalInstSetStateFault>::vals = {
+ // Some dummy values (SPAlignmentFault is AArch64-only)
+ "Illegal Inst Set State Fault", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
+ 0, 0, 0, 0, true, false, false, EC_ILLEGAL_INST, FaultStat()
+};
+
+Addr
+ArmFault::getVector(ThreadContext *tc)
+{
+ Addr base;