1#![expect(missing_docs)]
7#![forbid(unsafe_code)]
8#![no_std]
9
10pub mod gic;
11pub mod smccc;
12
13use bitfield_struct::bitfield;
14use open_enum::open_enum;
15use zerocopy::FromBytes;
16use zerocopy::Immutable;
17use zerocopy::IntoBytes;
18use zerocopy::KnownLayout;
19
20#[bitfield(u64)]
23pub struct Cpsr64 {
24 pub sp: bool,
26 _rsvd0: bool,
27 #[bits(2)]
29 pub el: u8,
30 pub aa32: bool,
33 _rsvd1: bool,
34 pub f: bool,
35 pub i: bool,
36 pub a: bool,
37 pub d: bool,
38 #[bits(2)]
39 pub btype: u8,
40 pub ssbs: bool,
41 #[bits(7)]
42 _rsvd2: u8,
43 pub il: bool,
44 pub ss: bool,
45 pub pan: bool,
46 pub uao: bool,
47 pub dit: bool,
48 pub tco: bool,
49 #[bits(2)]
50 _rsvd3: u8,
51 pub v: bool,
52 pub c: bool,
53 pub z: bool,
54 pub n: bool,
55 pub res0: u32,
56}
57
58#[bitfield(u64)]
60#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
61pub struct EsrEl2 {
62 #[bits(25)]
63 pub iss: u32,
64 pub il: bool,
65 #[bits(6)]
66 pub ec: u8,
67 #[bits(5)]
68 pub iss2: u8,
69 #[bits(27)]
70 _rsvd: u32,
71}
72
73#[bitfield(u64)]
75#[derive(PartialEq, Eq)]
76pub struct SctlrEl1 {
77 pub m: bool,
78 pub a: bool,
79 pub c: bool,
80 pub sa: bool,
81 pub sa0: bool,
82 pub cp15ben: bool,
83 pub n_aa: bool,
84 pub itd: bool,
85 pub sed: bool,
86 pub uma: bool,
87 pub en_rctx: bool,
88 pub eos: bool,
89 pub i: bool,
90 pub en_db: bool,
91 pub dze: bool,
92 pub uct: bool,
93 pub n_twi: bool,
94 _mbz0: bool,
95 pub n_twe: bool,
96 pub wxn: bool,
97 pub tscxt: bool,
98 pub iesb: bool,
99 pub eis: bool,
100 pub span: bool,
101 pub e0e: bool,
102 pub ee: bool,
103 pub uci: bool,
104 pub en_da: bool,
105 pub n_tlsmd: bool,
106 pub lsmaoe: bool,
107 pub en_ib: bool,
108 pub en_ia: bool,
109 pub cmow: bool,
110 pub msc_en: bool,
111 _mbz1: bool,
112 pub bt0: bool,
113 pub bt1: bool,
114 pub itfsb: bool,
115 #[bits(2)]
116 pub tcf0: u64,
117 #[bits(2)]
118 pub tcf: u64,
119 pub ata0: bool,
120 pub ata: bool,
121 pub dssbs: bool,
122 pub twed_en: bool,
123 #[bits(4)]
124 pub twedel: u64,
125 pub tmt0: bool,
126 pub tmt: bool,
127 pub tme0: bool,
128 pub tme: bool,
129 pub en_asr: bool,
130 pub en_as0: bool,
131 pub en_als: bool,
132 pub epan: bool,
133 pub tcso0: bool,
134 pub tcso: bool,
135 pub en_tp2: bool,
136 pub nmi: bool,
137 pub spintmask: bool,
138 pub tidcp: bool,
139}
140
141open_enum! {
142 pub enum ExceptionClass: u8 {
143 UNKNOWN = 0b000000,
144 WFI = 0b000001,
145 MCR_MRC_COPROC_15 = 0b000011,
146 MCRR_MRRC_COPROC_15 = 0b000100,
147 MCR_MRC_COPROC_14 = 0b000101,
148 LDC_STC = 0b000110,
149 FP_OR_SIMD = 0b000111,
150 VMRS = 0b001000,
151 POINTER_AUTH_HCR_OR_SCR = 0b001001,
152 LS64 = 0b001010,
153 MRRC_COPROC_14 = 0b001100,
154 BRANCH_TARGET = 0b001101,
155 ILLEGAL_STATE = 0b001110,
156 SVC32 = 0b010001,
157 HVC32 = 0b010010,
158 SMC32 = 0b010011,
159 SVC = 0b010101,
160 HVC = 0b010110,
161 SMC = 0b010111,
162 SYSTEM = 0b011000,
163 SVE = 0b011001,
164 ERET = 0b011010,
165 TSTART = 0b011011,
166 POINTER_AUTH = 0b011100,
167 SME = 0b011101,
168 INSTRUCTION_ABORT_LOWER = 0b100000,
169 INSTRUCTION_ABORT = 0b100001,
170 PC_ALIGNMENT = 0b100010,
171 DATA_ABORT_LOWER = 0b100100,
172 DATA_ABORT = 0b100101,
173 SP_ALIGNMENT_FAULT = 0b100110,
174 MEMORY_OP = 0b100111,
175 FP_EXCEPTION_32 = 0b101000,
176 FP_EXCEPTION_64 = 0b101100,
177 SERROR = 0b101111,
178 BREAKPOINT_LOWER = 0b110000,
179 BREAKPOINT = 0b110001,
180 STEP_LOWER = 0b110010,
181 STEP = 0b110011,
182 WATCHPOINT_LOWER = 0b110100,
183 WATCHPOINT = 0b110101,
184 BRK32 = 0b111000,
185 VECTOR_CATCH_32 = 0b111010,
186 BRK = 0b111100,
187 }
188}
189
190#[bitfield(u32)]
191pub struct IssDataAbort {
192 #[bits(6)]
193 pub dfsc: FaultStatusCode,
194 pub wnr: bool,
196 pub s1ptw: bool,
197 pub cm: bool,
198 pub ea: bool,
199 pub fnv: bool,
201 #[bits(2)]
202 pub set: u8,
203 pub vncr: bool,
204 pub ar: bool,
206 pub sf: bool,
208 #[bits(5)]
209 pub srt: u8,
211 pub sse: bool,
213 #[bits(2)]
214 pub sas: u8,
216 pub isv: bool,
218 #[bits(7)]
219 _unused: u8,
220}
221
222impl From<IssDataAbort> for EsrEl2 {
223 fn from(abort_code: IssDataAbort) -> Self {
224 let val: u32 = abort_code.into();
225 EsrEl2::new()
226 .with_ec(ExceptionClass::DATA_ABORT.0)
227 .with_iss(val & 0x07ffffff)
228 .with_iss2((val >> 27) as u8)
229 }
230}
231
232open_enum! {
233 pub enum FaultStatusCode: u8 {
234 ADDRESS_SIZE_FAULT_LEVEL0 = 0b000000,
235 ADDRESS_SIZE_FAULT_LEVEL1 = 0b000001,
236 ADDRESS_SIZE_FAULT_LEVEL2 = 0b000010,
237 ADDRESS_SIZE_FAULT_LEVEL3 = 0b000011,
238 TRANSLATION_FAULT_LEVEL0 = 0b000100,
239 TRANSLATION_FAULT_LEVEL1 = 0b000101,
240 TRANSLATION_FAULT_LEVEL2 = 0b000110,
241 TRANSLATION_FAULT_LEVEL3 = 0b000111,
242 ACCESS_FLAG_FAULT_LEVEL0 = 0b001000,
243 ACCESS_FLAG_FAULT_LEVEL1 = 0b001001,
244 ACCESS_FLAG_FAULT_LEVEL2 = 0b001010,
245 ACCESS_FLAG_FAULT_LEVEL3 = 0b001011,
246 PERMISSION_FAULT_LEVEL0 = 0b001100,
247 PERMISSION_FAULT_LEVEL1 = 0b001101,
248 PERMISSION_FAULT_LEVEL2 = 0b001110,
249 PERMISSION_FAULT_LEVEL3 = 0b001111,
250 SYNCHRONOUS_EXTERNAL_ABORT = 0b010000,
251 SYNC_TAG_CHECK_FAULT = 0b010001,
252 SEA_TTW_LEVEL_NEG1 = 0b010011,
253 SEA_TTW_LEVEL0 = 0b010100,
254 SEA_TTW_LEVEL1 = 0b010101,
255 SEA_TTW_LEVEL2 = 0b010110,
256 SEA_TTW_LEVEL3 = 0b010111,
257 ECC_PARITY = 0b011000,
258 ECC_PARITY_TTW_LEVEL_NEG1 = 0b011011,
259 ECC_PARITY_TTW_LEVEL0 = 0b011100,
260 ECC_PARITY_TTW_LEVEL1 = 0b011101,
261 ECC_PARITY_TTW_LEVEL2 = 0b011110,
262 ECC_PARITY_TTW_LEVEL3 = 0b011111,
263 ALIGNMENT_FAULT = 0b100001,
265 GRANULE_PROTECTION_FAULT_LEVEL_NEG = 0b100011,
267 GRANULE_PROTECTION_FAULT_LEVEL0 = 0b100100,
269 GRANULE_PROTECTION_FAULT_LEVEL1 = 0b100101,
271 GRANULE_PROTECTION_FAULT_LEVEL2 = 0b100110,
273 GRANULE_PROTECTION_FAULT_LEVE3 = 0b100111,
275 ADDRESS_SIZE_FAULT_LEVEL_NEG1 = 0b101001,
276 TRANSLATION_FAULT_LEVEL_NEG1 = 0b101011,
277 TLB_CONFLICT_ABORT = 0b110000,
278 UNSUPPORTED_HW_UPDATE_FAULT = 0b110001,
279 }
280}
281
282impl FaultStatusCode {
284 const fn from_bits(bits: u32) -> Self {
285 FaultStatusCode((bits & 0x3f) as u8)
286 }
287
288 const fn into_bits(self) -> u32 {
289 self.0 as u32
290 }
291}
292
293#[bitfield(u32)]
294pub struct IssInstructionAbort {
295 #[bits(6)]
296 pub ifsc: FaultStatusCode,
297 #[bits(1)]
298 _rsvd: u8,
299 pub s1ptw: bool,
301 #[bits(1)]
302 _rsvd2: u8,
303 pub ea: bool,
305 pub fnv: bool,
307 #[bits(2)]
308 pub set: SynchronousErrorType,
309 #[bits(11)]
310 _rsvd3: u16,
311 #[bits(8)]
312 _unused: u8,
313}
314
315impl From<IssInstructionAbort> for EsrEl2 {
316 fn from(instruction_code: IssInstructionAbort) -> Self {
317 let val: u32 = instruction_code.into();
318 EsrEl2::new()
319 .with_ec(ExceptionClass::INSTRUCTION_ABORT.0)
320 .with_iss(val & 0x07ffffff)
321 .with_iss2((val >> 27) as u8)
322 }
323}
324
325open_enum! {
326 pub enum SynchronousErrorType: u8 {
327 RECOVERABLE = 0,
328 UNCONTAINABLE = 2,
329 RESTARTABLE = 3,
330 }
331}
332
333impl SynchronousErrorType {
335 const fn from_bits(bits: u32) -> Self {
336 SynchronousErrorType((bits & 0x1800) as u8)
337 }
338
339 const fn into_bits(self) -> u32 {
340 (self.0 as u32) << 11
341 }
342}
343
344#[bitfield(u32)]
345pub struct IssSystem {
346 pub direction: bool,
347 #[bits(4)]
348 pub crm: u8,
349 #[bits(5)]
350 pub rt: u8,
351 #[bits(4)]
352 pub crn: u8,
353 #[bits(3)]
354 pub op1: u8,
355 #[bits(3)]
356 pub op2: u8,
357 #[bits(2)]
358 pub op0: u8,
359 #[bits(10)]
360 _unused: u32,
361}
362
363impl IssSystem {
364 pub const fn system_reg(&self) -> SystemReg {
365 SystemReg(
366 SystemRegEncoding::new()
367 .with_op0(self.op0())
368 .with_op1(self.op1())
369 .with_crn(self.crn())
370 .with_crm(self.crm())
371 .with_op2(self.op2()),
372 )
373 }
374}
375
376#[bitfield(u32)]
377#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
378pub struct SystemRegEncoding {
379 #[bits(5)]
380 _rsvd: u32,
381 #[bits(3)]
382 pub op2: u8,
383 #[bits(4)]
384 pub crm: u8,
385 #[bits(4)]
386 pub crn: u8,
387 #[bits(3)]
388 pub op1: u8,
389 #[bits(2)]
390 pub op0: u8,
391 #[bits(11)]
392 _rsvd2: u32,
393}
394
395open_enum! {
396 pub enum SystemReg: SystemRegEncoding {
397 SPSR_EL1 = SystemRegEncoding::make(3, 0, 4, 0, 0),
398 SPSR_EL2 = SystemRegEncoding::make(3, 4, 4, 0, 0),
399 SPSR_EL3 = SystemRegEncoding::make(3, 6, 4, 0, 0),
400 ELR_EL1 = SystemRegEncoding::make(3, 0, 4, 0, 1),
401 ELR_EL2 = SystemRegEncoding::make(3, 4, 4, 0, 1),
402 ELR_EL3 = SystemRegEncoding::make(3, 6, 4, 0, 1),
403 SP_EL0 = SystemRegEncoding::make(3, 0, 4, 1, 0),
404 SP_EL1 = SystemRegEncoding::make(3, 4, 4, 1, 0),
405 SP_EL2 = SystemRegEncoding::make(3, 6, 4, 1, 0),
406 FPSR = SystemRegEncoding::make(3, 3, 4, 4, 1),
407 FPCR = SystemRegEncoding::make(3, 3, 4, 4, 0),
408 SPSR_ABT = SystemRegEncoding::make(3, 4, 4, 3, 1),
409 IFSR32_EL2 = SystemRegEncoding::make(3, 4, 5, 0, 1),
410
411 VPIDR_EL2 = SystemRegEncoding::make(3, 4, 0, 0, 0),
412 ARM64_REVIDR_EL1 = SystemRegEncoding::make(3, 0, 0, 0, 6),
413 CTR_EL0 = SystemRegEncoding::make(3, 3, 0, 0, 1),
414 ARM64_VMPIDR_EL2 = SystemRegEncoding::make(3, 4, 0, 0, 5),
415 ID_AA64PFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 4, 0),
416 ID_AA64PFR1_EL1 = SystemRegEncoding::make(3, 0, 0, 4, 1),
417 ID_AA64DFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 5, 0),
418 ID_AA64DFR1_EL1 = SystemRegEncoding::make(3, 0, 0, 5, 1),
419 ID_AA64AFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 5, 4),
420 ID_AA64AFR1_EL1 = SystemRegEncoding::make(3, 0, 0, 5, 5),
421 ID_AA64ISAR0_EL1 = SystemRegEncoding::make(3, 0, 0, 6, 0),
422 ID_AA64ISAR1_EL1 = SystemRegEncoding::make(3, 0, 0, 6, 1),
423 ID_AA64MMFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 7, 0),
424 ID_AA64MMFR1_EL1 = SystemRegEncoding::make(3, 0, 0, 7, 1),
425 ID_AA64MMFR2_EL1 = SystemRegEncoding::make(3, 0, 0, 7, 2),
426
427 ID_MMFR0 = SystemRegEncoding::make(3, 0, 0, 1, 4),
428 ID_MMFR1 = SystemRegEncoding::make(3, 0, 0, 1, 5),
429 ID_MMFR2 = SystemRegEncoding::make(3, 0, 0, 1, 6),
430 ID_MMFR3 = SystemRegEncoding::make(3, 0, 0, 1, 7),
431 ID_MMFR4 = SystemRegEncoding::make(3, 0, 0, 2, 6),
432 ID_ISAR0 = SystemRegEncoding::make(3, 0, 0, 2, 0),
433 ID_ISAR1 = SystemRegEncoding::make(3, 0, 0, 2, 1),
434 ID_ISAR2 = SystemRegEncoding::make(3, 0, 0, 2, 2),
435 ID_ISAR3 = SystemRegEncoding::make(3, 0, 0, 2, 3),
436 ID_ISAR4 = SystemRegEncoding::make(3, 0, 0, 2, 4),
437 ID_ISAR5 = SystemRegEncoding::make(3, 0, 0, 2, 5),
438 ID_ISAR6 = SystemRegEncoding::make(3, 0, 0, 2, 7),
439 MVFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 3, 0),
440 MVFR1_EL1 = SystemRegEncoding::make(3, 3, 0, 0, 1),
441 MVFR2_EL1 = SystemRegEncoding::make(3, 3, 0, 0, 2),
442 ID_AA64ZFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 4, 4),
443 DACR32_EL2 = SystemRegEncoding::make(3, 4, 3, 0, 0),
444 FPEXC32_EL2 = SystemRegEncoding::make(3, 4, 5, 3, 0),
445 VMPIDR_EL2 = SystemRegEncoding::make(3, 4, 0, 0, 5),
446
447 SCTLR = SystemRegEncoding::make(3, 0, 1, 0, 0),
448 SCTLR_EL2 = SystemRegEncoding::make(3, 4, 1, 0, 0),
449 HCR_EL2 = SystemRegEncoding::make(3, 4, 1, 1, 0),
450 HSTR_EL2 = SystemRegEncoding::make(3, 4, 1, 1, 3),
451 HACR_EL2 = SystemRegEncoding::make(3, 4, 1, 1, 7),
452 ACTLR_EL1 = SystemRegEncoding::make(3, 0, 1, 0, 1),
453 ACTLR_EL2 = SystemRegEncoding::make(3, 4, 1, 0, 1),
454 CPACR = SystemRegEncoding::make(3, 0, 1, 0, 2),
455 CPTR_EL2 = SystemRegEncoding::make(3, 4, 1, 1, 2),
456 CPUECTLR_EL1 = SystemRegEncoding::make(3, 0, 15, 1, 4),
457 CNTPS_CTL_EL1 = SystemRegEncoding::make(3, 7, 14, 2, 1),
458 CPUMERRSR_EL1 = SystemRegEncoding::make(3, 1, 15, 2, 2),
459 CNTPS_CVAL_EL1 = SystemRegEncoding::make(3, 7, 14, 2, 2),
460 L2MERRSR_EL1 = SystemRegEncoding::make(3, 1, 15, 2, 3),
461
462 TTBR0_EL1 = SystemRegEncoding::make(3, 0, 2, 0, 0),
463 TTBR0_EL2 = SystemRegEncoding::make(3, 4, 2, 0, 0),
464 TTBR1_EL1 = SystemRegEncoding::make(3, 0, 2, 0, 1),
465 VTTBR_EL2 = SystemRegEncoding::make(3, 4, 2, 1, 0),
466 TCR_EL1 = SystemRegEncoding::make(3, 0, 2, 0, 2),
467 TCR_EL2 = SystemRegEncoding::make(3, 4, 2, 0, 2),
468 VTCR_EL2 = SystemRegEncoding::make(3, 4, 2, 1, 2),
469 ESR_EL1 = SystemRegEncoding::make(3, 0, 5, 2, 0),
470 ESR_EL2 = SystemRegEncoding::make(3, 4, 5, 2, 0),
471 ESR_EL3 = SystemRegEncoding::make(3, 6, 5, 2, 0),
472 FAR_EL1 = SystemRegEncoding::make(3, 0, 6, 0, 0),
473 FAR_EL2 = SystemRegEncoding::make(3, 4, 6, 0, 0),
474 HPFAR_EL2 = SystemRegEncoding::make(3, 4, 6, 0, 4),
475 AFSR0_EL1 = SystemRegEncoding::make(3, 0, 5, 1, 0),
476 AFSR0_EL2 = SystemRegEncoding::make(3, 4, 5, 1, 0),
477 AFSR1_EL1 = SystemRegEncoding::make(3, 0, 5, 1, 1),
478 AFSR1_EL2 = SystemRegEncoding::make(3, 4, 5, 1, 1),
479
480 PAR_EL1 = SystemRegEncoding::make(3, 0, 7, 4, 0),
481 CNTFRQ_EL0 = SystemRegEncoding::make(3, 3, 14, 0, 0),
482 CNTP_CTL_EL0 = SystemRegEncoding::make(3, 3, 14, 2, 1),
483 CNTP_CVAL_EL0 = SystemRegEncoding::make(3, 3, 14, 2, 2),
484 CNTV_CTL_EL0 = SystemRegEncoding::make(3, 3, 14, 3, 1),
485 CNTV_CVAL_EL0 = SystemRegEncoding::make(3, 3, 14, 3, 2),
486 CNTHCTL_EL2 = SystemRegEncoding::make(3, 4, 14, 1, 0),
487 CNTHP_CTL_EL2 = SystemRegEncoding::make(3, 4, 14, 2, 1),
488 CNTHP_CVAL_EL2 = SystemRegEncoding::make(3, 4, 14, 2, 2),
489 PMCCFILTR_EL0 = SystemRegEncoding::make(3, 3, 14, 15, 7),
490 MDCR_EL2 = SystemRegEncoding::make(3, 4, 1, 1, 1),
491 PMCR_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 0),
492 PMCNTENSET_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 1),
493 PMCNTENCLR_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 2),
494 PMOVSSET_EL0 = SystemRegEncoding::make(3, 3, 9, 14, 3),
495 PMOVSCLR_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 3),
496 PMSELR_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 5),
497 PMCEID0_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 6),
498 PMCEID1_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 7),
499 PMCCNTR_EL0 = SystemRegEncoding::make(3, 3, 9, 13, 0),
500 PMUSERENR_EL0 = SystemRegEncoding::make(3, 3, 9, 14, 0),
501 PMINTENSET_EL1 = SystemRegEncoding::make(3, 0, 9, 14, 1),
502 PMINTENCLR_EL1 = SystemRegEncoding::make(3, 0, 9, 14, 2),
503
504 MAIR_EL1 = SystemRegEncoding::make(3, 0, 10, 2, 0),
505 AMAIR0 = SystemRegEncoding::make(3, 0, 10, 3, 0),
506 MAIR_EL2 = SystemRegEncoding::make(3, 4, 10, 2, 0),
507 AMAIR_EL2 = SystemRegEncoding::make(3, 4, 10, 3, 0),
508 MAIR_EL3 = SystemRegEncoding::make(3, 6, 10, 2, 0),
509
510 VBAR = SystemRegEncoding::make(3, 0, 12, 0, 0),
511 VBAR_EL2 = SystemRegEncoding::make(3, 4, 12, 0, 0),
512 RVBAR_EL2 = SystemRegEncoding::make(3, 4, 12, 0, 1),
513
514 TPIDR_EL0 = SystemRegEncoding::make(3, 3, 13, 0, 2),
515 TPIDRRO_EL0 = SystemRegEncoding::make(3, 3, 13, 0, 3),
516 TPIDR_EL1 = SystemRegEncoding::make(3, 0, 13, 0, 4),
517 TPIDR_EL2 = SystemRegEncoding::make(3, 4, 13, 0, 2),
518 CONTEXTIDR_EL1 = SystemRegEncoding::make(3, 0, 13, 0, 1),
519
520 CLIDR = SystemRegEncoding::make(3, 1, 0, 0, 1),
521 AIDR = SystemRegEncoding::make(3, 1, 0, 0, 7),
522 CSSELR = SystemRegEncoding::make(3, 2, 0, 0, 0),
523
524 CNTKCTL = SystemRegEncoding::make(3, 0, 14, 1, 0),
525 CNTVOFF_EL2 = SystemRegEncoding::make(3, 4, 14, 0, 3),
526
527 MDCCSR_EL0 = SystemRegEncoding::make(2, 3, 0, 1, 0),
528 MDSCR_EL1 = SystemRegEncoding::make(2, 0, 0, 2, 2),
529 MDRAR_EL1 = SystemRegEncoding::make(2, 0, 1, 0, 0),
530 OSLSR_EL1 = SystemRegEncoding::make(2, 0, 1, 1, 4),
531 DBGBVR0 = SystemRegEncoding::make(2, 0, 0, 0, 4),
532 DBGBVR1 = SystemRegEncoding::make(2, 0, 0, 1, 4),
533 DBGBVR2 = SystemRegEncoding::make(2, 0, 0, 2, 4),
534 DBGBVR3 = SystemRegEncoding::make(2, 0, 0, 3, 4),
535 DBGBVR4 = SystemRegEncoding::make(2, 0, 0, 4, 4),
536 DBGBVR5 = SystemRegEncoding::make(2, 0, 0, 5, 4),
537 DBGBCR0 = SystemRegEncoding::make(2, 0, 0, 0, 5),
538 DBGBCR1 = SystemRegEncoding::make(2, 0, 0, 1, 5),
539 DBGBCR2 = SystemRegEncoding::make(2, 0, 0, 2, 5),
540 DBGBCR3 = SystemRegEncoding::make(2, 0, 0, 3, 5),
541 DBGBCR4 = SystemRegEncoding::make(2, 0, 0, 4, 5),
542 DBGBCR5 = SystemRegEncoding::make(2, 0, 0, 5, 5),
543 DBGWVR0 = SystemRegEncoding::make(2, 0, 0, 0, 6),
544 DBGWVR1 = SystemRegEncoding::make(2, 0, 0, 1, 6),
545 DBGWVR2 = SystemRegEncoding::make(2, 0, 0, 2, 6),
546 DBGWVR3 = SystemRegEncoding::make(2, 0, 0, 3, 6),
547 DBGWCR0 = SystemRegEncoding::make(2, 0, 0, 0, 7),
548 DBGWCR1 = SystemRegEncoding::make(2, 0, 0, 1, 7),
549 DBGWCR2 = SystemRegEncoding::make(2, 0, 0, 2, 7),
550 DBGWCR3 = SystemRegEncoding::make(2, 0, 0, 3, 7),
551
552 ICC_AP0R0_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 4),
553 ICC_AP0R1_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 5),
554 ICC_AP0R2_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 6),
555 ICC_AP0R3_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 7),
556 ICC_AP1R0_EL1 = SystemRegEncoding::make(3, 0, 12, 9, 0),
557 ICC_AP1R1_EL1 = SystemRegEncoding::make(3, 0, 12, 9, 1),
558 ICC_AP1R2_EL1 = SystemRegEncoding::make(3, 0, 12, 9, 2),
559 ICC_AP1R3_EL1 = SystemRegEncoding::make(3, 0, 12, 9, 3),
560 ICC_ASGI1R_EL1 = SystemRegEncoding::make(3, 0, 12, 11, 6),
561 ICC_BPR0_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 3),
562 ICC_BPR1_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 3),
563 ICC_CTLR_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 4),
564 ICC_CTLR_EL3 = SystemRegEncoding::make(3, 6, 12, 12, 4),
565 ICC_DIR_EL1 = SystemRegEncoding::make(3, 0, 12, 11, 1),
566 ICC_EOIR0_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 1),
567 ICC_EOIR1_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 1),
568 ICC_HPPIR0_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 2),
569 ICC_HPPIR1_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 2),
570 ICC_IAR0_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 0),
571 ICC_IAR1_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 0),
572 ICC_IGRPEN0_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 6),
573 ICC_IGRPEN1_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 7),
574 ICC_IGRPEN1_EL3 = SystemRegEncoding::make(3, 6, 12, 12, 7),
575 ICC_PMR_EL1 = SystemRegEncoding::make(3, 0, 4, 6, 0),
576 ICC_RPR_EL1 = SystemRegEncoding::make(3, 0, 12, 11, 3),
577 ICC_SGI0R_EL1 = SystemRegEncoding::make(3, 0, 12, 11, 7),
578 ICC_SGI1R_EL1 = SystemRegEncoding::make(3, 0, 12, 11, 5),
579 ICC_SRE_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 5),
580 ICC_SRE_EL2 = SystemRegEncoding::make(3, 4, 12, 9, 5),
581 ICC_SRE_EL3 = SystemRegEncoding::make(3, 6, 12, 12, 5),
582 }
583}
584
585impl SystemRegEncoding {
586 pub const fn make(op0: u8, op1: u8, crn: u8, crm: u8, op2: u8) -> Self {
587 Self::new()
588 .with_op0(op0)
589 .with_op1(op1)
590 .with_crn(crn)
591 .with_crm(crm)
592 .with_op2(op2)
593 }
594}
595
596#[bitfield(u64)]
598pub struct MpidrEl1 {
599 pub aff0: u8,
600 pub aff1: u8,
601 pub aff2: u8,
602 pub mt: bool,
603 #[bits(5)]
604 pub res0_25_29: u8,
605 pub u: bool,
606 pub res1_31: bool,
607 pub aff3: u8,
608 #[bits(24)]
609 pub res0_40_63: u32,
610}
611
612impl MpidrEl1 {
613 pub const AFFINITY_MASK: Self = Self::new()
614 .with_aff0(0xff)
615 .with_aff1(0xff)
616 .with_aff2(0xff)
617 .with_aff3(0xff);
618}
619
620open_enum! {
621 pub enum TranslationGranule0: u64 {
623 TG_4KB = 0b00,
624 TG_64KB = 0b01,
625 TG_16KB = 0b10,
626 }
627}
628
629impl TranslationGranule0 {
630 const fn into_bits(self) -> u64 {
631 self.0
632 }
633
634 const fn from_bits(bits: u64) -> Self {
635 Self(bits)
636 }
637}
638
639open_enum! {
640 pub enum TranslationGranule1: u64 {
642 TG_INVALID = 0b00,
643 TG_16KB = 0b01,
644 TG_4KB = 0b10,
645 TG_64KB = 0b11,
646 }
647}
648
649impl TranslationGranule1 {
650 const fn into_bits(self) -> u64 {
651 self.0
652 }
653
654 const fn from_bits(bits: u64) -> Self {
655 Self(bits)
656 }
657}
658
659open_enum! {
660 pub enum IntermPhysAddrSize: u64{
662 IPA_32_BITS_4_GB = 0b000,
663 IPA_36_BITS_64_GB = 0b001,
664 IPA_40_BITS_1_TB = 0b010,
665 IPA_42_BITS_4_TB = 0b011,
666 IPA_44_BITS_16_TB = 0b100,
667 IPA_48_BITS_256_TB = 0b101,
668 IPA_52_BITS_4_PB = 0b110,
669 IPA_56_BITS_64_PB = 0b111,
670 }
671}
672
673impl IntermPhysAddrSize {
674 const fn into_bits(self) -> u64 {
675 self.0
676 }
677
678 const fn from_bits(bits: u64) -> Self {
679 Self(bits)
680 }
681}
682
683#[bitfield(u64)]
685#[derive(PartialEq, Eq)]
686pub struct TranslationControlEl1 {
687 #[bits(6)]
688 pub t0sz: u64,
689 #[bits(1)]
690 _mbz0: u64,
691 #[bits(1)]
692 pub epd0: u64,
693 #[bits(2)]
694 pub irgn0: u64,
695 #[bits(2)]
696 pub orgn0: u64,
697 #[bits(2)]
698 pub sh0: u64,
699 #[bits(2)]
700 pub tg0: TranslationGranule0,
701 #[bits(6)]
702 pub t1sz: u64,
703 #[bits(1)]
704 pub a1: u64,
705 #[bits(1)]
706 pub epd1: u64,
707 #[bits(2)]
708 pub irgn1: u64,
709 #[bits(2)]
710 pub orgn1: u64,
711 #[bits(2)]
712 pub sh1: u64,
713 #[bits(2)]
714 pub tg1: TranslationGranule1,
715 #[bits(3)]
716 pub ips: IntermPhysAddrSize,
717 #[bits(1)]
718 _mbz1: u64,
719 #[bits(1)]
720 pub a_s: u64,
721 #[bits(1)]
722 pub tbi0: u64,
723 #[bits(1)]
724 pub tbi1: u64,
725 #[bits(1)]
726 pub ha: u64,
727 #[bits(1)]
728 pub hd: u64,
729 #[bits(1)]
730 pub hpd0: u64,
731 #[bits(1)]
732 pub hpd1: u64,
733 #[bits(1)]
734 pub hwu059: u64,
735 #[bits(1)]
736 pub hwu060: u64,
737 #[bits(1)]
738 pub hwu061: u64,
739 #[bits(1)]
740 pub hwu062: u64,
741 #[bits(1)]
742 pub hwu159: u64,
743 #[bits(1)]
744 pub hwu160: u64,
745 #[bits(1)]
746 pub hwu161: u64,
747 #[bits(1)]
748 pub hwu162: u64,
749 #[bits(1)]
750 pub tbid0: u64,
751 #[bits(1)]
752 pub tbid1: u64,
753 #[bits(1)]
754 pub nfd0: u64,
755 #[bits(1)]
756 pub nfd1: u64,
757 #[bits(1)]
758 pub e0pd0: u64,
759 #[bits(1)]
760 pub e0pd1: u64,
761 #[bits(1)]
762 pub tcma0: u64,
763 #[bits(1)]
764 pub tcma1: u64,
765 #[bits(1)]
766 pub ds: u64,
767 #[bits(1)]
768 pub mtx0: u64,
769 #[bits(1)]
770 pub mtx1: u64,
771 #[bits(2)]
772 _mbz2: u64,
773}
774
775impl TranslationControlEl1 {
776 pub fn ttbr0_valid_address_bits(&self) -> u64 {
777 64 - self.t0sz()
778 }
779
780 pub fn ttbr1_valid_address_bits(&self) -> u64 {
781 64 - self.t1sz()
782 }
783}
784
785#[bitfield(u64)]
787#[derive(PartialEq, Eq)]
788pub struct TranslationBaseEl1 {
789 #[bits(48)]
793 pub baddr: u64,
794 #[bits(16)]
795 pub asid: u64,
796}
797
798#[bitfield(u64)]
799#[derive(PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)]
800pub struct Pte {
801 pub valid: bool,
802 pub not_large_page: bool,
803 #[bits(3)]
804 pub attribute_index: u64,
805 pub non_secure: bool,
806 pub ap_unprivileged: bool,
807 pub ap_read_only: bool,
808 #[bits(2)]
809 pub shareability: u64,
810 pub access_flag: bool,
811 pub not_global: bool,
812 #[bits(36)]
813 pub pfn: u64,
814 #[bits(3)]
815 pub reserved_must_be_zero: u64,
816 pub dbm: bool,
817 pub contiguous_hint: bool,
818 pub privilege_no_execute: bool,
819 pub user_no_execute: bool,
820 #[bits(4)]
821 pub _reserved2: u64,
822 pub pxn_table: bool,
823 pub uxn_table: bool,
824 pub ap_table_privileged_only: bool,
825 pub ap_table_read_only: bool,
826 pub ns_table: bool,
827}
828
829#[bitfield(u64)]
831pub struct MmFeatures0El1 {
832 #[bits(4)]
833 pub pa_range: IntermPhysAddrSize,
834 #[bits(60)]
835 _rest: u64,
836}
837
838pub const GIC_DISTRIBUTOR_SIZE: u64 = 0x1_0000;
839pub const GIC_REDISTRIBUTOR_FRAME_SIZE: u64 = 0x1_0000;
840pub const GIC_SGI_FRAME_SIZE: u64 = 0x1_0000;
841pub const GIC_REDISTRIBUTOR_SIZE: u64 = GIC_REDISTRIBUTOR_FRAME_SIZE + GIC_SGI_FRAME_SIZE;
842
843open_enum! {
844 pub enum SystemReset2Code: u32 {
845 WARM_RESET = 0,
846 }
847}
848
849open_enum! {
850 pub enum SystemOff2Code: u32 {
851 DEFAULT = 0,
852 HIBERNATE_OFF = 1,
853 }
854}