Skip to main content

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::{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/// Corresponds to `seL4_Fault`.
33#[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    // TODO
93}
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    // TODO
115}
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}