use ax_task::current;
use crate::{
StarryError, StarryResult,
task::{AsThread, current_pid_view},
};
#[inline(never)]
pub fn sys_getpid() -> StarryResult<isize> {
let curr = current();
let thr = curr.as_thread();
current_pid_view()
.visible_process_number(&thr.proc_data.identity())
.map(|pid| pid.get() as isize)
.ok_or(StarryError::NoSuchProcess)
}
pub fn sys_getppid() -> StarryResult<isize> {
let curr = current();
let thr = curr.as_thread();
let parent = thr
.proc_data
.proc
.parent()
.ok_or(StarryError::NoSuchProcess)?;
Ok(current_pid_view()
.visible_process_number(&parent.identity())
.map_or(0, |pid| pid.get() as isize))
}
pub fn sys_gettid() -> StarryResult<isize> {
Ok(current().as_thread().user_tid().get() as _)
}
pub fn sys_getcpu(cpu: *mut u32, node: *mut u32, _tcache: usize) -> StarryResult<isize> {
use ax_runtime::hal::percpu::this_cpu_id;
use starry_vm::VmMutPtr;
if !cpu.is_null() {
cpu.vm_write(this_cpu_id() as u32)?;
}
if !node.is_null() {
node.vm_write(0)?;
}
Ok(0)
}
#[cfg(target_arch = "x86_64")]
#[derive(Debug, Eq, PartialEq, num_enum::TryFromPrimitive)]
#[repr(i32)]
enum ArchPrctlCode {
SetGs = 0x1001,
SetFs = 0x1002,
GetFs = 0x1003,
GetGs = 0x1004,
GetCpuid = 0x1011,
SetCpuid = 0x1012,
}
pub fn sys_set_tid_address(clear_child_tid: usize) -> StarryResult<isize> {
let curr = current();
let thr = curr.as_thread();
thr.set_clear_child_tid(clear_child_tid);
Ok(thr.user_tid().get() as isize)
}
#[cfg(target_arch = "x86_64")]
pub fn sys_arch_prctl(
uctx: &mut ax_runtime::hal::cpu::uspace::UserContext,
code: i32,
addr: usize,
) -> StarryResult<isize> {
use starry_vm::VmMutPtr;
let code = ArchPrctlCode::try_from(code).map_err(|_| StarryError::InvalidInput)?;
debug!("sys_arch_prctl: code = {code:?}, addr = {addr:#x}");
match code {
ArchPrctlCode::GetFs => {
(addr as *mut usize).vm_write(uctx.tls())?;
Ok(0)
}
ArchPrctlCode::SetFs => {
uctx.set_tls(addr);
Ok(0)
}
ArchPrctlCode::GetGs => {
(addr as *mut usize).vm_write(uctx.gs_base as _)?;
Ok(0)
}
ArchPrctlCode::SetGs => {
uctx.gs_base = addr as _;
Ok(0)
}
ArchPrctlCode::GetCpuid => Ok(0),
ArchPrctlCode::SetCpuid => Err(crate::StarryError::NoSuchDevice),
}
}
#[cfg(test)]
pub(crate) fn thread_arch_prctl_code_rules_hold_for_test() -> bool {
#[cfg(target_arch = "x86_64")]
{
assert!(ArchPrctlCode::SetGs as i32 == 0x1001);
assert!(ArchPrctlCode::SetFs as i32 == 0x1002);
assert!(ArchPrctlCode::GetFs as i32 == 0x1003);
assert!(ArchPrctlCode::GetGs as i32 == 0x1004);
assert!(ArchPrctlCode::GetCpuid as i32 == 0x1011);
assert!(ArchPrctlCode::SetCpuid as i32 == 0x1012);
use num_enum::TryFromPrimitive;
assert!(ArchPrctlCode::try_from_primitive(0x1001).is_ok());
assert!(ArchPrctlCode::try_from_primitive(0x1002).is_ok());
assert!(ArchPrctlCode::try_from_primitive(0xFFFF).is_err());
}
true
}