use core::mem::MaybeUninit;
use moa_uapi::{
error::{ERR_FAULT, ERR_INVAL, ERR_NO_RESOURCE, ERR_NOT_FOUND, ERR_PERM},
sched::SchedParam,
sysnr::{
SYSNR_TASK_CLOSE, SYSNR_TASK_CREATE, SYSNR_TASK_GET_REGS, SYSNR_TASK_GET_STATUS,
SYSNR_TASK_SET_POLICY, SYSNR_TASK_SET_REGS, SYSNR_TASK_START,
},
task::{RegMask, TaskCreateArgs, TaskHandle, TaskRegs, TaskStatus},
};
pub type Result<T> = core::result::Result<T, TaskError>;
define_syscall_error! {
pub enum TaskError {
Perm = ERR_PERM,
NotFound = ERR_NOT_FOUND,
Inval = ERR_INVAL,
NoResource = ERR_NO_RESOURCE,
Fault = ERR_FAULT,
}
}
pub fn task_create(args: &TaskCreateArgs) -> Result<TaskHandle> {
let ret =
unsafe { super::arch::syscall1(SYSNR_TASK_CREATE, args as *const TaskCreateArgs as usize) };
if ret < 0 {
Err(TaskError::from_raw(ret))
} else {
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
Ok(TaskHandle::from_raw(ret as u32))
}
}
pub fn task_close(task: TaskHandle) -> Result<()> {
let ret = unsafe { super::arch::syscall1(SYSNR_TASK_CLOSE, task.raw() as usize) };
if ret < 0 { Err(TaskError::from_raw(ret)) } else { Ok(()) }
}
pub fn task_start(task: TaskHandle) -> Result<()> {
let ret = unsafe { super::arch::syscall1(SYSNR_TASK_START, task.raw() as usize) };
if ret < 0 { Err(TaskError::from_raw(ret)) } else { Ok(()) }
}
pub fn task_set_regs(task: TaskHandle, mask: RegMask, regs: &TaskRegs) -> Result<()> {
let ret = unsafe {
super::arch::syscall3(
SYSNR_TASK_SET_REGS,
task.raw() as usize,
mask.bits() as usize,
regs as *const TaskRegs as usize,
)
};
if ret < 0 { Err(TaskError::from_raw(ret)) } else { Ok(()) }
}
pub fn task_get_regs(task: TaskHandle) -> Result<TaskRegs> {
let mut regs = MaybeUninit::<TaskRegs>::uninit();
let ret = unsafe {
super::arch::syscall2(SYSNR_TASK_GET_REGS, task.raw() as usize, regs.as_mut_ptr() as usize)
};
if ret < 0 { Err(TaskError::from_raw(ret)) } else { Ok(unsafe { regs.assume_init() }) }
}
pub fn task_get_status(task: TaskHandle) -> Result<TaskStatus> {
let mut status = MaybeUninit::<TaskStatus>::uninit();
let ret = unsafe {
super::arch::syscall2(
SYSNR_TASK_GET_STATUS,
task.raw() as usize,
status.as_mut_ptr() as usize,
)
};
if ret < 0 { Err(TaskError::from_raw(ret)) } else { Ok(unsafe { status.assume_init() }) }
}
pub fn task_set_policy(task: TaskHandle, param: &SchedParam) -> Result<()> {
let ret = unsafe {
super::arch::syscall2(
SYSNR_TASK_SET_POLICY,
task.raw() as usize,
param as *const SchedParam as usize,
)
};
if ret < 0 { Err(TaskError::from_raw(ret)) } else { Ok(()) }
}