cannon_io/syscalls/
mod.rs1use raw::{syscall1, syscall3};
5
6#[cfg(target_arch = "mips")]
7mod raw;
8#[cfg(not(target_arch = "mips"))]
10mod raw {
11 pub unsafe fn syscall1(_: u32, _: u32) -> u32 {
12 todo!("Crate can only work on MIPS target")
13 }
14 pub unsafe fn syscall3(_: u32, _: u32, _: u32, _: u32) -> Result<u32, i32> {
15 todo!("Crate can only work on MIPS target")
16 }
17}
18
19enum FileDescriptor {
20 StdOut = 1,
21 HintRead = 3,
22 HintWrite = 4,
23 PreimageRead = 5,
24 PreimageWrite = 6,
25}
26enum SyscallNo {
27 Exit = 4246,
28 Read = 4003,
29 Write = 4004,
30}
31
32#[derive(Debug)]
33pub enum SyscallError {
34 Code(u32),
35}
36
37impl From<i32> for SyscallError {
38 fn from(code: i32) -> Self {
39 SyscallError::Code(code as u32)
40 }
41}
42
43type Result<T> = core::result::Result<T, SyscallError>;
44
45pub fn print(s: &str) -> Result<u32> {
46 write(FileDescriptor::StdOut, s.as_bytes())
47}
48
49pub fn write_preimage(key: &[u8]) -> Result<u32> {
50 write(FileDescriptor::PreimageWrite, key)
51}
52
53pub fn read_preimage(out: &mut [u8]) -> Result<u32> {
54 read(FileDescriptor::PreimageRead, out)
55}
56
57pub fn write_hint(key: [u8; 32]) -> Result<u32> {
58 write(FileDescriptor::HintWrite, &key)
59}
60
61pub fn read_hint(out: &mut [u8]) -> Result<u32> {
62 read(FileDescriptor::HintRead, out)
63}
64
65pub fn exit(code: u8) -> ! {
66 unsafe {
67 syscall1(SyscallNo::Exit as u32, code.into());
68 panic!() }
70}
71
72fn write(fd: FileDescriptor, buf: &[u8]) -> Result<u32> {
73 let result = unsafe {
74 syscall3(
75 SyscallNo::Write as u32,
76 fd as u32,
77 buf.as_ptr() as u32,
78 buf.len() as u32,
79 )
80 };
81 result.map_err(SyscallError::from)
82}
83
84fn read(fd: FileDescriptor, buf: &mut [u8]) -> Result<u32> {
85 let result = unsafe {
86 syscall3(
87 SyscallNo::Read as u32,
88 fd as u32,
89 buf.as_ptr() as u32,
90 buf.len() as u32,
91 )
92 };
93 result.map_err(SyscallError::from)
94}