use crate::definitions::{
Connection, Error, InvokeType, MemoryFlags, Syscall, SyscallResult, ThreadId,
};
use crate::syscall;
pub fn r#move(
connection: Connection,
opcode: usize,
data: Box<[u8]>,
arg1: usize,
arg2: usize,
) -> Result<(), Error> {
let (addr, len) = (data.as_ptr() as usize, data.len());
core::mem::forget(data);
unsafe {
syscall(
Syscall::SendMessage,
connection.0 as _,
InvokeType::Move as _,
opcode,
addr,
len,
arg1,
arg2,
)?
};
Ok(())
}
pub fn try_move(
connection: Connection,
opcode: usize,
data: Box<[u8]>,
arg1: usize,
arg2: usize,
) -> Result<(), Error> {
let (addr, len) = (data.as_ptr() as usize, data.len());
core::mem::forget(data);
unsafe {
syscall(
Syscall::TrySendMessage,
connection.0 as _,
InvokeType::Move as _,
opcode,
addr,
len,
arg1,
arg2,
)?
};
Ok(())
}
pub unsafe fn map_memory<T>(
phys: Option<core::ptr::NonNull<T>>,
virt: Option<core::ptr::NonNull<T>>,
count: usize,
flags: MemoryFlags,
) -> Result<Box<[T]>, Error> {
let result = unsafe {
syscall(
Syscall::MapMemory,
phys.map(|p| p.as_ptr() as usize).unwrap_or_default(),
virt.map(|p| p.as_ptr() as usize).unwrap_or_default(),
count * size_of::<T>(),
flags.bits(),
0,
0,
0,
)?
};
if result.0 != SyscallResult::MemoryRange as usize {
return Err(Error::InternalError);
}
let start = core::ptr::with_exposed_provenance_mut::<T>(result.1);
let len = result.2 / size_of::<T>();
Ok(unsafe { Box::from_raw(core::slice::from_raw_parts_mut(start, len)) })
}
pub unsafe fn unmap_memory<T>(range: Box<[T]>) -> Result<(), Error> {
unsafe {
syscall(
Syscall::UnmapMemory,
range.as_ptr() as usize,
range.len() * size_of::<T>(),
0,
0,
0,
0,
0,
)?
};
core::mem::forget(range);
Ok(())
}
pub unsafe fn update_memory_flags<T>(
range: &mut Box<[T]>,
new_flags: MemoryFlags,
) -> Result<(), Error> {
unsafe {
syscall(
Syscall::UpdateMemoryFlags,
range.as_mut_ptr() as _,
range.len() * size_of::<T>(),
new_flags.bits(),
0, 0,
0,
0,
)?
};
Ok(())
}
pub fn create_thread(
start: *mut usize,
stack: Box<[u8]>,
arg0: usize,
arg1: usize,
arg2: usize,
arg3: usize,
) -> Result<ThreadId, Error> {
let result = unsafe {
syscall(
Syscall::CreateThread,
start as usize,
stack.as_ptr() as _,
stack.len(),
arg0,
arg1,
arg2,
arg3,
)?
};
core::mem::forget(stack);
if result.0 != SyscallResult::ThreadId as usize {
return Err(Error::InternalError);
}
Ok(result.1.into())
}