1use ax_alloc::AllocError;
2#[cfg(feature = "paging")]
3use ax_hal::cache::TlbShootdownError;
4use ax_hal::irq::IrqError;
5#[cfg(feature = "paging")]
6use ax_mm::MmError;
7#[cfg(feature = "fs")]
8use axfs_ng_vfs::VfsError;
9#[cfg(feature = "paging")]
10use axklib::KlibError;
11use rdif_serial::ConfigError;
12
13use crate::task::thread::TaskError;
14
15#[derive(Clone, Copy, Debug, Eq, PartialEq, thiserror::Error)]
17pub enum RuntimeError {
18 #[cfg(feature = "paging")]
20 #[error(transparent)]
21 Mm(#[from] MmError),
22 #[cfg(feature = "paging")]
24 #[error(transparent)]
25 TlbShootdown(#[from] TlbShootdownError),
26 #[error(transparent)]
28 Irq(#[from] IrqError),
29 #[error(transparent)]
31 Allocation(#[from] AllocError),
32 #[cfg(feature = "fs")]
34 #[error(transparent)]
35 Vfs(#[from] VfsError),
36 #[error(transparent)]
38 Task(#[from] TaskError),
39 #[error(transparent)]
41 SerialConfig(#[from] ConfigError),
42 #[error(transparent)]
44 ConsoleHandoff(#[from] ax_hal::console::ConsoleHandoffError),
45 #[error("another serial runtime already owns console routing")]
47 SerialConsoleBusy,
48 #[error("runtime console failed closed")]
50 ConsoleFailedClosed,
51 #[error("serial runtime is not started")]
53 SerialNotStarted,
54 #[error("serial control queue is busy")]
56 SerialControlBusy,
57 #[error("runtime operation would block")]
59 WouldBlock,
60 #[error("runtime operation is not supported")]
62 OperationNotSupported,
63 #[error("invalid runtime CPU index {cpu}")]
65 InvalidCpu { cpu: usize },
66}
67
68pub type RuntimeResult<T = ()> = Result<T, RuntimeError>;
70
71#[cfg(feature = "paging")]
73pub(crate) fn runtime_error_to_klib_error(error: RuntimeError) -> KlibError {
74 match error {
75 #[cfg(feature = "paging")]
76 RuntimeError::Mm(error) => match error {
77 MmError::InvalidInput(_) => KlibError::InvalidInput,
78 MmError::NoMemory => KlibError::NoMemory,
79 MmError::AlreadyExists => KlibError::AlreadyExists,
80 MmError::BadAddress => KlibError::BadAddress,
81 MmError::BadState(_) => KlibError::BadState,
82 MmError::Unsupported => KlibError::Unsupported,
83 MmError::TlbShootdown(error) => match error {
84 TlbShootdownError::CpuOffline | TlbShootdownError::Unsupported => {
85 KlibError::Unsupported
86 }
87 TlbShootdownError::Timeout => KlibError::TimedOut,
88 TlbShootdownError::Platform => KlibError::Io,
89 TlbShootdownError::GenerationExhausted => KlibError::BadState,
90 },
91 },
92 #[cfg(feature = "paging")]
93 RuntimeError::TlbShootdown(error) => match error {
94 TlbShootdownError::CpuOffline | TlbShootdownError::Unsupported => {
95 KlibError::Unsupported
96 }
97 TlbShootdownError::Timeout => KlibError::TimedOut,
98 TlbShootdownError::GenerationExhausted => KlibError::BadState,
99 TlbShootdownError::Platform => KlibError::Io,
100 },
101 RuntimeError::Irq(error) => match error {
102 IrqError::InvalidIrq | IrqError::InvalidCpu => KlibError::InvalidInput,
103 IrqError::CpuOffline | IrqError::Unsupported => KlibError::Unsupported,
104 IrqError::Timeout => KlibError::TimedOut,
105 IrqError::Busy | IrqError::InIrqContext => KlibError::ResourceBusy,
106 IrqError::NoMemory => KlibError::NoMemory,
107 IrqError::NotFound => KlibError::NotFound,
108 IrqError::Controller => KlibError::Io,
109 },
110 RuntimeError::Allocation(_) => KlibError::NoMemory,
111 #[cfg(feature = "fs")]
112 RuntimeError::Vfs(error) => match error {
113 VfsError::AlreadyExists => KlibError::AlreadyExists,
114 VfsError::BadAddress => KlibError::BadAddress,
115 VfsError::NoMemory => KlibError::NoMemory,
116 VfsError::ResourceBusy => KlibError::ResourceBusy,
117 VfsError::TimedOut => KlibError::TimedOut,
118 VfsError::Unsupported | VfsError::OperationNotSupported => KlibError::Unsupported,
119 _ => KlibError::Io,
120 },
121 RuntimeError::Task(error) => task_error_to_klib_error(error),
122 RuntimeError::SerialConfig(error) => match error {
123 ConfigError::InvalidBaudrate
124 | ConfigError::UnsupportedDataBits
125 | ConfigError::UnsupportedStopBits
126 | ConfigError::UnsupportedParity => KlibError::InvalidInput,
127 ConfigError::Timeout => KlibError::TimedOut,
128 ConfigError::RegisterError => KlibError::Io,
129 },
130 RuntimeError::ConsoleHandoff(_) => KlibError::BadState,
131 RuntimeError::SerialConsoleBusy => KlibError::ResourceBusy,
132 RuntimeError::ConsoleFailedClosed => KlibError::BadState,
133 RuntimeError::SerialNotStarted => KlibError::BadState,
134 RuntimeError::SerialControlBusy => KlibError::ResourceBusy,
135 RuntimeError::WouldBlock => KlibError::ResourceBusy,
136 RuntimeError::OperationNotSupported => KlibError::Unsupported,
137 RuntimeError::InvalidCpu { .. } => KlibError::InvalidInput,
138 }
139}
140
141#[cfg(feature = "paging")]
142fn task_error_to_klib_error(error: TaskError) -> KlibError {
143 use ax_task::runtime::RuntimeStatus;
144
145 match error {
146 TaskError::InvalidConfiguration
147 | TaskError::InvalidCpuCount(_)
148 | TaskError::InvalidCpu(_)
149 | TaskError::InvalidNice(_)
150 | TaskError::InvalidRtPriority(_)
151 | TaskError::InvalidRoundRobinQuantum
152 | TaskError::InvalidDeadline { .. }
153 | TaskError::UnsupportedDeadlineFlags(_) => KlibError::InvalidInput,
154 TaskError::TimerCapacity | TaskError::ThreadCapacity => KlibError::NoMemory,
155 TaskError::RuntimeFailure(status) if status == RuntimeStatus::NoMemory as u32 => {
156 KlibError::NoMemory
157 }
158 TaskError::CpuOffline(_)
159 | TaskError::CpuNotQuiescent(_)
160 | TaskError::LastOnlineCpu(_)
161 | TaskError::DeadlineAdmission
162 | TaskError::DeadlineAffinity
163 | TaskError::ActiveTimerAffinity
164 | TaskError::ThreadBusy
165 | TaskError::CpuOwnerBorrowed => KlibError::ResourceBusy,
166 TaskError::StaleThreadId => KlibError::NotFound,
167 TaskError::UnsafeContext
168 | TaskError::NotInitialized
169 | TaskError::InvalidRuntimeHandle
170 | TaskError::CpuOwnerMismatch { .. }
171 | TaskError::ExecutorOwnerMismatch { .. }
172 | TaskError::CpuAlreadyOnline(_)
173 | TaskError::InvalidTransition { .. }
174 | TaskError::AlreadyQueued
175 | TaskError::NotReady
176 | TaskError::NotExited
177 | TaskError::NoRunnableThread
178 | TaskError::InvalidPiState
179 | TaskError::InvalidPiWaitState(_)
180 | TaskError::PiCycle
181 | TaskError::PiChainLimit { .. }
182 | TaskError::RuntimeFailure(_) => KlibError::BadState,
183 }
184}