mirror of
https://github.com/Noratrieb/rustv32i.git
synced 2026-01-14 13:25:01 +01:00
more syscalls
This commit is contained in:
parent
b2c3c9fc80
commit
d336c4af7d
1 changed files with 69 additions and 2 deletions
71
src/main.rs
71
src/main.rs
|
|
@ -54,9 +54,37 @@ fn ecall_handler(
|
|||
let nr = xreg[Reg::A7.0 as usize];
|
||||
|
||||
let arg0 = xreg[Reg::A0.0 as usize];
|
||||
let arg1 = xreg[Reg::A1.0 as usize];
|
||||
let arg2 = xreg[Reg::A2.0 as usize];
|
||||
|
||||
// https://jborza.com/post/2021-05-11-riscv-linux-syscalls/
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/unistd.h
|
||||
match nr {
|
||||
// ioctl
|
||||
29 => {
|
||||
let fd = arg0;
|
||||
let request = arg1;
|
||||
|
||||
match request {
|
||||
// TIOCGWINSZ
|
||||
0x5413 => {
|
||||
let wsz_ptr = xreg[Reg::A2.0 as usize];
|
||||
|
||||
let mut wsz: libc::winsize = unsafe { std::mem::zeroed() };
|
||||
|
||||
let r = unsafe { libc::ioctl(fd as i32, libc::TIOCGWINSZ, &mut wsz) };
|
||||
|
||||
xreg[Reg::A0.0 as usize] = r as u32;
|
||||
if r >= 0 {
|
||||
mem.store_u16(wsz_ptr, wsz.ws_row)?;
|
||||
mem.store_u16(wsz_ptr + 2, wsz.ws_col)?;
|
||||
mem.store_u16(wsz_ptr + 4, wsz.ws_xpixel)?;
|
||||
mem.store_u16(wsz_ptr + 6, wsz.ws_ypixel)?;
|
||||
}
|
||||
}
|
||||
_ => todo!("unknown ioctl: {request}"),
|
||||
}
|
||||
}
|
||||
// read
|
||||
63 => {
|
||||
let fd = arg0;
|
||||
|
|
@ -91,8 +119,39 @@ fn ecall_handler(
|
|||
|
||||
xreg[Reg::A0.0 as usize] = ret;
|
||||
}
|
||||
// exit
|
||||
93 => {
|
||||
// https://man7.org/linux/man-pages/man3/writev.3p.html
|
||||
66 => {
|
||||
let fd = arg0;
|
||||
let iovec = arg1;
|
||||
let iovcnt = arg2;
|
||||
|
||||
let mut written = 0;
|
||||
|
||||
for i in 0..iovcnt {
|
||||
let iov_ptr = mem.load_u32(iovec + i * 8)?;
|
||||
let iov_len = mem.load_u32(iovec + i * 8 + 4)?;
|
||||
|
||||
let data = mem.slice(iov_ptr, iov_len)?;
|
||||
|
||||
let len = unsafe { libc::write(fd as i32, data.as_ptr().cast(), data.len()) };
|
||||
let ret = if len < 0 {
|
||||
(-std::io::Error::last_os_error().raw_os_error().unwrap_or(1)) as u32
|
||||
} else {
|
||||
len as u32
|
||||
};
|
||||
|
||||
if (ret as i32) < 0 {
|
||||
xreg[Reg::A0.0 as usize] = ret;
|
||||
return Ok(());
|
||||
} else {
|
||||
written += ret;
|
||||
}
|
||||
}
|
||||
|
||||
xreg[Reg::A0.0 as usize] = written;
|
||||
}
|
||||
// exit | exit_group
|
||||
93 | 94 => {
|
||||
return Err(emu::Status::Exit {
|
||||
code: xreg[Reg::A0.0 as usize] as i32,
|
||||
});
|
||||
|
|
@ -104,6 +163,14 @@ fn ecall_handler(
|
|||
|
||||
xreg[Reg::A0.0 as usize] = 1; // thread ID
|
||||
}
|
||||
// ppoll - called for some stdin/stdout/stderr check.
|
||||
414 => {
|
||||
// musl uses ppoll to batch check whether FDs 0,1,2 are invalid,
|
||||
// and opens /dev/null for them if they are.
|
||||
// They're always valid here, so just get out.
|
||||
|
||||
xreg[Reg::A0.0 as usize] = 0;
|
||||
}
|
||||
_ => {
|
||||
todo!("unkonwn syscall: {nr}");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue