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