#!/usr/bin/env python3 # SPDX-License-Identifier: MIT import json, os, re from enum import IntEnum from utils import Register64, Register32 def load_registers(): for fname in ["arm_regs.json", "apple_regs.json"]: data = json.load(open(os.path.join(os.path.dirname(__file__), "..", "tools", fname))) for reg in data: yield reg["name"], tuple(reg["enc"]) sysreg_fwd = dict(load_registers()) sysreg_rev = {v: k for k, v in sysreg_fwd.items()} globals().update(sysreg_fwd) def sysreg_name(enc): if enc in sysreg_rev: return sysreg_rev[enc] return f"s{enc[0]}_{enc[1]}_c{enc[2]}_c{enc[3]}_{enc[4]}" def sysreg_parse(s): if isinstance(s, tuple) or isinstance(s, list): return tuple(s) s = s.strip() for r in (r"s(\d+)_(\d+)_c(\d+)_c(\d+)_(\d+)", r"(\d+), *(\d+), *(\d+), *(\d+), *(\d+)"): if m := re.match(r, s): enc = tuple(map(int, m.groups())) break else: try: enc = sysreg_fwd[s] except KeyError: raise Exception(f"Unknown sysreg name {s}") return enc class ESR_EC(IntEnum): UNKNOWN = 0b000000 WFI = 0b000001 FP_TRAP = 0b000111 PAUTH_TRAP = 0b001000 LS64 = 0b001010 BTI = 0b001101 ILLEGAL = 0b001110 SVC = 0b010101 HVC = 0b010110 SMC = 0b010111 MSR = 0b011000 SVE = 0b011001 PAUTH_FAIL = 0b011100 IABORT_LOWER = 0b100000 IABORT = 0b100001 PC_ALIGN = 0b100010 DABORT_LOWER = 0b100100 DABORT = 0b100101 SP_ALIGN = 0b100110 FP_EXC = 0b101100 SERROR = 0b101111 BKPT_LOWER = 0b110000 BKPT = 0b110001 SSTEP_LOWER = 0b110010 SSTEP = 0b110011 WATCH_LOWER = 0b110100 WATCH = 0b110101 BRK = 0b111100 IMPDEF = 0b111111 class MSR_DIR(IntEnum): WRITE = 0 READ = 1 class ESR_ISS_MSR(Register32): Op0 = 21, 20 Op2 = 19, 17 Op1 = 16, 14 CRn = 13, 10 Rt = 9, 5 CRm = 4, 1 DIR = 0, 0, MSR_DIR class DABORT_DFSC(IntEnum): ASIZE_L0 = 0b000000 ASIZE_L1 = 0b000001 ASIZE_L2 = 0b000010 ASIZE_L3 = 0b000011 XLAT_L0 = 0b000100 XLAT_L1 = 0b000101 XLAT_L2 = 0b000110 XLAT_L3 = 0b000111 AF_L0 = 0b001000 AF_L1 = 0b001001 AF_L2 = 0b001010 AF_L3 = 0b001011 PERM_L0 = 0b001100 PERM_L1 = 0b001101 PERM_L2 = 0b001110 PERM_L3 = 0b001111 EABORT = 0b010000 TAG_CHECK = 0b010001 PT_EABORT_Lm1 = 0b010011 PT_EABORT_L0 = 0b010100 PT_EABORT_L1 = 0b010101 PT_EABORT_L2 = 0b010110 PT_EABORT_L3 = 0b010111 ECC_ERROR = 0b011000 PT_ECC_ERROR_Lm1 = 0b011011 PT_ECC_ERROR_L0 = 0b011100 PT_ECC_ERROR_L1 = 0b011101 PT_ECC_ERROR_L2 = 0b011110 PT_ECC_ERROR_L3 = 0b011111 ALIGN = 0b100001 ASIZE_Lm1 = 0b101001 XLAT_Lm1 = 0b101011 TLB_CONFLICT = 0b110000 UNSUPP_ATOMIC = 0b110001 IMPDEF_LOCKDOWN = 0b110100 IMPDEF_ATOMIC = 0b110101 class ESR_ISS_DABORT(Register32): ISV = 24 SAS = 23, 22 SSE = 21 SRT = 20, 16 SF = 15 AR = 14 VNCR = 13 SET = 12, 11 LSR = 12, 11 FnV = 10 EA = 9 CM = 8 S1PTR = 7 WnR = 6 DFSC = 5, 0, DABORT_DFSC class ESR(Register64): ISS2 = 36, 32 EC = 31, 26, ESR_EC IL = 25 ISS = 24, 0 class SPSR_M(IntEnum): EP0t = 0 EL1t = 4 EL1h = 5 EL2t = 8 EL2h = 9 class SPSR(Register64): N = 31 Z = 30 C = 29 V = 28 TCO = 25 DIT = 24 UAO = 23 PAN = 22 SS = 21 IL = 20 SSBS = 12 BTYPE = 11, 10 D = 9 A = 8 I = 7 F = 6 M = 4, 0, SPSR_M class ACTLR(Register64): EnMDSB = 12 EnPRSV = 6 EnAFP = 5 EnAPFLG = 4 DisHWP = 3 EnTSO = 1 class HCR(Register64): TWEDEL = 63, 60 TWEDEn = 59 TID5 = 58 DCT = 57 ATA = 56 TTLBOS = 55 TTLBIS = 54 EnSCXT = 53 TOCU = 52 AMVOFFEN = 51 TICAB = 50 TID4 = 49 FIEN = 47 FWB = 46 NV2 = 45 AT = 44 NV1 = 43 NV1 = 43 NV = 42 NV = 42 API = 41 APK = 40 MIOCNCE = 38 TEA = 37 TERR = 36 TLOR = 35 E2H = 34 ID = 33 CD = 32 RW = 31 TRVM = 30 HCD = 29 TDZ = 28 TGE = 27 TVM = 26 TTLB = 25 TPU = 24 TPCP = 23 TPC = 23 TSW = 22 TACR = 21 TIDCP = 20 TSC = 19 TID3 = 18 TID2 = 17 TID1 = 16 TID0 = 15 TWE = 14 TWI = 13 DC = 12 BSU = 11, 10 FB = 9 VSE = 8 VI = 7 VF = 6 AMO = 5 IMO = 4 FMO = 3 PTW = 2 SWIO = 1 VM = 0 class HACR(Register64): TRAP_CPU_EXT = 0 TRAP_AIDR = 4 TRAP_AMX = 10 TRAP_SPRR = 11 TRAP_GXF = 13 TRAP_CTRR = 14 TRAP_IPI = 16 TRAP_s3_4_c15_c5z6_x = 18 TRAP_s3_4_c15_c0z12_5 = 19 GIC_CNTV = 20 TRAP_s3_4_c15_c10_4 = 25 TRAP_SERROR_INFO = 48 TRAP_EHID = 49 TRAP_HID = 50 TRAP_s3_0_c15_c12_1z2 = 51 TRAP_ACC = 52 TRAP_PM = 57 TRAP_UPM = 58 TRAP_s3_1z7_c15_cx_3 = 59 class AMX_CTL(Register64): EN = 63 EN_EL1 = 62