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_AA64PFR1_EL1 = SystemRegEncoding::make(3, 0, 0, 4, 1),
416 ID_AA64DFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 5, 0),
417 ID_AA64DFR1_EL1 = SystemRegEncoding::make(3, 0, 0, 5, 1),
418 ID_AA64AFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 5, 4),
419 ID_AA64AFR1_EL1 = SystemRegEncoding::make(3, 0, 0, 5, 5),
420 ID_AA64ISAR0_EL1 = SystemRegEncoding::make(3, 0, 0, 6, 0),
421 ID_AA64ISAR1_EL1 = SystemRegEncoding::make(3, 0, 0, 6, 1),
422 ID_AA64MMFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 7, 0),
423 ID_AA64MMFR1_EL1 = SystemRegEncoding::make(3, 0, 0, 7, 1),
424 ID_AA64MMFR2_EL1 = SystemRegEncoding::make(3, 0, 0, 7, 2),
425
426 ID_MMFR0 = SystemRegEncoding::make(3, 0, 0, 1, 4),
427 ID_MMFR1 = SystemRegEncoding::make(3, 0, 0, 1, 5),
428 ID_MMFR2 = SystemRegEncoding::make(3, 0, 0, 1, 6),
429 ID_MMFR3 = SystemRegEncoding::make(3, 0, 0, 1, 7),
430 ID_MMFR4 = SystemRegEncoding::make(3, 0, 0, 2, 6),
431 ID_ISAR0 = SystemRegEncoding::make(3, 0, 0, 2, 0),
432 ID_ISAR1 = SystemRegEncoding::make(3, 0, 0, 2, 1),
433 ID_ISAR2 = SystemRegEncoding::make(3, 0, 0, 2, 2),
434 ID_ISAR3 = SystemRegEncoding::make(3, 0, 0, 2, 3),
435 ID_ISAR4 = SystemRegEncoding::make(3, 0, 0, 2, 4),
436 ID_ISAR5 = SystemRegEncoding::make(3, 0, 0, 2, 5),
437 ID_ISAR6 = SystemRegEncoding::make(3, 0, 0, 2, 7),
438 MVFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 3, 0),
439 MVFR1_EL1 = SystemRegEncoding::make(3, 3, 0, 0, 1),
440 MVFR2_EL1 = SystemRegEncoding::make(3, 3, 0, 0, 2),
441 ID_AA64ZFR0_EL1 = SystemRegEncoding::make(3, 0, 0, 4, 4),
442 DACR32_EL2 = SystemRegEncoding::make(3, 4, 3, 0, 0),
443 FPEXC32_EL2 = SystemRegEncoding::make(3, 4, 5, 3, 0),
444 VMPIDR_EL2 = SystemRegEncoding::make(3, 4, 0, 0, 5),
445
446 SCTLR = SystemRegEncoding::make(3, 0, 1, 0, 0),
447 SCTLR_EL2 = SystemRegEncoding::make(3, 4, 1, 0, 0),
448 HCR_EL2 = SystemRegEncoding::make(3, 4, 1, 1, 0),
449 HSTR_EL2 = SystemRegEncoding::make(3, 4, 1, 1, 3),
450 HACR_EL2 = SystemRegEncoding::make(3, 4, 1, 1, 7),
451 ACTLR_EL1 = SystemRegEncoding::make(3, 0, 1, 0, 1),
452 ACTLR_EL2 = SystemRegEncoding::make(3, 4, 1, 0, 1),
453 CPACR = SystemRegEncoding::make(3, 0, 1, 0, 2),
454 CPTR_EL2 = SystemRegEncoding::make(3, 4, 1, 1, 2),
455 CPUECTLR_EL1 = SystemRegEncoding::make(3, 0, 15, 1, 4),
456 CNTPS_CTL_EL1 = SystemRegEncoding::make(3, 7, 14, 2, 1),
457 CPUMERRSR_EL1 = SystemRegEncoding::make(3, 1, 15, 2, 2),
458 CNTPS_CVAL_EL1 = SystemRegEncoding::make(3, 7, 14, 2, 2),
459 L2MERRSR_EL1 = SystemRegEncoding::make(3, 1, 15, 2, 3),
460
461 TTBR0_EL1 = SystemRegEncoding::make(3, 0, 2, 0, 0),
462 TTBR0_EL2 = SystemRegEncoding::make(3, 4, 2, 0, 0),
463 TTBR1_EL1 = SystemRegEncoding::make(3, 0, 2, 0, 1),
464 VTTBR_EL2 = SystemRegEncoding::make(3, 4, 2, 1, 0),
465 TCR_EL1 = SystemRegEncoding::make(3, 0, 2, 0, 2),
466 TCR_EL2 = SystemRegEncoding::make(3, 4, 2, 0, 2),
467 VTCR_EL2 = SystemRegEncoding::make(3, 4, 2, 1, 2),
468 ESR_EL1 = SystemRegEncoding::make(3, 0, 5, 2, 0),
469 ESR_EL2 = SystemRegEncoding::make(3, 4, 5, 2, 0),
470 ESR_EL3 = SystemRegEncoding::make(3, 6, 5, 2, 0),
471 FAR_EL1 = SystemRegEncoding::make(3, 0, 6, 0, 0),
472 FAR_EL2 = SystemRegEncoding::make(3, 4, 6, 0, 0),
473 HPFAR_EL2 = SystemRegEncoding::make(3, 4, 6, 0, 4),
474 AFSR0_EL1 = SystemRegEncoding::make(3, 0, 5, 1, 0),
475 AFSR0_EL2 = SystemRegEncoding::make(3, 4, 5, 1, 0),
476 AFSR1_EL1 = SystemRegEncoding::make(3, 0, 5, 1, 1),
477 AFSR1_EL2 = SystemRegEncoding::make(3, 4, 5, 1, 1),
478
479 PAR_EL1 = SystemRegEncoding::make(3, 0, 7, 4, 0),
480 CNTFRQ_EL0 = SystemRegEncoding::make(3, 3, 14, 0, 0),
481 CNTP_CTL_EL0 = SystemRegEncoding::make(3, 3, 14, 2, 1),
482 CNTP_CVAL_EL0 = SystemRegEncoding::make(3, 3, 14, 2, 2),
483 CNTV_CTL_EL0 = SystemRegEncoding::make(3, 3, 14, 3, 1),
484 CNTV_CVAL_EL0 = SystemRegEncoding::make(3, 3, 14, 3, 2),
485 CNTHCTL_EL2 = SystemRegEncoding::make(3, 4, 14, 1, 0),
486 CNTHP_CTL_EL2 = SystemRegEncoding::make(3, 4, 14, 2, 1),
487 CNTHP_CVAL_EL2 = SystemRegEncoding::make(3, 4, 14, 2, 2),
488 PMCCFILTR_EL0 = SystemRegEncoding::make(3, 3, 14, 15, 7),
489 MDCR_EL2 = SystemRegEncoding::make(3, 4, 1, 1, 1),
490 PMCR_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 0),
491 PMCNTENSET_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 1),
492 PMCNTENCLR_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 2),
493 PMOVSSET_EL0 = SystemRegEncoding::make(3, 3, 9, 14, 3),
494 PMOVSCLR_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 3),
495 PMSELR_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 5),
496 PMCEID0_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 6),
497 PMCEID1_EL0 = SystemRegEncoding::make(3, 3, 9, 12, 7),
498 PMCCNTR_EL0 = SystemRegEncoding::make(3, 3, 9, 13, 0),
499 PMUSERENR_EL0 = SystemRegEncoding::make(3, 3, 9, 14, 0),
500 PMINTENSET_EL1 = SystemRegEncoding::make(3, 0, 9, 14, 1),
501 PMINTENCLR_EL1 = SystemRegEncoding::make(3, 0, 9, 14, 2),
502
503 MAIR_EL1 = SystemRegEncoding::make(3, 0, 10, 2, 0),
504 AMAIR0 = SystemRegEncoding::make(3, 0, 10, 3, 0),
505 MAIR_EL2 = SystemRegEncoding::make(3, 4, 10, 2, 0),
506 AMAIR_EL2 = SystemRegEncoding::make(3, 4, 10, 3, 0),
507 MAIR_EL3 = SystemRegEncoding::make(3, 6, 10, 2, 0),
508
509 VBAR = SystemRegEncoding::make(3, 0, 12, 0, 0),
510 VBAR_EL2 = SystemRegEncoding::make(3, 4, 12, 0, 0),
511 RVBAR_EL2 = SystemRegEncoding::make(3, 4, 12, 0, 1),
512
513 TPIDR_EL0 = SystemRegEncoding::make(3, 3, 13, 0, 2),
514 TPIDRRO_EL0 = SystemRegEncoding::make(3, 3, 13, 0, 3),
515 TPIDR_EL1 = SystemRegEncoding::make(3, 0, 13, 0, 4),
516 TPIDR_EL2 = SystemRegEncoding::make(3, 4, 13, 0, 2),
517 CONTEXTIDR_EL1 = SystemRegEncoding::make(3, 0, 13, 0, 1),
518
519 CLIDR = SystemRegEncoding::make(3, 1, 0, 0, 1),
520 AIDR = SystemRegEncoding::make(3, 1, 0, 0, 7),
521 CSSELR = SystemRegEncoding::make(3, 2, 0, 0, 0),
522
523 CNTKCTL = SystemRegEncoding::make(3, 0, 14, 1, 0),
524 CNTVOFF_EL2 = SystemRegEncoding::make(3, 4, 14, 0, 3),
525
526 MDCCSR_EL0 = SystemRegEncoding::make(2, 3, 0, 1, 0),
527 MDSCR_EL1 = SystemRegEncoding::make(2, 0, 0, 2, 2),
528 MDRAR_EL1 = SystemRegEncoding::make(2, 0, 1, 0, 0),
529 OSLSR_EL1 = SystemRegEncoding::make(2, 0, 1, 1, 4),
530 DBGBVR0 = SystemRegEncoding::make(2, 0, 0, 0, 4),
531 DBGBVR1 = SystemRegEncoding::make(2, 0, 0, 1, 4),
532 DBGBVR2 = SystemRegEncoding::make(2, 0, 0, 2, 4),
533 DBGBVR3 = SystemRegEncoding::make(2, 0, 0, 3, 4),
534 DBGBVR4 = SystemRegEncoding::make(2, 0, 0, 4, 4),
535 DBGBVR5 = SystemRegEncoding::make(2, 0, 0, 5, 4),
536 DBGBCR0 = SystemRegEncoding::make(2, 0, 0, 0, 5),
537 DBGBCR1 = SystemRegEncoding::make(2, 0, 0, 1, 5),
538 DBGBCR2 = SystemRegEncoding::make(2, 0, 0, 2, 5),
539 DBGBCR3 = SystemRegEncoding::make(2, 0, 0, 3, 5),
540 DBGBCR4 = SystemRegEncoding::make(2, 0, 0, 4, 5),
541 DBGBCR5 = SystemRegEncoding::make(2, 0, 0, 5, 5),
542 DBGWVR0 = SystemRegEncoding::make(2, 0, 0, 0, 6),
543 DBGWVR1 = SystemRegEncoding::make(2, 0, 0, 1, 6),
544 DBGWVR2 = SystemRegEncoding::make(2, 0, 0, 2, 6),
545 DBGWVR3 = SystemRegEncoding::make(2, 0, 0, 3, 6),
546 DBGWCR0 = SystemRegEncoding::make(2, 0, 0, 0, 7),
547 DBGWCR1 = SystemRegEncoding::make(2, 0, 0, 1, 7),
548 DBGWCR2 = SystemRegEncoding::make(2, 0, 0, 2, 7),
549 DBGWCR3 = SystemRegEncoding::make(2, 0, 0, 3, 7),
550
551 ICC_AP0R0_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 4),
552 ICC_AP0R1_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 5),
553 ICC_AP0R2_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 6),
554 ICC_AP0R3_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 7),
555 ICC_AP1R0_EL1 = SystemRegEncoding::make(3, 0, 12, 9, 0),
556 ICC_AP1R1_EL1 = SystemRegEncoding::make(3, 0, 12, 9, 1),
557 ICC_AP1R2_EL1 = SystemRegEncoding::make(3, 0, 12, 9, 2),
558 ICC_AP1R3_EL1 = SystemRegEncoding::make(3, 0, 12, 9, 3),
559 ICC_ASGI1R_EL1 = SystemRegEncoding::make(3, 0, 12, 11, 6),
560 ICC_BPR0_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 3),
561 ICC_BPR1_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 3),
562 ICC_CTLR_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 4),
563 ICC_CTLR_EL3 = SystemRegEncoding::make(3, 6, 12, 12, 4),
564 ICC_DIR_EL1 = SystemRegEncoding::make(3, 0, 12, 11, 1),
565 ICC_EOIR0_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 1),
566 ICC_EOIR1_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 1),
567 ICC_HPPIR0_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 2),
568 ICC_HPPIR1_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 2),
569 ICC_IAR0_EL1 = SystemRegEncoding::make(3, 0, 12, 8, 0),
570 ICC_IAR1_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 0),
571 ICC_IGRPEN0_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 6),
572 ICC_IGRPEN1_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 7),
573 ICC_IGRPEN1_EL3 = SystemRegEncoding::make(3, 6, 12, 12, 7),
574 ICC_PMR_EL1 = SystemRegEncoding::make(3, 0, 4, 6, 0),
575 ICC_RPR_EL1 = SystemRegEncoding::make(3, 0, 12, 11, 3),
576 ICC_SGI0R_EL1 = SystemRegEncoding::make(3, 0, 12, 11, 7),
577 ICC_SGI1R_EL1 = SystemRegEncoding::make(3, 0, 12, 11, 5),
578 ICC_SRE_EL1 = SystemRegEncoding::make(3, 0, 12, 12, 5),
579 ICC_SRE_EL2 = SystemRegEncoding::make(3, 4, 12, 9, 5),
580 ICC_SRE_EL3 = SystemRegEncoding::make(3, 6, 12, 12, 5),
581 }
582}
583
584impl SystemRegEncoding {
585 pub const fn make(op0: u8, op1: u8, crn: u8, crm: u8, op2: u8) -> Self {
586 Self::new()
587 .with_op0(op0)
588 .with_op1(op1)
589 .with_crn(crn)
590 .with_crm(crm)
591 .with_op2(op2)
592 }
593}
594
595#[bitfield(u64)]
597pub struct MpidrEl1 {
598 pub aff0: u8,
599 pub aff1: u8,
600 pub aff2: u8,
601 pub mt: bool,
602 #[bits(5)]
603 pub res0_25_29: u8,
604 pub u: bool,
605 pub res1_31: bool,
606 pub aff3: u8,
607 #[bits(24)]
608 pub res0_40_63: u32,
609}
610
611impl MpidrEl1 {
612 pub const AFFINITY_MASK: Self = Self::new()
613 .with_aff0(0xff)
614 .with_aff1(0xff)
615 .with_aff2(0xff)
616 .with_aff3(0xff);
617}
618
619open_enum! {
620 pub enum TranslationGranule0: u64 {
622 TG_4KB = 0b00,
623 TG_64KB = 0b01,
624 TG_16KB = 0b10,
625 }
626}
627
628impl TranslationGranule0 {
629 const fn into_bits(self) -> u64 {
630 self.0
631 }
632
633 const fn from_bits(bits: u64) -> Self {
634 Self(bits)
635 }
636}
637
638open_enum! {
639 pub enum TranslationGranule1: u64 {
641 TG_INVALID = 0b00,
642 TG_16KB = 0b01,
643 TG_4KB = 0b10,
644 TG_64KB = 0b11,
645 }
646}
647
648impl TranslationGranule1 {
649 const fn into_bits(self) -> u64 {
650 self.0
651 }
652
653 const fn from_bits(bits: u64) -> Self {
654 Self(bits)
655 }
656}
657
658open_enum! {
659 pub enum IntermPhysAddrSize: u64{
661 IPA_32_BITS_4_GB = 0b000,
662 IPA_36_BITS_64_GB = 0b001,
663 IPA_40_BITS_1_TB = 0b010,
664 IPA_42_BITS_4_TB = 0b011,
665 IPA_44_BITS_16_TB = 0b100,
666 IPA_48_BITS_256_TB = 0b101,
667 IPA_52_BITS_4_PB = 0b110,
668 IPA_56_BITS_64_PB = 0b111,
669 }
670}
671
672impl IntermPhysAddrSize {
673 const fn into_bits(self) -> u64 {
674 self.0
675 }
676
677 const fn from_bits(bits: u64) -> Self {
678 Self(bits)
679 }
680}
681
682#[bitfield(u64)]
684#[derive(PartialEq, Eq)]
685pub struct TranslationControlEl1 {
686 #[bits(6)]
687 pub t0sz: u64,
688 #[bits(1)]
689 _mbz0: u64,
690 #[bits(1)]
691 pub epd0: u64,
692 #[bits(2)]
693 pub irgn0: u64,
694 #[bits(2)]
695 pub orgn0: u64,
696 #[bits(2)]
697 pub sh0: u64,
698 #[bits(2)]
699 pub tg0: TranslationGranule0,
700 #[bits(6)]
701 pub t1sz: u64,
702 #[bits(1)]
703 pub a1: u64,
704 #[bits(1)]
705 pub epd1: u64,
706 #[bits(2)]
707 pub irgn1: u64,
708 #[bits(2)]
709 pub orgn1: u64,
710 #[bits(2)]
711 pub sh1: u64,
712 #[bits(2)]
713 pub tg1: TranslationGranule1,
714 #[bits(3)]
715 pub ips: IntermPhysAddrSize,
716 #[bits(1)]
717 _mbz1: u64,
718 #[bits(1)]
719 pub a_s: u64,
720 #[bits(1)]
721 pub tbi0: u64,
722 #[bits(1)]
723 pub tbi1: u64,
724 #[bits(1)]
725 pub ha: u64,
726 #[bits(1)]
727 pub hd: u64,
728 #[bits(1)]
729 pub hpd0: u64,
730 #[bits(1)]
731 pub hpd1: u64,
732 #[bits(1)]
733 pub hwu059: u64,
734 #[bits(1)]
735 pub hwu060: u64,
736 #[bits(1)]
737 pub hwu061: u64,
738 #[bits(1)]
739 pub hwu062: u64,
740 #[bits(1)]
741 pub hwu159: u64,
742 #[bits(1)]
743 pub hwu160: u64,
744 #[bits(1)]
745 pub hwu161: u64,
746 #[bits(1)]
747 pub hwu162: u64,
748 #[bits(1)]
749 pub tbid0: u64,
750 #[bits(1)]
751 pub tbid1: u64,
752 #[bits(1)]
753 pub nfd0: u64,
754 #[bits(1)]
755 pub nfd1: u64,
756 #[bits(1)]
757 pub e0pd0: u64,
758 #[bits(1)]
759 pub e0pd1: u64,
760 #[bits(1)]
761 pub tcma0: u64,
762 #[bits(1)]
763 pub tcma1: u64,
764 #[bits(1)]
765 pub ds: u64,
766 #[bits(1)]
767 pub mtx0: u64,
768 #[bits(1)]
769 pub mtx1: u64,
770 #[bits(2)]
771 _mbz2: u64,
772}
773
774impl TranslationControlEl1 {
775 pub fn ttbr0_valid_address_bits(&self) -> u64 {
776 64 - self.t0sz()
777 }
778
779 pub fn ttbr1_valid_address_bits(&self) -> u64 {
780 64 - self.t1sz()
781 }
782}
783
784#[bitfield(u64)]
786#[derive(PartialEq, Eq)]
787pub struct TranslationBaseEl1 {
788 #[bits(48)]
792 pub baddr: u64,
793 #[bits(16)]
794 pub asid: u64,
795}
796
797#[bitfield(u64)]
798#[derive(PartialEq, Eq, IntoBytes, Immutable, KnownLayout, FromBytes)]
799pub struct Pte {
800 pub valid: bool,
801 pub not_large_page: bool,
802 #[bits(3)]
803 pub attribute_index: u64,
804 pub non_secure: bool,
805 pub ap_unprivileged: bool,
806 pub ap_read_only: bool,
807 #[bits(2)]
808 pub shareability: u64,
809 pub access_flag: bool,
810 pub not_global: bool,
811 #[bits(36)]
812 pub pfn: u64,
813 #[bits(3)]
814 pub reserved_must_be_zero: u64,
815 pub dbm: bool,
816 pub contiguous_hint: bool,
817 pub privilege_no_execute: bool,
818 pub user_no_execute: bool,
819 #[bits(4)]
820 pub _reserved2: u64,
821 pub pxn_table: bool,
822 pub uxn_table: bool,
823 pub ap_table_privileged_only: bool,
824 pub ap_table_read_only: bool,
825 pub ns_table: bool,
826}
827
828#[bitfield(u64)]
830pub struct MmFeatures0El1 {
831 #[bits(4)]
832 pub pa_range: IntermPhysAddrSize,
833 #[bits(60)]
834 _rest: u64,
835}
836
837pub const GIC_DISTRIBUTOR_SIZE: u64 = 0x1_0000;
838pub const GIC_REDISTRIBUTOR_FRAME_SIZE: u64 = 0x1_0000;
839pub const GIC_SGI_FRAME_SIZE: u64 = 0x1_0000;
840pub const GIC_REDISTRIBUTOR_SIZE: u64 = GIC_REDISTRIBUTOR_FRAME_SIZE + GIC_SGI_FRAME_SIZE;