1pub type ErrorCode = u16;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6#[repr(u16)]
7pub enum Error {
8 Ok = 0,
9 Unspecified = 1,
10 Unknown = 2,
11 NotReady = 3, NotImplemented = 4,
13 VersionTooHigh = 5,
14 VersionTooLow = 6,
15 InvalidArgument = 7,
16 OutOfMemory = 8,
17 NotAllowed = 9,
18 NotFound = 10,
19 InternalError = 11,
20 TimedOut = 12,
21 AlreadyInUse = 13,
22 UnexpectedEof = 14,
23 InvalidFilename = 15,
24 NotADirectory = 16,
25 BadHandle = 17,
26 FileTooLarge = 18,
27 NotConnected = 19,
28 StorageFull = 20,
29 InvalidData = 21,
30
31 Max,
33}
34
35pub type Result<T> = core::result::Result<T, Error>;
36
37impl core::fmt::Display for Error {
38 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
39 core::fmt::Debug::fmt(self, f)
40 }
41}
42
43impl From<Error> for ErrorCode {
44 fn from(val: Error) -> ErrorCode {
45 val as ErrorCode
46 }
47}
48
49impl From<u16> for Error {
50 fn from(val: u16) -> Self {
51 if val < Error::Max.into() {
52 unsafe { core::mem::transmute::<u16, Error>(val) }
54 } else {
55 Error::Unknown
56 }
57 }
58}
59
60pub const E_OK: u16 = Error::Ok as u16;
61pub const E_UNSPECIFIED: u16 = Error::Unspecified as u16;
62pub const E_UNKNOWN: u16 = Error::Unknown as u16;
63pub const E_NOT_READY: u16 = Error::NotReady as u16;
64pub const E_NOT_IMPLEMENTED: u16 = Error::NotImplemented as u16;
65pub const E_VERSION_TOO_HIGH: u16 = Error::VersionTooHigh as u16;
66pub const E_VERSION_TOO_LOW: u16 = Error::VersionTooLow as u16;
67pub const E_INVALID_ARGUMENT: u16 = Error::InvalidArgument as u16;
68pub const E_OUT_OF_MEMORY: u16 = Error::OutOfMemory as u16;
69pub const E_NOT_ALLOWED: u16 = Error::NotAllowed as u16;
70pub const E_NOT_FOUND: u16 = Error::NotFound as u16;
71pub const E_INTERNAL_ERROR: u16 = Error::InternalError as u16;
72pub const E_TIMED_OUT: u16 = Error::TimedOut as u16;
73pub const E_ALREADY_IN_USE: u16 = Error::AlreadyInUse as u16;
74pub const E_UNEXPECTED_EOF: u16 = Error::UnexpectedEof as u16;
75pub const E_INVALID_FILENAME: u16 = Error::InvalidFilename as u16;
76pub const E_NOT_A_DIRECTORY: u16 = Error::NotADirectory as u16;
77pub const E_BAD_HANDLE: u16 = Error::BadHandle as u16;
78pub const E_FILE_TOO_LARGE: u16 = Error::FileTooLarge as u16;
79pub const E_NOT_CONNECTED: u16 = Error::NotConnected as u16;
80pub const E_STORAGE_FULL: u16 = Error::StorageFull as u16;
81pub const E_INVALID_DATA: u16 = Error::InvalidData as u16;
82
83pub const E_MAX: u16 = u16::MAX;
84
85#[cfg(not(feature = "base"))]
86pub fn log_to_kernel(msg: &str) {
87 let vdso_log_to_kernel: extern "C" fn(*const u8, usize) = unsafe {
88 core::mem::transmute(
89 super::RtVdsoVtable::get()
90 .log_to_kernel
91 .load(core::sync::atomic::Ordering::Relaxed) as usize as *const (),
92 )
93 };
94
95 let bytes = msg.as_bytes();
96 vdso_log_to_kernel(bytes.as_ptr(), bytes.len());
97}
98
99#[cfg(not(feature = "base"))]
100#[macro_export]
101macro_rules! moto_log {
102 ($($arg:tt)*) => {
103 {
104 #[allow(unused_extern_crates)]
105 extern crate alloc;
106 $crate::error::log_to_kernel(alloc::format!($($arg)*).as_str());
107 }
108 };
109}
110
111#[cfg(not(feature = "base"))]
113pub fn log_backtrace(rt_fd: crate::RtFd) {
114 let vdso_log_backtrace: extern "C" fn(crate::RtFd) = unsafe {
115 core::mem::transmute(
116 super::RtVdsoVtable::get()
117 .log_backtrace
118 .load(core::sync::atomic::Ordering::Relaxed) as usize as *const (),
119 )
120 };
121
122 vdso_log_backtrace(rt_fd);
123}
124
125#[cfg(not(feature = "base"))]
126pub fn log_panic(info: &core::panic::PanicInfo<'_>) {
127 if crate::fs::is_terminal(crate::FD_STDERR) {
128 #[cfg(not(feature = "rustc-dep-of-std"))]
129 extern crate alloc;
130
131 let _ = crate::fs::write(crate::FD_STDERR, b"PANIC\n"); let msg = alloc::format!("PANIC: {info}\n");
133 let _ = crate::fs::write(crate::FD_STDERR, msg.as_bytes());
134 log_backtrace(crate::FD_STDERR);
135 } else {
136 log_to_kernel("PANIC"); moto_log!("PANIC: {}", info);
138 log_backtrace(-1);
139 }
140}
141
142#[cfg(not(feature = "base"))]
143pub fn into_result(val: ErrorCode) -> Result<()> {
144 if val == Error::Ok.into() {
145 Ok(())
146 } else {
147 Err(val.into())
148 }
149}
150
151#[cfg(not(feature = "base"))]
152#[macro_export]
153macro_rules! to_result {
154 ($arg:expr) => {{
155 let res = $arg;
156 if res < 0 {
157 Err(((-res) as ErrorCode).into())
158 } else {
159 Ok(unsafe { res.try_into().unwrap_unchecked() })
160 }
161 }};
162}