sel4/arch/arm/
fault.rs

1//
2// Copyright 2023, Colias Group, LLC
3// Copyright (c) 2020 Arm Limited
4//
5// SPDX-License-Identifier: MIT
6//
7
8use sel4_config::{sel4_cfg, sel4_cfg_enum, sel4_cfg_if, sel4_cfg_wrap_match};
9
10use crate::{declare_fault_newtype, sys, Word};
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
21sel4_cfg_if! {
22    if #[sel4_cfg(ARM_HYPERVISOR_SUPPORT)] {
23        declare_fault_newtype!(VGicMaintenance, seL4_Fault_VGICMaintenance);
24        declare_fault_newtype!(VCpuFault, seL4_Fault_VCPUFault);
25        declare_fault_newtype!(VPpiEvent, seL4_Fault_VPPIEvent);
26    }
27}
28
29/// Corresponds to `seL4_Fault`.
30#[sel4_cfg_enum]
31#[derive(Debug, Clone, PartialEq, Eq)]
32pub enum Fault {
33    NullFault(NullFault),
34    CapFault(CapFault),
35    UnknownSyscall(UnknownSyscall),
36    UserException(UserException),
37    VmFault(VmFault),
38    #[sel4_cfg(KERNEL_MCS)]
39    Timeout(Timeout),
40    #[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
41    VGicMaintenance(VGicMaintenance),
42    #[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
43    VCpuFault(VCpuFault),
44    #[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
45    VPpiEvent(VPpiEvent),
46}
47
48impl Fault {
49    pub fn from_sys(raw: sys::seL4_Fault) -> Self {
50        sel4_cfg_wrap_match! {
51            match raw.splay() {
52                sys::seL4_Fault_Splayed::NullFault(inner) => {
53                    Self::NullFault(NullFault::from_inner(inner))
54                }
55                sys::seL4_Fault_Splayed::CapFault(inner) => Self::CapFault(CapFault::from_inner(inner)),
56                sys::seL4_Fault_Splayed::UnknownSyscall(inner) => {
57                    Self::UnknownSyscall(UnknownSyscall::from_inner(inner))
58                }
59                sys::seL4_Fault_Splayed::UserException(inner) => {
60                    Self::UserException(UserException::from_inner(inner))
61                }
62                sys::seL4_Fault_Splayed::VMFault(inner) => Self::VmFault(VmFault::from_inner(inner)),
63                #[sel4_cfg(KERNEL_MCS)]
64                sys::seL4_Fault_Splayed::Timeout(inner) => Self::Timeout(Timeout::from_inner(inner)),
65                #[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
66                sys::seL4_Fault_Splayed::VGICMaintenance(inner) => {
67                    Self::VGicMaintenance(VGicMaintenance::from_inner(inner))
68                }
69                #[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
70                sys::seL4_Fault_Splayed::VCPUFault(inner) => {
71                    Self::VCpuFault(VCpuFault::from_inner(inner))
72                }
73                #[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
74                sys::seL4_Fault_Splayed::VPPIEvent(inner) => {
75                    Self::VPpiEvent(VPpiEvent::from_inner(inner))
76                }
77            }
78        }
79    }
80}
81
82impl CapFault {
83    // TODO
84}
85
86impl UnknownSyscall {
87    pub fn fault_ip(&self) -> Word {
88        self.inner().get_FaultIP()
89    }
90
91    pub fn sp(&self) -> Word {
92        self.inner().get_SP()
93    }
94
95    pub fn lr(&self) -> Word {
96        self.inner().get_LR()
97    }
98
99    pub fn syscall(&self) -> Word {
100        self.inner().get_Syscall()
101    }
102}
103
104impl UserException {
105    // TODO
106}
107
108impl VmFault {
109    pub fn ip(&self) -> Word {
110        self.inner().get_IP()
111    }
112
113    pub fn addr(&self) -> Word {
114        self.inner().get_Addr()
115    }
116
117    pub fn is_prefetch(&self) -> bool {
118        self.inner().get_PrefetchFault() != 0
119    }
120
121    pub fn fsr(&self) -> Word {
122        self.inner().get_FSR()
123    }
124}
125
126#[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
127impl VGicMaintenance {
128    pub fn idx(&self) -> Option<Word> {
129        match self.inner().get_IDX() {
130            Word::MAX => None,
131            idx => Some(idx),
132        }
133    }
134}
135
136#[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
137impl VCpuFault {
138    pub fn hsr(&self) -> Word {
139        self.inner().get_HSR()
140    }
141}
142
143#[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
144impl VPpiEvent {
145    pub fn irq(&self) -> Word {
146        self.inner().get_irq()
147    }
148}