const SYSCALL_READ: usize = 63; const SYSCALL_WRITE: usize = 64; const SYSCALL_EXIT: usize = 93; const SYSCALL_YIELD: usize = 124; const SYSCALL_GET_TIME: usize = 169; const SYSCALL_GETPID: usize = 172; const SYSCALL_FORK: usize = 220; const SYSCALL_EXEC: usize = 221; const SYSCALL_WAITPID: usize = 260; fn syscall(id: usize, args: [usize; 3]) -> isize { let mut ret: isize; unsafe { llvm_asm!("ecall" : "={x10}" (ret) : "{x10}" (args[0]), "{x11}" (args[1]), "{x12}" (args[2]), "{x17}" (id) : "memory" : "volatile" ); } ret } pub fn sys_read(fd: usize, buffer: &mut [u8]) -> isize { syscall(SYSCALL_READ, [fd, buffer.as_mut_ptr() as usize, buffer.len()]) } pub fn sys_write(fd: usize, buffer: &[u8]) -> isize { syscall(SYSCALL_WRITE, [fd, buffer.as_ptr() as usize, buffer.len()]) } pub fn sys_exit(exit_code: i32) -> ! { syscall(SYSCALL_EXIT, [exit_code as usize, 0, 0]); panic!("sys_exit never returns!"); } pub fn sys_yield() -> isize { syscall(SYSCALL_YIELD, [0, 0, 0]) } pub fn sys_get_time() -> isize { syscall(SYSCALL_GET_TIME, [0, 0, 0]) } pub fn sys_getpid() -> isize { syscall(SYSCALL_GETPID, [0, 0, 0]) } pub fn sys_fork() -> isize { syscall(SYSCALL_FORK, [0, 0, 0]) } pub fn sys_exec(path: &str) -> isize { syscall(SYSCALL_EXEC, [path.as_ptr() as usize, 0, 0]) } pub fn sys_waitpid(pid: isize, xstatus: *mut i32) -> isize { syscall(SYSCALL_WAITPID, [pid as usize, xstatus as usize, 0]) }