#[cfg(target_arch = "riscv64")]
use crate::arch::riscv::{syscall, SyscallTable};
#[cfg(target_arch = "x86_64")]
use crate::arch::x86_64::{syscall, SyscallTable};
use crate::interface::{isal, TimeSpec, Stat};
use crate::interface::{MemProt, MemFlags, OpenFlags};
use crate::os::abi_types;
pub struct SAL;
impl isal::Task for SAL {
fn create<Func>(_func: Func, _stack_top_ptr: usize) -> usize
where Func: Fn() + 'static {
1
}
fn destory(_tid: usize) {
}
}
impl isal::Memory for SAL {
fn mmap(
addr: usize,
size: usize,
prot: MemProt,
flags: MemFlags,
fd: usize,
offset: usize
) -> usize {
let ret;
#[cfg(target_arch = "riscv64")]
{
let mut args = abi_types::mmap_args_struct {
addr: addr,
len: size,
prot: prot.bits() as usize,
flags: flags.bits() as usize,
fd: fd,
offset: offset
};
let args_ptr = &mut args as *mut abi_types::mmap_args_struct;
ret = syscall(
SyscallTable::MMAP,
[
args_ptr as usize,
0, 0, 0, 0, 0
]
);
}
#[cfg(target_arch = "x86_64")]
{
ret = syscall(
SyscallTable::MMAP,
[
addr,
size,
prot.bits() as usize,
flags.bits() as usize,
fd,
offset
]
);
}
ret as usize
}
fn unmmap(addr: usize, len: usize) -> isize {
let ret = syscall(
SyscallTable::MUNMAP,
[
addr,
len,
0, 0, 0, 0
]
);
ret
}
}
impl isal::File for SAL {
fn sys_open(path_ptr: usize, flags: OpenFlags) -> isize {
syscall(
SyscallTable::OPEN,
[
path_ptr,
flags.bits(),
0, 0, 0, 0
]
)
}
fn sys_read(fd: usize, buffer: &mut [u8], len: usize) -> isize {
let mut ret = syscall(
SyscallTable::READ,
[
fd,
buffer.as_ptr() as usize,
len,
0, 0, 0
]
);
if ret == -21 { let read_size = syscall(
SyscallTable::GETDENTS,
[
fd,
buffer.as_ptr() as usize,
len,
0, 0, 0
]
);
if read_size < 0 {
return read_size;
}
let mut index: usize = 0;
let mut offset = 0;
while index < read_size as usize {
let dirent_ptr = (buffer[offset..]).as_ptr() as *mut abi_types::dirent;
let name_slice: &[u8];
unsafe { let dir_name_addr = (*dirent_ptr).d_name.as_ptr() as usize - 1;
name_slice = core::slice::from_raw_parts(
dir_name_addr as *const u8,
crate::strlen(dir_name_addr as *const u8)
);
offset += (*dirent_ptr).d_reclen as usize;
}
for y in 0..name_slice.len() {
buffer[index] = name_slice[y];
index += 1;
}
buffer[index] = '\n' as u8;
index += 1;
}
ret = index as isize;
}
ret
}
fn sys_write(fd: usize, buffer: &[u8]) -> isize {
syscall(
SyscallTable::WRITE,
[
fd,
buffer.as_ptr() as usize,
buffer.len(),
0, 0, 0
]
)
}
fn sys_ioctl(fd: usize, cmd: usize, arg: usize) -> isize {
syscall(
SyscallTable::IOCTL,
[
fd,
cmd,
arg,
0, 0, 0
]
)
}
fn sys_close(fd: usize) -> isize {
syscall(
SyscallTable::CLOSE,
[
fd,
0, 0, 0, 0, 0
]
)
}
fn sys_stat(path_ptr: usize, stat: &mut Stat) -> isize {
let mut file_stat: abi_types::stat = unsafe { core::mem::zeroed() };
let file_stat_ptr = (&mut file_stat as *const abi_types::stat) as usize;
let ret = syscall(
SyscallTable::STAT,
[
path_ptr,
file_stat_ptr,
0, 0, 0, 0
]
);
stat.dev = file_stat.st_dev;
stat.ino = file_stat.st_ino;
stat.mode = file_stat.st_mode;
stat.nlink = file_stat.st_nlink;
stat.uid = file_stat.st_uid;
stat.gid = file_stat.st_gid;
stat.rdev = file_stat.st_rdev;
stat.size = file_stat.st_size;
stat.blksize = file_stat.st_blksize;
stat.blocks = file_stat.st_blocks;
ret
}
}
impl isal::Process for SAL {
fn sys_exit(xstate: i32) -> isize {
syscall(
SyscallTable::EXIT,
[
xstate as usize,
0, 0, 0, 0, 0
]
)
}
}
impl isal::Time for SAL {
fn sys_nanosleep(req: TimeSpec, _rem: TimeSpec) -> isize {
let req_ptr = &req as *const TimeSpec;
syscall(
SyscallTable::NANOSLEEP,
[
req_ptr as usize,
0, 0, 0, 0, 0
]
)
}
}