1use sel4_config::{sel4_cfg, sel4_cfg_enum, sel4_cfg_if, sel4_cfg_wrap_match};
9
10use crate::{Word, declare_fault_newtype, sys};
11
12declare_fault_newtype!(NullFault, seL4_Fault_NullFault);
13declare_fault_newtype!(CapFault, seL4_Fault_CapFault);
14declare_fault_newtype!(UnknownSyscall, seL4_Fault_UnknownSyscall);
15declare_fault_newtype!(UserException, seL4_Fault_UserException);
16declare_fault_newtype!(VmFault, seL4_Fault_VMFault);
17
18#[sel4_cfg(KERNEL_MCS)]
19declare_fault_newtype!(Timeout, seL4_Fault_Timeout);
20
21#[sel4_cfg(HARDWARE_DEBUG_API)]
22declare_fault_newtype!(DebugException, seL4_Fault_DebugException);
23
24sel4_cfg_if! {
25 if #[sel4_cfg(ARM_HYPERVISOR_SUPPORT)] {
26 declare_fault_newtype!(VGicMaintenance, seL4_Fault_VGICMaintenance);
27 declare_fault_newtype!(VCpuFault, seL4_Fault_VCPUFault);
28 declare_fault_newtype!(VPpiEvent, seL4_Fault_VPPIEvent);
29 }
30}
31
32#[sel4_cfg_enum]
34#[derive(Debug, Clone, PartialEq, Eq)]
35pub enum Fault {
36 NullFault(NullFault),
37 CapFault(CapFault),
38 UnknownSyscall(UnknownSyscall),
39 UserException(UserException),
40 VmFault(VmFault),
41 #[sel4_cfg(KERNEL_MCS)]
42 Timeout(Timeout),
43 #[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
44 VGicMaintenance(VGicMaintenance),
45 #[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
46 VCpuFault(VCpuFault),
47 #[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
48 VPpiEvent(VPpiEvent),
49 #[sel4_cfg(HARDWARE_DEBUG_API)]
50 DebugException(DebugException),
51}
52
53impl Fault {
54 pub fn from_sys(raw: sys::seL4_Fault) -> Self {
55 sel4_cfg_wrap_match! {
56 match raw.splay() {
57 sys::seL4_Fault_Splayed::NullFault(inner) => {
58 Self::NullFault(NullFault::from_inner(inner))
59 }
60 sys::seL4_Fault_Splayed::CapFault(inner) => Self::CapFault(CapFault::from_inner(inner)),
61 sys::seL4_Fault_Splayed::UnknownSyscall(inner) => {
62 Self::UnknownSyscall(UnknownSyscall::from_inner(inner))
63 }
64 sys::seL4_Fault_Splayed::UserException(inner) => {
65 Self::UserException(UserException::from_inner(inner))
66 }
67 sys::seL4_Fault_Splayed::VMFault(inner) => Self::VmFault(VmFault::from_inner(inner)),
68 #[sel4_cfg(KERNEL_MCS)]
69 sys::seL4_Fault_Splayed::Timeout(inner) => Self::Timeout(Timeout::from_inner(inner)),
70 #[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
71 sys::seL4_Fault_Splayed::VGICMaintenance(inner) => {
72 Self::VGicMaintenance(VGicMaintenance::from_inner(inner))
73 }
74 #[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
75 sys::seL4_Fault_Splayed::VCPUFault(inner) => {
76 Self::VCpuFault(VCpuFault::from_inner(inner))
77 }
78 #[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
79 sys::seL4_Fault_Splayed::VPPIEvent(inner) => {
80 Self::VPpiEvent(VPpiEvent::from_inner(inner))
81 }
82 #[sel4_cfg(HARDWARE_DEBUG_API)]
83 sys::seL4_Fault_Splayed::DebugException(inner) => {
84 Self::DebugException(DebugException::from_inner(inner))
85 }
86 }
87 }
88 }
89}
90
91impl CapFault {
92 }
94
95impl UnknownSyscall {
96 pub fn fault_ip(&self) -> Word {
97 self.inner().get_FaultIP()
98 }
99
100 pub fn sp(&self) -> Word {
101 self.inner().get_SP()
102 }
103
104 pub fn lr(&self) -> Word {
105 self.inner().get_LR()
106 }
107
108 pub fn syscall(&self) -> Word {
109 self.inner().get_Syscall()
110 }
111}
112
113impl UserException {
114 }
116
117impl VmFault {
118 pub fn ip(&self) -> Word {
119 self.inner().get_IP()
120 }
121
122 pub fn addr(&self) -> Word {
123 self.inner().get_Addr()
124 }
125
126 pub fn is_prefetch(&self) -> bool {
127 self.inner().get_PrefetchFault() != 0
128 }
129
130 pub fn fsr(&self) -> Word {
131 self.inner().get_FSR()
132 }
133}
134
135#[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
136impl VGicMaintenance {
137 pub fn idx(&self) -> Option<Word> {
138 match self.inner().get_IDX() {
139 Word::MAX => None,
140 idx => Some(idx),
141 }
142 }
143}
144
145#[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
146impl VCpuFault {
147 pub fn hsr(&self) -> Word {
148 self.inner().get_HSR()
149 }
150}
151
152#[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
153impl VPpiEvent {
154 pub fn irq(&self) -> Word {
155 self.inner().get_irq()
156 }
157}