Skip to main content

aarch64defs/
lib.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! ARM64 type and constant definitions.
5
6#![expect(missing_docs)]
7#![forbid(unsafe_code)]
8#![no_std]
9
10pub mod gic;
11pub mod rsi;
12pub mod smccc;
13
14use bitfield_struct::bitfield;
15use core::fmt::Display;
16use open_enum::open_enum;
17use zerocopy::FromBytes;
18use zerocopy::Immutable;
19use zerocopy::IntoBytes;
20use zerocopy::KnownLayout;
21
22/// Aarch64 SPSR_EL2 register when in 64-bit mode. Usually called CPSR by
23/// hypervisors.
24#[bitfield(u64)]
25pub struct Cpsr64 {
26    /// PSTATE.SP
27    pub sp: bool,
28    _rsvd0: bool,
29    /// Exception Level
30    #[bits(2)]
31    pub el: u8,
32    /// Aarch32 mode. If set, this struct is the wrong one to interpret this
33    /// register.
34    pub aa32: bool,
35    _rsvd1: bool,
36    pub f: bool,
37    pub i: bool,
38    pub a: bool,
39    pub d: bool,
40    #[bits(2)]
41    pub btype: u8,
42    pub ssbs: bool,
43    #[bits(7)]
44    _rsvd2: u8,
45    pub il: bool,
46    pub ss: bool,
47    pub pan: bool,
48    pub uao: bool,
49    pub dit: bool,
50    pub tco: bool,
51    #[bits(2)]
52    _rsvd3: u8,
53    pub v: bool,
54    pub c: bool,
55    pub z: bool,
56    pub n: bool,
57    pub res0: u32,
58}
59
60/// ESR_EL2, exception syndrome register.
61#[bitfield(u64)]
62#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
63pub struct EsrEl2 {
64    #[bits(6)]
65    pub lower_iss: u8,
66    pub wnr: bool,
67    #[bits(9)]
68    pub mid_iss: u16,
69    #[bits(5)]
70    pub b_srt: u8,
71    pub a: bool,
72    pub b: bool,
73    pub c: bool,
74    pub d: bool,
75    pub il: bool,
76    #[bits(6)]
77    pub ec: u8,
78    #[bits(5)]
79    pub iss2: u8,
80    #[bits(27)]
81    _rsvd: u32,
82}
83
84impl EsrEl2 {
85    pub fn is_write(&self) -> bool {
86        // The WNR bit is set for writes, not reads.
87        self.wnr()
88    }
89
90    pub fn is_read(&self) -> bool {
91        // The WNR bit is set for writes, not reads.
92        !self.wnr()
93    }
94
95    pub fn iss(&self) -> u32 {
96        u32::from(self.lower_iss())
97            | ((self.wnr() as u32) << 6)
98            | (u32::from(self.mid_iss()) << 7)
99            | (u32::from(self.b_srt()) << 16)
100            | ((self.a() as u32) << 21)
101            | ((self.b() as u32) << 22)
102            | ((self.c() as u32) << 23)
103            | ((self.d() as u32) << 24)
104    }
105
106    pub fn srt(&self) -> Option<u8> {
107        // The SRT field is only valid for data aborts.
108        if (ExceptionClass::DATA_ABORT_LOWER.0..ExceptionClass::DATA_ABORT.0).contains(&self.ec()) {
109            Some(self.b_srt())
110        } else {
111            None
112        }
113    }
114}
115
116/// aarch64 SCTRL_EL1
117#[bitfield(u64)]
118#[derive(PartialEq, Eq)]
119pub struct SctlrEl1 {
120    pub m: bool,
121    pub a: bool,
122    pub c: bool,
123    pub sa: bool,
124    pub sa0: bool,
125    pub cp15ben: bool,
126    pub n_aa: bool,
127    pub itd: bool,
128    pub sed: bool,
129    pub uma: bool,
130    pub en_rctx: bool,
131    pub eos: bool,
132    pub i: bool,
133    pub en_db: bool,
134    pub dze: bool,
135    pub uct: bool,
136    pub n_twi: bool,
137    _mbz0: bool,
138    pub n_twe: bool,
139    pub wxn: bool,
140    pub tscxt: bool,
141    pub iesb: bool,
142    pub eis: bool,
143    pub span: bool,
144    pub e0e: bool,
145    pub ee: bool,
146    pub uci: bool,
147    pub en_da: bool,
148    pub n_tlsmd: bool,
149    pub lsmaoe: bool,
150    pub en_ib: bool,
151    pub en_ia: bool,
152    pub cmow: bool,
153    pub msc_en: bool,
154    _mbz1: bool,
155    pub bt0: bool,
156    pub bt1: bool,
157    pub itfsb: bool,
158    #[bits(2)]
159    pub tcf0: u64,
160    #[bits(2)]
161    pub tcf: u64,
162    pub ata0: bool,
163    pub ata: bool,
164    pub dssbs: bool,
165    pub twed_en: bool,
166    #[bits(4)]
167    pub twedel: u64,
168    pub tmt0: bool,
169    pub tmt: bool,
170    pub tme0: bool,
171    pub tme: bool,
172    pub en_asr: bool,
173    pub en_as0: bool,
174    pub en_als: bool,
175    pub epan: bool,
176    pub tcso0: bool,
177    pub tcso: bool,
178    pub en_tp2: bool,
179    pub nmi: bool,
180    pub spintmask: bool,
181    pub tidcp: bool,
182}
183
184/// aarch64 HPFAR_EL2
185#[bitfield(u64)]
186#[derive(PartialEq, Eq)]
187pub struct HpfarEl2 {
188    #[bits(4)]
189    pub res0: u8,
190    #[bits(44)]
191    pub fipa: u64,
192    #[bits(15)]
193    pub res1: u32,
194    pub ns: bool,
195}
196
197open_enum! {
198    pub enum ExceptionClass: u8 {
199        UNKNOWN = 0b000000,
200        WFI = 0b000001,
201        MCR_MRC_COPROC_15 = 0b000011,
202        MCRR_MRRC_COPROC_15 = 0b000100,
203        MCR_MRC_COPROC_14 = 0b000101,
204        LDC_STC = 0b000110,
205        FP_OR_SIMD = 0b000111,
206        VMRS = 0b001000,
207        POINTER_AUTH_HCR_OR_SCR = 0b001001,
208        LS64 = 0b001010,
209        MRRC_COPROC_14 = 0b001100,
210        BRANCH_TARGET = 0b001101,
211        ILLEGAL_STATE = 0b001110,
212        SVC32 = 0b010001,
213        HVC32 = 0b010010,
214        SMC32 = 0b010011,
215        SVC = 0b010101,
216        HVC = 0b010110,
217        SMC = 0b010111,
218        SYSTEM = 0b011000,
219        SVE = 0b011001,
220        ERET = 0b011010,
221        TSTART = 0b011011,
222        POINTER_AUTH = 0b011100,
223        SME = 0b011101,
224        INSTRUCTION_ABORT_LOWER = 0b100000,
225        INSTRUCTION_ABORT = 0b100001,
226        PC_ALIGNMENT = 0b100010,
227        DATA_ABORT_LOWER = 0b100100,
228        DATA_ABORT = 0b100101,
229        SP_ALIGNMENT_FAULT = 0b100110,
230        MEMORY_OP = 0b100111,
231        FP_EXCEPTION_32 = 0b101000,
232        FP_EXCEPTION_64 = 0b101100,
233        SERROR = 0b101111,
234        BREAKPOINT_LOWER = 0b110000,
235        BREAKPOINT = 0b110001,
236        STEP_LOWER = 0b110010,
237        STEP = 0b110011,
238        WATCHPOINT_LOWER = 0b110100,
239        WATCHPOINT = 0b110101,
240        BRK32 = 0b111000,
241        VECTOR_CATCH_32 = 0b111010,
242        BRK = 0b111100,
243    }
244}
245
246#[bitfield(u32)]
247pub struct IssDataAbort {
248    #[bits(6)]
249    pub dfsc: FaultStatusCode,
250    // Write operation (write not read)
251    pub wnr: bool,
252    pub s1ptw: bool,
253    pub cm: bool,
254    pub ea: bool,
255    /// FAR not valid
256    pub fnv: bool,
257    #[bits(2)]
258    pub set: u8,
259    pub vncr: bool,
260    /// Acquire/release
261    pub ar: bool,
262    /// (ISV==1) 64-bit, (ISV==0) FAR is approximate
263    pub sf: bool,
264    #[bits(5)]
265    /// Register index.
266    pub srt: u8,
267    /// Sign extended.
268    pub sse: bool,
269    #[bits(2)]
270    /// access width log2
271    pub sas: u8,
272    /// Valid ESREL2 iss field.
273    pub isv: bool,
274    #[bits(7)]
275    _unused: u8,
276}
277
278impl From<IssDataAbort> for EsrEl2 {
279    fn from(abort_code: IssDataAbort) -> Self {
280        let val: u32 = abort_code.into();
281        let iss = val & 0x07ff_ffff;
282        EsrEl2::new()
283            .with_ec(ExceptionClass::DATA_ABORT.0)
284            .with_lower_iss((iss & 0x3f) as u8)
285            .with_wnr(((iss >> 6) & 1) != 0)
286            .with_mid_iss(((iss >> 7) & 0x1ff) as u16)
287            .with_b_srt(((iss >> 16) & 0x1F) as u8)
288            .with_a(((iss >> 21) & 0x1) != 0)
289            .with_b(((iss >> 22) & 0x1) != 0)
290            .with_c(((iss >> 23) & 0x1) != 0)
291            .with_d(((iss >> 24) & 0x1) != 0)
292            .with_iss2((val >> 27) as u8)
293    }
294}
295
296open_enum! {
297    pub enum FaultStatusCode: u8 {
298        ADDRESS_SIZE_FAULT_LEVEL0 = 0b000000,
299        ADDRESS_SIZE_FAULT_LEVEL1 = 0b000001,
300        ADDRESS_SIZE_FAULT_LEVEL2 = 0b000010,
301        ADDRESS_SIZE_FAULT_LEVEL3 = 0b000011,
302        TRANSLATION_FAULT_LEVEL0 = 0b000100,
303        TRANSLATION_FAULT_LEVEL1 = 0b000101,
304        TRANSLATION_FAULT_LEVEL2 = 0b000110,
305        TRANSLATION_FAULT_LEVEL3 = 0b000111,
306        ACCESS_FLAG_FAULT_LEVEL0 = 0b001000,
307        ACCESS_FLAG_FAULT_LEVEL1 = 0b001001,
308        ACCESS_FLAG_FAULT_LEVEL2 = 0b001010,
309        ACCESS_FLAG_FAULT_LEVEL3 = 0b001011,
310        PERMISSION_FAULT_LEVEL0 = 0b001100,
311        PERMISSION_FAULT_LEVEL1 = 0b001101,
312        PERMISSION_FAULT_LEVEL2 = 0b001110,
313        PERMISSION_FAULT_LEVEL3 = 0b001111,
314        SYNCHRONOUS_EXTERNAL_ABORT = 0b010000,
315        SYNC_TAG_CHECK_FAULT = 0b010001,
316        SEA_TTW_LEVEL_NEG1 = 0b010011,
317        SEA_TTW_LEVEL0 = 0b010100,
318        SEA_TTW_LEVEL1 = 0b010101,
319        SEA_TTW_LEVEL2 = 0b010110,
320        SEA_TTW_LEVEL3 = 0b010111,
321        ECC_PARITY = 0b011000,
322        ECC_PARITY_TTW_LEVEL_NEG1 = 0b011011,
323        ECC_PARITY_TTW_LEVEL0 = 0b011100,
324        ECC_PARITY_TTW_LEVEL1 = 0b011101,
325        ECC_PARITY_TTW_LEVEL2 = 0b011110,
326        ECC_PARITY_TTW_LEVEL3 = 0b011111,
327        /// Valid only for data fault.
328        ALIGNMENT_FAULT = 0b100001,
329        /// Valid only for instruction fault.
330        GRANULE_PROTECTION_FAULT_LEVEL_NEG = 0b100011,
331        /// Valid only for instruction fault.
332        GRANULE_PROTECTION_FAULT_LEVEL0 = 0b100100,
333        /// Valid only for instruction fault.
334        GRANULE_PROTECTION_FAULT_LEVEL1 = 0b100101,
335        /// Valid only for instruction fault.
336        GRANULE_PROTECTION_FAULT_LEVEL2 = 0b100110,
337        /// Valid only for instruction fault.
338        GRANULE_PROTECTION_FAULT_LEVEL3 = 0b100111,
339        ADDRESS_SIZE_FAULT_LEVEL_NEG1 = 0b101001,
340        TRANSLATION_FAULT_LEVEL_NEG1 = 0b101011,
341        TLB_CONFLICT_ABORT = 0b110000,
342        UNSUPPORTED_HW_UPDATE_FAULT = 0b110001,
343    }
344}
345
346/// Support for embedding within IssDataAbort/IssInstructionAbort
347impl FaultStatusCode {
348    const fn from_bits(bits: u32) -> Self {
349        FaultStatusCode((bits & 0x3f) as u8)
350    }
351
352    const fn into_bits(self) -> u32 {
353        self.0 as u32
354    }
355}
356
357#[bitfield(u32)]
358pub struct IssInstructionAbort {
359    #[bits(6)]
360    pub ifsc: FaultStatusCode,
361    #[bits(1)]
362    _rsvd: u8,
363    /// Stage 2 translation fault
364    pub s1ptw: bool,
365    #[bits(1)]
366    _rsvd2: u8,
367    /// External abort
368    pub ea: bool,
369    /// FAR not valid
370    pub fnv: bool,
371    #[bits(2)]
372    pub set: SynchronousErrorType,
373    #[bits(11)]
374    _rsvd3: u16,
375    #[bits(8)]
376    _unused: u8,
377}
378
379impl From<IssInstructionAbort> for EsrEl2 {
380    fn from(instruction_code: IssInstructionAbort) -> Self {
381        let val: u32 = instruction_code.into();
382        let iss = val & 0x07ff_ffff;
383
384        EsrEl2::new()
385            .with_ec(ExceptionClass::INSTRUCTION_ABORT.0)
386            .with_lower_iss((iss & 0x3f) as u8)
387            .with_wnr(((iss >> 6) & 1) != 0)
388            .with_mid_iss(((iss >> 7) & 0x1ff) as u16)
389            .with_b_srt(((iss >> 16) & 0x1F) as u8)
390            .with_a(((iss >> 21) & 0x1) != 0)
391            .with_b(((iss >> 22) & 0x1) != 0)
392            .with_c(((iss >> 23) & 0x1) != 0)
393            .with_d(((iss >> 24) & 0x1) != 0)
394            .with_iss2((val >> 27) as u8)
395    }
396}
397
398open_enum! {
399    pub enum SynchronousErrorType: u8 {
400        RECOVERABLE = 0,
401        UNCONTAINABLE = 2,
402        RESTARTABLE = 3,
403    }
404}
405
406/// Support for embedding within IssInstructionAbort
407impl SynchronousErrorType {
408    const fn from_bits(bits: u32) -> Self {
409        SynchronousErrorType((bits & 0x1800) as u8)
410    }
411
412    const fn into_bits(self) -> u32 {
413        (self.0 as u32) << 11
414    }
415}
416
417#[bitfield(u32)]
418pub struct IssSystem {
419    pub direction: bool,
420    #[bits(4)]
421    pub crm: u8,
422    #[bits(5)]
423    pub rt: u8,
424    #[bits(4)]
425    pub crn: u8,
426    #[bits(3)]
427    pub op1: u8,
428    #[bits(3)]
429    pub op2: u8,
430    #[bits(2)]
431    pub op0: u8,
432    #[bits(10)]
433    _unused: u32,
434}
435
436impl IssSystem {
437    pub const fn system_reg(&self) -> SystemReg {
438        SystemReg(
439            SystemRegEncoding::new()
440                .with_op0(self.op0())
441                .with_op1(self.op1())
442                .with_crn(self.crn())
443                .with_crm(self.crm())
444                .with_op2(self.op2()),
445        )
446    }
447}
448
449#[bitfield(u32)]
450#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
451pub struct SystemRegEncoding {
452    #[bits(5)]
453    _rsvd: u32,
454    #[bits(3)]
455    pub op2: u8,
456    #[bits(4)]
457    pub crm: u8,
458    #[bits(4)]
459    pub crn: u8,
460    #[bits(3)]
461    pub op1: u8,
462    #[bits(2)]
463    pub op0: u8,
464    #[bits(11)]
465    _rsvd2: u32,
466}
467
468open_enum! {
469    pub enum SystemReg: SystemRegEncoding {
470        SPSR_EL1 = SystemRegEncoding::make(3, 0, 4, 0, 0),
471        SPSR_EL2 = SystemRegEncoding::make(3, 4, 4, 0, 0),
472        SPSR_EL3 = SystemRegEncoding::make(3, 6, 4, 0, 0),
473        ELR_EL1 = SystemRegEncoding::make(3, 0, 4, 0, 1),
474        ELR_EL2 = SystemRegEncoding::make(3, 4, 4, 0, 1),
475        ELR_EL3 = SystemRegEncoding::make(3, 6, 4, 0, 1),
476        SP_EL0 = SystemRegEncoding::make(3, 0, 4, 1, 0),
477        SP_EL1 = SystemRegEncoding::make(3, 4, 4, 1, 0),
478        SP_EL2 = SystemRegEncoding::make(3, 6, 4, 1, 0),
479        FPSR = SystemRegEncoding::make(3, 3, 4, 4, 1),
480        FPCR = SystemRegEncoding::make(3, 3, 4, 4, 0),
481        SPSR_ABT = SystemRegEncoding::make(3, 4, 4, 3, 1),
482        IFSR32_EL2 = SystemRegEncoding::make(3, 4, 5, 0, 1),
483
484        VPIDR_EL2 = SystemRegEncoding::make(3, 4, 0, 0, 0),
485        MPIDR_EL1 = SystemRegEncoding::make(3, 0, 0, 0, 5),
486        ARM64_REVIDR_EL1 = SystemRegEncoding::make(3, 0, 0, 0, 6),
487        CTR_EL0 = SystemRegEncoding::make(3, 3, 0, 0, 1),
488        ARM64_VMPIDR_EL2 = SystemRegEncoding::make(3, 4, 0, 0, 5),
489        ID_AA64PFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 4, 0),
490        ID_AA64PFR1_EL1 = SystemRegEncoding::make(3, 0, 0, 4, 1),
491        ID_AA64DFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 5, 0),
492        ID_AA64DFR1_EL1 = SystemRegEncoding::make(3, 0, 0, 5, 1),
493        ID_AA64AFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 5, 4),
494        ID_AA64AFR1_EL1 = SystemRegEncoding::make(3, 0, 0, 5, 5),
495        ID_AA64ISAR0_EL1 = SystemRegEncoding::make(3, 0, 0, 6, 0),
496        ID_AA64ISAR1_EL1 = SystemRegEncoding::make(3, 0, 0, 6, 1),
497        ID_AA64MMFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 7, 0),
498        ID_AA64MMFR1_EL1 = SystemRegEncoding::make(3, 0, 0, 7, 1),
499        ID_AA64MMFR2_EL1 = SystemRegEncoding::make(3, 0, 0, 7, 2),
500
501        ID_MMFR0 = SystemRegEncoding::make(3, 0, 0, 1, 4),
502        ID_MMFR1 = SystemRegEncoding::make(3, 0, 0, 1, 5),
503        ID_MMFR2 = SystemRegEncoding::make(3, 0, 0, 1, 6),
504        ID_MMFR3 = SystemRegEncoding::make(3, 0, 0, 1, 7),
505        ID_MMFR4 = SystemRegEncoding::make(3, 0, 0, 2, 6),
506        ID_ISAR0 = SystemRegEncoding::make(3, 0, 0, 2, 0),
507        ID_ISAR1 = SystemRegEncoding::make(3, 0, 0, 2, 1),
508        ID_ISAR2 = SystemRegEncoding::make(3, 0, 0, 2, 2),
509        ID_ISAR3 = SystemRegEncoding::make(3, 0, 0, 2, 3),
510        ID_ISAR4 = SystemRegEncoding::make(3, 0, 0, 2, 4),
511        ID_ISAR5 = SystemRegEncoding::make(3, 0, 0, 2, 5),
512        ID_ISAR6 = SystemRegEncoding::make(3, 0, 0, 2, 7),
513        MVFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 3, 0),
514        MVFR1_EL1 = SystemRegEncoding::make(3, 3, 0, 0, 1),
515        MVFR2_EL1 = SystemRegEncoding::make(3, 3, 0, 0, 2),
516        ID_AA64ZFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 4, 4),
517        DACR32_EL2 = SystemRegEncoding::make(3, 4, 3, 0, 0),
518        FPEXC32_EL2 = SystemRegEncoding::make(3, 4, 5, 3, 0),
519        VMPIDR_EL2 = SystemRegEncoding::make(3, 4, 0, 0, 5),
520
521        SCTLR = SystemRegEncoding::make(3, 0, 1, 0, 0),
522        SCTLR_EL2 = SystemRegEncoding::make(3, 4, 1, 0, 0),
523        HCR_EL2 = SystemRegEncoding::make(3, 4, 1, 1, 0),
524        HSTR_EL2 = SystemRegEncoding::make(3, 4, 1, 1, 3),
525        HACR_EL2 = SystemRegEncoding::make(3, 4, 1, 1, 7),
526        ACTLR_EL1 = SystemRegEncoding::make(3, 0, 1, 0, 1),
527        ACTLR_EL2 = SystemRegEncoding::make(3, 4, 1, 0, 1),
528        CPACR = SystemRegEncoding::make(3, 0, 1, 0, 2),
529        CPTR_EL2 = SystemRegEncoding::make(3, 4, 1, 1, 2),
530        CPUECTLR_EL1 = SystemRegEncoding::make(3, 0, 15, 1, 4),
531        CNTPS_CTL_EL1 = SystemRegEncoding::make(3, 7, 14, 2, 1),
532        CPUMERRSR_EL1 = SystemRegEncoding::make(3, 1, 15, 2, 2),
533        CNTPS_CVAL_EL1 = SystemRegEncoding::make(3, 7, 14, 2, 2),
534        L2MERRSR_EL1 = SystemRegEncoding::make(3, 1, 15, 2, 3),
535
536        TTBR0_EL1 = SystemRegEncoding::make(3, 0, 2, 0, 0),
537        TTBR0_EL2 = SystemRegEncoding::make(3, 4, 2, 0, 0),
538        TTBR1_EL1 = SystemRegEncoding::make(3, 0, 2, 0, 1),
539        VTTBR_EL2 = SystemRegEncoding::make(3, 4, 2, 1, 0),
540        TCR_EL1 = SystemRegEncoding::make(3, 0, 2, 0, 2),
541        TCR_EL2 = SystemRegEncoding::make(3, 4, 2, 0, 2),
542        VTCR_EL2 = SystemRegEncoding::make(3, 4, 2, 1, 2),
543        ESR_EL1 = SystemRegEncoding::make(3, 0, 5, 2, 0),
544        ESR_EL2 = SystemRegEncoding::make(3, 4, 5, 2, 0),
545        ESR_EL3 = SystemRegEncoding::make(3, 6, 5, 2, 0),
546        FAR_EL1 = SystemRegEncoding::make(3, 0, 6, 0, 0),
547        FAR_EL2 = SystemRegEncoding::make(3, 4, 6, 0, 0),
548        HPFAR_EL2 = SystemRegEncoding::make(3, 4, 6, 0, 4),
549        AFSR0_EL1 = SystemRegEncoding::make(3, 0, 5, 1, 0),
550        AFSR0_EL2 = SystemRegEncoding::make(3, 4, 5, 1, 0),
551        AFSR1_EL1 = SystemRegEncoding::make(3, 0, 5, 1, 1),
552        AFSR1_EL2 = SystemRegEncoding::make(3, 4, 5, 1, 1),
553
554        PAR_EL1 = SystemRegEncoding::make(3, 0, 7, 4, 0),
555        CNTFRQ_EL0 = SystemRegEncoding::make(3, 3, 14, 0, 0),
556        CNTPCT_EL0 = SystemRegEncoding::make(3, 3, 14, 0, 1),
557        CNTVCT_EL0 = SystemRegEncoding::make(3, 3, 14, 0, 2),
558        CNTP_CTL_EL0 = SystemRegEncoding::make(3, 3, 14, 2, 1),
559        CNTP_CVAL_EL0 = SystemRegEncoding::make(3, 3, 14, 2, 2),
560        CNTV_CTL_EL0 = SystemRegEncoding::make(3, 3, 14, 3, 1),
561        CNTV_CVAL_EL0 = SystemRegEncoding::make(3, 3, 14, 3, 2),
562        CNTHCTL_EL2 = SystemRegEncoding::make(3, 4, 14, 1, 0),
563        CNTHP_CTL_EL2 = SystemRegEncoding::make(3, 4, 14, 2, 1),
564        CNTHP_CVAL_EL2 = SystemRegEncoding::make(3, 4, 14, 2, 2),
565        PMCCFILTR_EL0 = SystemRegEncoding::make(3, 3, 14, 15, 7),
566        MDCR_EL2 = SystemRegEncoding::make(3, 4, 1, 1, 1),
567        PMCR_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 0),
568        PMCNTENSET_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 1),
569        PMCNTENCLR_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 2),
570        PMOVSSET_EL0 = SystemRegEncoding::make(3, 3, 9, 14, 3),
571        PMOVSCLR_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 3),
572        PMSELR_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 5),
573        PMCEID0_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 6),
574        PMCEID1_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 7),
575        PMCCNTR_EL0 = SystemRegEncoding::make(3, 3, 9, 13, 0),
576        PMUSERENR_EL0 = SystemRegEncoding::make(3, 3, 9, 14, 0),
577        PMINTENSET_EL1 = SystemRegEncoding::make(3, 0, 9, 14, 1),
578        PMINTENCLR_EL1 = SystemRegEncoding::make(3, 0, 9, 14, 2),
579
580        MAIR_EL1 = SystemRegEncoding::make(3, 0, 10, 2, 0),
581        AMAIR0 = SystemRegEncoding::make(3, 0, 10, 3, 0),
582        MAIR_EL2 = SystemRegEncoding::make(3, 4, 10, 2, 0),
583        AMAIR_EL2 = SystemRegEncoding::make(3, 4, 10, 3, 0),
584        MAIR_EL3 = SystemRegEncoding::make(3, 6, 10, 2, 0),
585
586        VBAR = SystemRegEncoding::make(3, 0, 12, 0, 0),
587        VBAR_EL2 = SystemRegEncoding::make(3, 4, 12, 0, 0),
588        RVBAR_EL2 = SystemRegEncoding::make(3, 4, 12, 0, 1),
589
590        TPIDR_EL0 = SystemRegEncoding::make(3, 3, 13, 0, 2),
591        TPIDRRO_EL0 = SystemRegEncoding::make(3, 3, 13, 0, 3),
592        TPIDR_EL1 = SystemRegEncoding::make(3, 0, 13, 0, 4),
593        TPIDR_EL2 = SystemRegEncoding::make(3, 4, 13, 0, 2),
594        CONTEXTIDR_EL1 = SystemRegEncoding::make(3, 0, 13, 0, 1),
595
596        CLIDR = SystemRegEncoding::make(3, 1, 0, 0, 1),
597        AIDR = SystemRegEncoding::make(3, 1, 0, 0, 7),
598        CSSELR = SystemRegEncoding::make(3, 2, 0, 0, 0),
599
600        CNTKCTL = SystemRegEncoding::make(3, 0, 14, 1, 0),
601        CNTVOFF_EL2 = SystemRegEncoding::make(3, 4, 14, 0, 3),
602
603        MDCCSR_EL0 = SystemRegEncoding::make(2, 3, 0, 1, 0),
604        MDSCR_EL1 = SystemRegEncoding::make(2, 0, 0, 2, 2),
605        MDRAR_EL1 = SystemRegEncoding::make(2, 0, 1, 0, 0),
606        OSLSR_EL1 = SystemRegEncoding::make(2, 0, 1, 1, 4),
607        DBGBVR0 = SystemRegEncoding::make(2, 0, 0, 0, 4),
608        DBGBVR1 = SystemRegEncoding::make(2, 0, 0, 1, 4),
609        DBGBVR2 = SystemRegEncoding::make(2, 0, 0, 2, 4),
610        DBGBVR3 = SystemRegEncoding::make(2, 0, 0, 3, 4),
611        DBGBVR4 = SystemRegEncoding::make(2, 0, 0, 4, 4),
612        DBGBVR5 = SystemRegEncoding::make(2, 0, 0, 5, 4),
613        DBGBCR0 = SystemRegEncoding::make(2, 0, 0, 0, 5),
614        DBGBCR1 = SystemRegEncoding::make(2, 0, 0, 1, 5),
615        DBGBCR2 = SystemRegEncoding::make(2, 0, 0, 2, 5),
616        DBGBCR3 = SystemRegEncoding::make(2, 0, 0, 3, 5),
617        DBGBCR4 = SystemRegEncoding::make(2, 0, 0, 4, 5),
618        DBGBCR5 = SystemRegEncoding::make(2, 0, 0, 5, 5),
619        DBGWVR0 = SystemRegEncoding::make(2, 0, 0, 0, 6),
620        DBGWVR1 = SystemRegEncoding::make(2, 0, 0, 1, 6),
621        DBGWVR2 = SystemRegEncoding::make(2, 0, 0, 2, 6),
622        DBGWVR3 = SystemRegEncoding::make(2, 0, 0, 3, 6),
623        DBGWCR0 = SystemRegEncoding::make(2, 0, 0, 0, 7),
624        DBGWCR1 = SystemRegEncoding::make(2, 0, 0, 1, 7),
625        DBGWCR2 = SystemRegEncoding::make(2, 0, 0, 2, 7),
626        DBGWCR3 = SystemRegEncoding::make(2, 0, 0, 3, 7),
627
628        ICC_AP0R0_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 4),
629        ICC_AP0R1_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 5),
630        ICC_AP0R2_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 6),
631        ICC_AP0R3_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 7),
632        ICC_AP1R0_EL1 = SystemRegEncoding::make(3, 0, 12, 9, 0),
633        ICC_AP1R1_EL1 = SystemRegEncoding::make(3, 0, 12, 9, 1),
634        ICC_AP1R2_EL1 = SystemRegEncoding::make(3, 0, 12, 9, 2),
635        ICC_AP1R3_EL1 = SystemRegEncoding::make(3, 0, 12, 9, 3),
636        ICC_ASGI1R_EL1 = SystemRegEncoding::make(3, 0, 12, 11, 6),
637        ICC_BPR0_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 3),
638        ICC_BPR1_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 3),
639        ICC_CTLR_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 4),
640        ICC_CTLR_EL3 = SystemRegEncoding::make(3, 6, 12, 12, 4),
641        ICC_DIR_EL1 = SystemRegEncoding::make(3, 0, 12, 11, 1),
642        ICC_EOIR0_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 1),
643        ICC_EOIR1_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 1),
644        ICC_HPPIR0_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 2),
645        ICC_HPPIR1_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 2),
646        ICC_IAR0_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 0),
647        ICC_IAR1_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 0),
648        ICC_IGRPEN0_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 6),
649        ICC_IGRPEN1_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 7),
650        ICC_IGRPEN1_EL3 = SystemRegEncoding::make(3, 6, 12, 12, 7),
651        ICC_PMR_EL1 = SystemRegEncoding::make(3, 0, 4, 6, 0),
652        ICC_RPR_EL1 = SystemRegEncoding::make(3, 0, 12, 11, 3),
653        ICC_SGI0R_EL1 = SystemRegEncoding::make(3, 0, 12, 11, 7),
654        ICC_SGI1R_EL1 = SystemRegEncoding::make(3, 0, 12, 11, 5),
655        ICC_SRE_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 5),
656        ICC_SRE_EL2 = SystemRegEncoding::make(3, 4, 12, 9, 5),
657        ICC_SRE_EL3 = SystemRegEncoding::make(3, 6, 12, 12, 5),
658    }
659}
660
661impl SystemRegEncoding {
662    pub const fn make(op0: u8, op1: u8, crn: u8, crm: u8, op2: u8) -> Self {
663        Self::new()
664            .with_op0(op0)
665            .with_op1(op1)
666            .with_crn(crn)
667            .with_crm(crm)
668            .with_op2(op2)
669    }
670}
671
672/// MPIDR_EL1
673#[bitfield(u64)]
674pub struct MpidrEl1 {
675    pub aff0: u8,
676    pub aff1: u8,
677    pub aff2: u8,
678    pub mt: bool,
679    #[bits(5)]
680    pub res0_25_29: u8,
681    pub u: bool,
682    pub res1_31: bool,
683    pub aff3: u8,
684    #[bits(24)]
685    pub res0_40_63: u32,
686}
687
688impl MpidrEl1 {
689    pub const AFFINITY_MASK: Self = Self::new()
690        .with_aff0(0xff)
691        .with_aff1(0xff)
692        .with_aff2(0xff)
693        .with_aff3(0xff);
694}
695
696open_enum! {
697    /// aarch64 translation granule size for TTBR0_EL1
698    pub enum TranslationGranule0: u64 {
699        TG_4KB = 0b00,
700        TG_64KB = 0b01,
701        TG_16KB = 0b10,
702    }
703}
704
705impl TranslationGranule0 {
706    const fn into_bits(self) -> u64 {
707        self.0
708    }
709
710    const fn from_bits(bits: u64) -> Self {
711        Self(bits)
712    }
713}
714
715open_enum! {
716    /// aarch64 translation granule size for TTBR1_EL1
717    pub enum TranslationGranule1: u64 {
718        TG_INVALID = 0b00,
719        TG_16KB = 0b01,
720        TG_4KB = 0b10,
721        TG_64KB = 0b11,
722    }
723}
724
725impl TranslationGranule1 {
726    const fn into_bits(self) -> u64 {
727        self.0
728    }
729
730    const fn from_bits(bits: u64) -> Self {
731        Self(bits)
732    }
733}
734
735open_enum! {
736    /// aarch64 intermediate physical address size
737    pub enum IntermPhysAddrSize: u64{
738        IPA_32_BITS_4_GB = 0b000,
739        IPA_36_BITS_64_GB = 0b001,
740        IPA_40_BITS_1_TB = 0b010,
741        IPA_42_BITS_4_TB = 0b011,
742        IPA_44_BITS_16_TB = 0b100,
743        IPA_48_BITS_256_TB = 0b101,
744        IPA_52_BITS_4_PB = 0b110,
745        IPA_56_BITS_64_PB = 0b111,
746    }
747}
748
749impl IntermPhysAddrSize {
750    pub const fn from_ipa_bit_length(bits: u8) -> Option<Self> {
751        Some(match bits {
752            32 => Self::IPA_32_BITS_4_GB,
753            36 => Self::IPA_36_BITS_64_GB,
754            40 => Self::IPA_40_BITS_1_TB,
755            42 => Self::IPA_42_BITS_4_TB,
756            44 => Self::IPA_44_BITS_16_TB,
757            48 => Self::IPA_48_BITS_256_TB,
758            52 => Self::IPA_52_BITS_4_PB,
759            56 => Self::IPA_56_BITS_64_PB,
760            _ => return None,
761        })
762    }
763
764    const fn into_bits(self) -> u64 {
765        self.0
766    }
767
768    const fn from_bits(bits: u64) -> Self {
769        Self(bits)
770    }
771}
772
773open_enum! {
774    /// `ID_AA64PFR0_EL1.GIC`.
775    pub enum GicCpuInterface: u8 {
776        NONE = 0,
777        GICV3_OR_GICV4 = 1,
778    }
779}
780
781impl GicCpuInterface {
782    const fn into_bits(self) -> u64 {
783        self.0 as u64
784    }
785
786    const fn from_bits(bits: u64) -> Self {
787        Self(bits as u8)
788    }
789}
790
791/// The fields of `ID_AA64PFR0_EL1` used by virtual CPU policy.
792#[bitfield(u64)]
793pub struct ProcessorFeatures0El1 {
794    #[bits(8)]
795    _el0_el1: u8,
796    #[bits(4)]
797    pub el2: u8,
798    #[bits(4)]
799    pub el3: u8,
800    #[bits(8)]
801    _fp_simd: u8,
802    #[bits(4)]
803    pub gic: GicCpuInterface,
804    #[bits(4)]
805    _ras: u8,
806    #[bits(4)]
807    pub sve: u8,
808    #[bits(28)]
809    _rest: u32,
810}
811
812/// The fields of `ID_AA64PFR1_EL1` used by virtual CPU policy.
813#[bitfield(u64)]
814pub struct ProcessorFeatures1El1 {
815    #[bits(24)]
816    _lower: u32,
817    #[bits(4)]
818    pub sme: u8,
819    #[bits(36)]
820    _rest: u64,
821}
822
823/// The fields of `ID_AA64DFR0_EL1` used by virtual CPU policy.
824#[bitfield(u64)]
825pub struct DebugFeatures0El1 {
826    #[bits(8)]
827    _lower: u8,
828    #[bits(4)]
829    pub pmu_ver: u8,
830    #[bits(52)]
831    _rest: u64,
832}
833
834/// The fields of `ID_AA64MMFR2_EL1` used by virtual CPU policy.
835#[bitfield(u64)]
836pub struct MmFeatures2El1 {
837    #[bits(4)]
838    pub cnp: u8,
839    #[bits(20)]
840    _middle: u32,
841    #[bits(4)]
842    pub nv: u8,
843    #[bits(36)]
844    _rest: u64,
845}
846
847/// aarch64 TCR_EL1 register
848#[bitfield(u64)]
849#[derive(PartialEq, Eq)]
850pub struct TranslationControlEl1 {
851    #[bits(6)]
852    pub t0sz: u64,
853    #[bits(1)]
854    _mbz0: u64,
855    #[bits(1)]
856    pub epd0: u64,
857    #[bits(2)]
858    pub irgn0: u64,
859    #[bits(2)]
860    pub orgn0: u64,
861    #[bits(2)]
862    pub sh0: u64,
863    #[bits(2)]
864    pub tg0: TranslationGranule0,
865    #[bits(6)]
866    pub t1sz: u64,
867    #[bits(1)]
868    pub a1: u64,
869    #[bits(1)]
870    pub epd1: u64,
871    #[bits(2)]
872    pub irgn1: u64,
873    #[bits(2)]
874    pub orgn1: u64,
875    #[bits(2)]
876    pub sh1: u64,
877    #[bits(2)]
878    pub tg1: TranslationGranule1,
879    #[bits(3)]
880    pub ips: IntermPhysAddrSize,
881    #[bits(1)]
882    _mbz1: u64,
883    #[bits(1)]
884    pub a_s: u64,
885    #[bits(1)]
886    pub tbi0: u64,
887    #[bits(1)]
888    pub tbi1: u64,
889    #[bits(1)]
890    pub ha: u64,
891    #[bits(1)]
892    pub hd: u64,
893    #[bits(1)]
894    pub hpd0: u64,
895    #[bits(1)]
896    pub hpd1: u64,
897    #[bits(1)]
898    pub hwu059: u64,
899    #[bits(1)]
900    pub hwu060: u64,
901    #[bits(1)]
902    pub hwu061: u64,
903    #[bits(1)]
904    pub hwu062: u64,
905    #[bits(1)]
906    pub hwu159: u64,
907    #[bits(1)]
908    pub hwu160: u64,
909    #[bits(1)]
910    pub hwu161: u64,
911    #[bits(1)]
912    pub hwu162: u64,
913    #[bits(1)]
914    pub tbid0: u64,
915    #[bits(1)]
916    pub tbid1: u64,
917    #[bits(1)]
918    pub nfd0: u64,
919    #[bits(1)]
920    pub nfd1: u64,
921    #[bits(1)]
922    pub e0pd0: u64,
923    #[bits(1)]
924    pub e0pd1: u64,
925    #[bits(1)]
926    pub tcma0: u64,
927    #[bits(1)]
928    pub tcma1: u64,
929    #[bits(1)]
930    pub ds: u64,
931    #[bits(1)]
932    pub mtx0: u64,
933    #[bits(1)]
934    pub mtx1: u64,
935    #[bits(2)]
936    _mbz2: u64,
937}
938
939impl TranslationControlEl1 {
940    pub fn ttbr0_valid_address_bits(&self) -> u64 {
941        64 - self.t0sz()
942    }
943
944    pub fn ttbr1_valid_address_bits(&self) -> u64 {
945        64 - self.t1sz()
946    }
947}
948
949/// aarch64 TTBRx_EL1 content
950#[bitfield(u64)]
951#[derive(PartialEq, Eq)]
952pub struct TranslationBaseEl1 {
953    // Hardcoding CnP to be `0` for simplicity.
954    // #[bits(1)]
955    // pub cnp: u64,
956    #[bits(48)]
957    pub baddr: u64,
958    #[bits(16)]
959    pub asid: u64,
960}
961
962#[bitfield(u64)]
963#[derive(PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)]
964pub struct Pte {
965    pub valid: bool,
966    pub not_large_page: bool,
967    #[bits(3)]
968    pub attribute_index: u64,
969    pub non_secure: bool,
970    pub ap_unprivileged: bool,
971    pub ap_read_only: bool,
972    #[bits(2)]
973    pub shareability: u64,
974    pub access_flag: bool,
975    pub not_global: bool,
976    #[bits(36)]
977    pub pfn: u64,
978    #[bits(3)]
979    pub reserved_must_be_zero: u64,
980    pub dbm: bool,
981    pub contiguous_hint: bool,
982    pub privilege_no_execute: bool,
983    pub user_no_execute: bool,
984    #[bits(4)]
985    pub _reserved2: u64,
986    pub pxn_table: bool,
987    pub uxn_table: bool,
988    pub ap_table_privileged_only: bool,
989    pub ap_table_read_only: bool,
990    pub ns_table: bool,
991}
992
993/// The contents of ID_MMFR0_EL1
994#[bitfield(u64)]
995pub struct MmFeatures0El1 {
996    #[bits(4)]
997    pub pa_range: IntermPhysAddrSize,
998    #[bits(60)]
999    _rest: u64,
1000}
1001
1002pub const GIC_DISTRIBUTOR_SIZE: u64 = 0x1_0000;
1003pub const GIC_REDISTRIBUTOR_FRAME_SIZE: u64 = 0x1_0000;
1004pub const GIC_SGI_FRAME_SIZE: u64 = 0x1_0000;
1005pub const GIC_REDISTRIBUTOR_SIZE: u64 = GIC_REDISTRIBUTOR_FRAME_SIZE + GIC_SGI_FRAME_SIZE;
1006
1007// GICv2 sizes.
1008pub const GIC_V2_DISTRIBUTOR_SIZE: u64 = 0x1000;
1009pub const GIC_V2_CPU_INTERFACE_SIZE: u64 = 0x2000;
1010
1011open_enum! {
1012    pub enum SystemReset2Code: u32 {
1013        WARM_RESET = 0,
1014    }
1015}
1016
1017open_enum! {
1018    pub enum SystemOff2Code: u32 {
1019        DEFAULT = 0,
1020        HIBERNATE_OFF = 1,
1021    }
1022}
1023
1024#[derive(Debug, PartialEq, Eq, Copy, Clone)]
1025pub struct Vendor(pub u32);
1026
1027impl Vendor {
1028    pub const ARM: Self = Self(0x0010);
1029
1030    pub fn is_arm_compatible(&self) -> bool {
1031        *self == Self::ARM
1032    }
1033
1034    // Intel and Amd compatible checkers are still implemented and return false.
1035    // By this, some generic code do NOT diverge on AArch64.
1036    pub fn is_intel_compatible(&self) -> bool {
1037        false
1038    }
1039
1040    // Likewise
1041    pub fn is_amd_compatible(&self) -> bool {
1042        false
1043    }
1044}
1045
1046impl Display for Vendor {
1047    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1048        if self.is_arm_compatible() {
1049            f.pad("Arm")
1050        } else {
1051            write!(f, "{:#x}", self.0)
1052        }
1053    }
1054}
1055
1056#[derive(Debug, Clone, Copy)]
1057pub enum InstructionAbortReason {
1058    AddressSizeFaultLevel0,
1059    AddressSizeFaultLevel1,
1060    AddressSizeFaultLevel2,
1061    AddressSizeFaultLevel3,
1062    TranslationFaultLevel0,
1063    TranslationFaultLevel1,
1064    TranslationFaultLevel2,
1065    TranslationFaultLevel3,
1066    AccessFlagFaultLevel0,
1067    AccessFlagFaultLevel1,
1068    AccessFlagFaultLevel2,
1069    AccessFlagFaultLevel3,
1070    PermissionFaultLevel0,
1071    PermissionFaultLevel1,
1072    PermissionFaultLevel2,
1073    PermissionFaultLevel3,
1074    SynchronousExternalAbort,
1075    SyncTagCheckFault,
1076    SynchronousExternalAbortOnTableWalkLevelNeg1,
1077    SynchronousExternalAbortOnTableWalkLevel0,
1078    SynchronousExternalAbortOnTableWalkLevel1,
1079    SynchronousExternalAbortOnTableWalkLevel2,
1080    SynchronousExternalAbortOnTableWalkLevel3,
1081    EccParity,
1082    EccParityOnTableWalkLevelNeg1,
1083    EccParityOnTableWalkLevel0,
1084    EccParityOnTableWalkLevel1,
1085    EccParityOnTableWalkLevel2,
1086    EccParityOnTableWalkLevel3,
1087    GranuleProtectionFaultLevelNeg1,
1088    GranuleProtectionFaultLevel0,
1089    GranuleProtectionFaultLevel1,
1090    GranuleProtectionFaultLevel2,
1091    GranuleProtectionFaultLevel3,
1092    AddressSizeFaultLevelNeg1,
1093    TranslationFaultLevelNeg1,
1094    TlbConflictAbort,
1095    UnsupportedHardwareUpdateFault,
1096    Unknown,
1097}
1098
1099impl From<FaultStatusCode> for InstructionAbortReason {
1100    fn from(value: FaultStatusCode) -> Self {
1101        match value {
1102            FaultStatusCode::ADDRESS_SIZE_FAULT_LEVEL0 => Self::AddressSizeFaultLevel0,
1103            FaultStatusCode::ADDRESS_SIZE_FAULT_LEVEL1 => Self::AddressSizeFaultLevel1,
1104            FaultStatusCode::ADDRESS_SIZE_FAULT_LEVEL2 => Self::AddressSizeFaultLevel2,
1105            FaultStatusCode::ADDRESS_SIZE_FAULT_LEVEL3 => Self::AddressSizeFaultLevel3,
1106            FaultStatusCode::TRANSLATION_FAULT_LEVEL0 => Self::TranslationFaultLevel0,
1107            FaultStatusCode::TRANSLATION_FAULT_LEVEL1 => Self::TranslationFaultLevel1,
1108            FaultStatusCode::TRANSLATION_FAULT_LEVEL2 => Self::TranslationFaultLevel2,
1109            FaultStatusCode::TRANSLATION_FAULT_LEVEL3 => Self::TranslationFaultLevel3,
1110            FaultStatusCode::ACCESS_FLAG_FAULT_LEVEL0 => Self::AccessFlagFaultLevel0,
1111            FaultStatusCode::ACCESS_FLAG_FAULT_LEVEL1 => Self::AccessFlagFaultLevel1,
1112            FaultStatusCode::ACCESS_FLAG_FAULT_LEVEL2 => Self::AccessFlagFaultLevel2,
1113            FaultStatusCode::ACCESS_FLAG_FAULT_LEVEL3 => Self::AccessFlagFaultLevel3,
1114            FaultStatusCode::PERMISSION_FAULT_LEVEL0 => Self::PermissionFaultLevel0,
1115            FaultStatusCode::PERMISSION_FAULT_LEVEL1 => Self::PermissionFaultLevel1,
1116            FaultStatusCode::PERMISSION_FAULT_LEVEL2 => Self::PermissionFaultLevel2,
1117            FaultStatusCode::PERMISSION_FAULT_LEVEL3 => Self::PermissionFaultLevel3,
1118            FaultStatusCode::SYNCHRONOUS_EXTERNAL_ABORT => Self::SynchronousExternalAbort,
1119            FaultStatusCode::SYNC_TAG_CHECK_FAULT => Self::SyncTagCheckFault,
1120            FaultStatusCode::SEA_TTW_LEVEL_NEG1 => {
1121                Self::SynchronousExternalAbortOnTableWalkLevelNeg1
1122            }
1123            FaultStatusCode::SEA_TTW_LEVEL0 => Self::SynchronousExternalAbortOnTableWalkLevel0,
1124            FaultStatusCode::SEA_TTW_LEVEL1 => Self::SynchronousExternalAbortOnTableWalkLevel1,
1125            FaultStatusCode::SEA_TTW_LEVEL2 => Self::SynchronousExternalAbortOnTableWalkLevel2,
1126            FaultStatusCode::SEA_TTW_LEVEL3 => Self::SynchronousExternalAbortOnTableWalkLevel3,
1127            FaultStatusCode::ECC_PARITY => Self::EccParity,
1128            FaultStatusCode::ECC_PARITY_TTW_LEVEL_NEG1 => Self::EccParityOnTableWalkLevelNeg1,
1129            FaultStatusCode::ECC_PARITY_TTW_LEVEL0 => Self::EccParityOnTableWalkLevel0,
1130            FaultStatusCode::ECC_PARITY_TTW_LEVEL1 => Self::EccParityOnTableWalkLevel1,
1131            FaultStatusCode::ECC_PARITY_TTW_LEVEL2 => Self::EccParityOnTableWalkLevel2,
1132            FaultStatusCode::ECC_PARITY_TTW_LEVEL3 => Self::EccParityOnTableWalkLevel3,
1133            FaultStatusCode::GRANULE_PROTECTION_FAULT_LEVEL_NEG => {
1134                Self::GranuleProtectionFaultLevelNeg1
1135            }
1136            FaultStatusCode::GRANULE_PROTECTION_FAULT_LEVEL0 => Self::GranuleProtectionFaultLevel0,
1137            FaultStatusCode::GRANULE_PROTECTION_FAULT_LEVEL1 => Self::GranuleProtectionFaultLevel1,
1138            FaultStatusCode::GRANULE_PROTECTION_FAULT_LEVEL2 => Self::GranuleProtectionFaultLevel2,
1139            FaultStatusCode::GRANULE_PROTECTION_FAULT_LEVEL3 => Self::GranuleProtectionFaultLevel3,
1140            FaultStatusCode::ADDRESS_SIZE_FAULT_LEVEL_NEG1 => Self::AddressSizeFaultLevelNeg1,
1141            FaultStatusCode::TRANSLATION_FAULT_LEVEL_NEG1 => Self::TranslationFaultLevelNeg1,
1142            FaultStatusCode::TLB_CONFLICT_ABORT => Self::TlbConflictAbort,
1143            FaultStatusCode::UNSUPPORTED_HW_UPDATE_FAULT => Self::UnsupportedHardwareUpdateFault,
1144            _ => Self::Unknown,
1145        }
1146    }
1147}