islet_rmm/exception/trap/
syndrome.rs1use aarch64_cpu::registers::*;
2
3#[derive(Debug, Copy, Clone)]
4pub enum Fault {
5 AddressSize { level: u8 },
6 Translation { level: u8 },
7 AccessFlag { level: u8 },
8 Permission { level: u8 },
9 Alignment,
10 TLBConflict,
11 Other(u8),
12}
13
14const DFSC_MASK: u8 = 0x3f;
15const ISS_BRK_CMT_MASK: u16 = 0xffff;
16
17impl From<u32> for Fault {
18 fn from(origin: u32) -> Self {
19 let level = (origin & 0b11) as u8;
20 let origin = origin as u8;
21 match (origin & DFSC_MASK) >> 2 {
22 0b0000 => Fault::AddressSize { level },
23 0b0001 => Fault::Translation { level },
24 0b0010 => Fault::AccessFlag { level },
25 0b0011 => Fault::Permission { level },
26 0b1000 => Fault::Alignment,
27 0b1100 => Fault::TLBConflict,
28 _ => Fault::Other(origin & DFSC_MASK),
29 }
30 }
31}
32
33#[derive(Debug, Copy, Clone)]
34pub enum Syndrome {
35 Unknown,
36 PCAlignmentFault,
37 DataAbort(Fault),
38 InstructionAbort(Fault),
39 SPAlignmentFault,
40 Brk(u16),
41 HVC,
42 SMC,
43 SysRegInst,
44 WFX,
45 FPU,
46 SVE,
47 SME,
48 Other(u32),
49}
50
51impl From<u32> for Syndrome {
52 fn from(origin: u32) -> Self {
53 match (origin >> ESR_EL2::EC.shift) & ESR_EL2::EC.mask as u32 {
54 0b00_0000 => Syndrome::Unknown,
55 0b00_0001 => Syndrome::WFX,
56 0b00_0111 => Syndrome::FPU,
57 0b01_0010 => Syndrome::HVC,
58 0b01_0110 => Syndrome::HVC,
59 0b01_0011 => Syndrome::SMC,
60 0b01_0111 => Syndrome::SMC,
61 0b01_1000 => Syndrome::SysRegInst,
62 0b01_1001 => Syndrome::SVE,
63 0b01_1101 => Syndrome::SME,
64 0b10_0000 => {
65 debug!("Instruction Abort from a lower Exception level");
66 Syndrome::InstructionAbort(Fault::from(origin))
67 }
68 0b10_0001 => {
69 debug!("Instruction Abort taken without a change in Exception level");
70 Syndrome::InstructionAbort(Fault::from(origin))
71 }
72 0b10_0010 => Syndrome::PCAlignmentFault,
73 0b10_0100 => {
74 debug!("Data Abort from a lower Exception level");
75 Syndrome::DataAbort(Fault::from(origin))
76 }
77 0b10_0101 => {
78 debug!("Data Abort without a change in Exception level");
79 Syndrome::DataAbort(Fault::from(origin))
80 }
81 0b10_0110 => Syndrome::SPAlignmentFault,
82 0b11_1100 => Syndrome::Brk(origin as u16 & ISS_BRK_CMT_MASK),
83 ec => Syndrome::Other(ec),
84 }
85 }
86}
87
88impl Into<u64> for Syndrome {
89 fn into(self) -> u64 {
90 match self {
91 Syndrome::DataAbort(fault) => {
92 let ec: u64 = 0b10_0100 << ESR_EL2::EC.shift;
93 let iss: u64 = fault.into();
94 ec | iss
95 }
96 _ => {
97 panic!("Not implemented yet!");
98 }
99 }
100 }
101}
102
103impl Into<u64> for Fault {
104 fn into(self) -> u64 {
105 match self {
106 Fault::Translation { level } => (0b000100 | level) as u64,
107 _ => {
108 panic!("Not implemented yet!");
109 }
110 }
111 }
112}