1#![no_std]
2mod definitions;
3pub use definitions::*;
4
5pub mod ns;
6
7#[cfg(feature = "unstable_mem")]
8mod unstable;
9#[cfg(feature = "unstable_mem")]
10pub use unstable::*;
11
12#[inline]
17pub unsafe fn raw_syscall(
18 mut a0: usize,
19 mut a1: usize,
20 mut a2: usize,
21 mut a3: usize,
22 mut a4: usize,
23 mut a5: usize,
24 mut a6: usize,
25 mut a7: usize,
26) -> (usize, usize, usize, usize, usize, usize, usize, usize) {
27 unsafe {
28 core::arch::asm!(
29 "ecall",
30 inlateout("a0") a0,
31 inlateout("a1") a1,
32 inlateout("a2") a2,
33 inlateout("a3") a3,
34 inlateout("a4") a4,
35 inlateout("a5") a5,
36 inlateout("a6") a6,
37 inlateout("a7") a7,
38 )
39 };
40 (a0, a1, a2, a3, a4, a5, a6, a7)
41}
42
43#[inline]
47pub unsafe fn syscall(
48 a0: Syscall,
49 a1: usize,
50 a2: usize,
51 a3: usize,
52 a4: usize,
53 a5: usize,
54 a6: usize,
55 a7: usize,
56) -> Result<(usize, usize, usize, usize, usize, usize, usize, usize), Error> {
57 let result = unsafe { raw_syscall(a0 as usize, a1, a2, a3, a4, a5, a6, a7) };
58 if result.0 == 1 {
59 return Err(result.1.into());
60 }
61 Ok((
62 result.0, result.1, result.2, result.3, result.4, result.5, result.6, result.7,
63 ))
64}
65
66pub fn lend_mut(
69 connection: Connection,
70 opcode: usize,
71 data: &mut [u8],
72 arg1: usize,
73 arg2: usize,
74) -> Result<(usize, usize), Error> {
75 let result = unsafe {
76 syscall(
77 Syscall::SendMessage,
78 connection.0 as _,
79 InvokeType::LendMut as _,
80 opcode,
81 data.as_ptr() as usize,
82 data.len(),
83 arg1,
84 arg2,
85 )?
86 };
87 Ok((result.1, result.2))
88}
89
90pub fn try_lend_mut(
93 connection: Connection,
94 opcode: usize,
95 data: &mut [u8],
96 arg1: usize,
97 arg2: usize,
98) -> Result<(usize, usize), Error> {
99 let result = unsafe {
100 syscall(
101 Syscall::TrySendMessage,
102 connection.0 as _,
103 InvokeType::LendMut as _,
104 opcode,
105 data.as_ptr() as usize,
106 data.len(),
107 arg1,
108 arg2,
109 )?
110 };
111 Ok((result.1, result.2))
112}
113
114pub fn lend(
116 connection: Connection,
117 opcode: usize,
118 data: &[u8],
119 arg1: usize,
120 arg2: usize,
121) -> Result<(usize, usize), Error> {
122 let result = unsafe {
123 syscall(
124 Syscall::SendMessage,
125 connection.0 as _,
126 InvokeType::Lend as _,
127 opcode,
128 data.as_ptr() as usize,
129 data.len(),
130 arg1,
131 arg2,
132 )?
133 };
134 Ok((result.1, result.2))
135}
136
137pub fn try_lend(
140 connection: Connection,
141 opcode: usize,
142 data: &[u8],
143 arg1: usize,
144 arg2: usize,
145) -> Result<(usize, usize), Error> {
146 let result = unsafe {
147 syscall(
148 Syscall::TrySendMessage,
149 connection.0 as _,
150 InvokeType::Lend as _,
151 opcode,
152 data.as_ptr() as usize,
153 data.len(),
154 arg1,
155 arg2,
156 )?
157 };
158 Ok((result.1, result.2))
159}
160
161pub fn scalar(connection: Connection, args: [usize; 5]) -> Result<(), Error> {
163 unsafe {
164 syscall(
165 Syscall::SendMessage,
166 connection.0 as _,
167 InvokeType::Scalar as _,
168 args[0],
169 args[1],
170 args[2],
171 args[3],
172 args[4],
173 )?
174 };
175 Ok(())
176}
177
178pub fn try_scalar(connection: Connection, args: [usize; 5]) -> Result<(), Error> {
180 unsafe {
181 syscall(
182 Syscall::TrySendMessage,
183 connection.0 as _,
184 InvokeType::Scalar as _,
185 args[0],
186 args[1],
187 args[2],
188 args[3],
189 args[4],
190 )?
191 };
192 Ok(())
193}
194
195pub fn blocking_scalar(connection: Connection, args: [usize; 5]) -> Result<[usize; 5], Error> {
198 let result = unsafe {
199 syscall(
200 Syscall::SendMessage,
201 connection.0 as _,
202 InvokeType::BlockingScalar as _,
203 args[0],
204 args[1],
205 args[2],
206 args[3],
207 args[4],
208 )?
209 };
210 Ok([result.1, result.2, result.3, result.4, result.5])
211}
212
213pub fn try_blocking_scalar(connection: Connection, args: [usize; 5]) -> Result<[usize; 5], Error> {
216 let result = unsafe {
217 syscall(
218 Syscall::TrySendMessage,
219 connection.0 as _,
220 InvokeType::BlockingScalar as _,
221 args[0],
222 args[1],
223 args[2],
224 args[3],
225 args[4],
226 )?
227 };
228 Ok([result.1, result.2, result.3, result.4, result.5])
229}
230
231pub fn connect(address: ServerAddress) -> Result<Connection, Error> {
236 let result = unsafe {
237 syscall(
238 Syscall::Connect,
239 address.0[0] as usize,
240 address.0[1] as usize,
241 address.0[2] as usize,
242 address.0[3] as usize,
243 0,
244 0,
245 0,
246 )?
247 };
248 Ok(Connection(result.1 as u32))
249}
250
251pub fn try_connect(address: ServerAddress) -> Result<Option<Connection>, Error> {
255 let result = unsafe {
256 syscall(
257 Syscall::Connect,
258 address.0[0] as usize,
259 address.0[1] as usize,
260 address.0[2] as usize,
261 address.0[3] as usize,
262 0,
263 0,
264 0,
265 )
266 };
267 match result {
268 Ok(val) => Ok(Some(Connection(val.1 as u32))),
269 Err(Error::ServerNotFound) => Ok(None),
270 Err(e) => Err(e),
271 }
272}
273
274pub unsafe fn disconnect(connection: Connection) -> Result<(), Error> {
280 unsafe { syscall(Syscall::Disconnect, connection.0 as _, 0, 0, 0, 0, 0, 0)? };
281 Ok(())
282}
283
284pub fn exit(exit_code: u32) -> ! {
286 let _ = unsafe { syscall(Syscall::TerminateProcess, exit_code as _, 0, 0, 0, 0, 0, 0) };
287 unreachable!();
288}
289
290pub fn do_yield() {
294 let _ = unsafe { syscall(Syscall::Yield, 0, 0, 0, 0, 0, 0, 0) };
295}
296
297pub fn join_thread(thread_id: ThreadId) -> Result<usize, Error> {
299 let result = unsafe { syscall(Syscall::JoinThread, thread_id.into(), 0, 0, 0, 0, 0, 0)? };
300 Ok(result.1)
301}
302
303pub fn thread_id() -> Result<ThreadId, Error> {
305 let result = unsafe { syscall(Syscall::GetThreadId, 0, 0, 0, 0, 0, 0, 0)? };
306 Ok(result.1.into())
307}
308
309pub fn adjust_limit(knob: Limits, current: usize, new: usize) -> Result<usize, Error> {
318 let result = unsafe {
319 syscall(
320 Syscall::AdjustProcessLimit,
321 knob as usize,
322 current,
323 new,
324 0,
325 0,
326 0,
327 0,
328 )?
329 };
330
331 if result.0 == SyscallResult::Scalar2 as usize && result.1 == knob as usize {
332 Ok(result.2)
333 } else if result.0 == SyscallResult::Scalar5 as usize && result.1 == knob as usize {
334 Ok(result.1)
335 } else {
336 Err(Error::InternalError)
337 }
338}