Skip to main content

ax_runtime/
error.rs

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/// Errors owned by the ArceOS runtime layer.
16#[derive(Clone, Copy, Debug, Eq, PartialEq, thiserror::Error)]
17pub enum RuntimeError {
18    /// Address-space management failed while updating runtime mappings.
19    #[cfg(feature = "paging")]
20    #[error(transparent)]
21    Mm(#[from] MmError),
22    /// A cross-CPU TLB invalidation failed after a mapping update.
23    #[cfg(feature = "paging")]
24    #[error(transparent)]
25    TlbShootdown(#[from] TlbShootdownError),
26    /// Interrupt discovery or registration failed.
27    #[error(transparent)]
28    Irq(#[from] IrqError),
29    /// Runtime-owned storage allocation failed.
30    #[error(transparent)]
31    Allocation(#[from] AllocError),
32    /// A filesystem operation used by a runtime adapter failed.
33    #[cfg(feature = "fs")]
34    #[error(transparent)]
35    Vfs(#[from] VfsError),
36    /// The scheduler rejected a runtime-owned task operation.
37    #[error(transparent)]
38    Task(#[from] TaskError),
39    /// A UART rejected its requested configuration.
40    #[error(transparent)]
41    SerialConfig(#[from] ConfigError),
42    /// A platform console ownership transition was requested out of order.
43    #[error(transparent)]
44    ConsoleHandoff(#[from] ax_hal::console::ConsoleHandoffError),
45    /// Another serial runtime already owns console log routing.
46    #[error("another serial runtime already owns console routing")]
47    SerialConsoleBusy,
48    /// The runtime console handoff failed after early ownership was revoked.
49    #[error("runtime console failed closed")]
50    ConsoleFailedClosed,
51    /// A serial operation requires a running port.
52    #[error("serial runtime is not started")]
53    SerialNotStarted,
54    /// The bounded serial control queue is full.
55    #[error("serial control queue is busy")]
56    SerialControlBusy,
57    /// A bounded runtime queue has no capacity without waiting.
58    #[error("runtime operation would block")]
59    WouldBlock,
60    /// The selected runtime capability does not support the operation.
61    #[error("runtime operation is not supported")]
62    OperationNotSupported,
63    /// A CPU index is outside the runtime's online CPU set.
64    #[error("invalid runtime CPU index {cpu}")]
65    InvalidCpu { cpu: usize },
66}
67
68/// A result returned by an ArceOS runtime-owned operation.
69pub type RuntimeResult<T = ()> = Result<T, RuntimeError>;
70
71/// Adapt a runtime-domain error at the external kernel capability boundary.
72#[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}