use core::mem::MaybeUninit;
use bitflags::bitflags;
use num_enum::{FromPrimitive, IntoPrimitive};
use super::{convert_codes_to_result, justval, Syscall};
use crate::{
arch::syscall::raw_syscall,
object::{ObjID, Protections},
};
#[derive(
Debug,
Copy,
Clone,
PartialEq,
PartialOrd,
Ord,
Eq,
IntoPrimitive,
FromPrimitive,
thiserror::Error,
)]
#[repr(u64)]
pub enum ObjectMapError {
#[num_enum(default)]
#[error("unknown error")]
Unknown = 0,
#[error("object not found")]
ObjectNotFound = 1,
#[error("invalid slot")]
InvalidSlot = 2,
#[error("invalid protections")]
InvalidProtections = 3,
#[error("invalid argument")]
InvalidArgument = 4,
}
impl core::error::Error for ObjectMapError {}
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct MapFlags: u32 {
}
}
pub fn sys_object_map(
handle: Option<ObjID>,
id: ObjID,
slot: usize,
prot: Protections,
flags: MapFlags,
) -> Result<usize, ObjectMapError> {
let (hi, lo) = id.split();
let args = [
hi,
lo,
slot as u64,
prot.bits() as u64,
flags.bits() as u64,
&handle as *const Option<ObjID> as usize as u64,
];
let (code, val) = unsafe { raw_syscall(Syscall::ObjectMap, &args) };
convert_codes_to_result(code, val, |c, _| c != 0, |_, v| v as usize, justval)
}
#[derive(
Debug,
Copy,
Clone,
PartialEq,
PartialOrd,
Ord,
Eq,
IntoPrimitive,
FromPrimitive,
thiserror::Error,
)]
#[repr(u64)]
pub enum ObjectUnmapError {
#[num_enum(default)]
#[error("unknown error")]
Unknown = 0,
#[error("invalid slot")]
InvalidSlot = 1,
#[error("invalid argument")]
InvalidArgument = 2,
}
impl core::error::Error for ObjectUnmapError {}
bitflags! {
pub struct UnmapFlags: u32 {
}
}
pub fn sys_object_unmap(
handle: Option<ObjID>,
slot: usize,
flags: UnmapFlags,
) -> Result<(), ObjectUnmapError> {
let (hi, lo) = handle.unwrap_or_else(|| 0.into()).split();
let args = [hi, lo, slot as u64, flags.bits() as u64];
let (code, val) = unsafe { raw_syscall(Syscall::ObjectUnmap, &args) };
convert_codes_to_result(code, val, |c, _| c != 0, |_, _| (), justval)
}
#[derive(
Debug,
Copy,
Clone,
PartialEq,
PartialOrd,
Ord,
Eq,
FromPrimitive,
IntoPrimitive,
thiserror::Error,
)]
#[repr(u64)]
pub enum ObjectReadMapError {
#[num_enum(default)]
#[error("unknown error")]
Unknown = 0,
#[error("invalid slot")]
InvalidSlot = 1,
#[error("invalid argument")]
InvalidArgument = 2,
}
impl core::error::Error for ObjectReadMapError {}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[repr(C)]
pub struct MapInfo {
pub id: ObjID,
pub prot: Protections,
pub slot: usize,
pub flags: MapFlags,
}
pub fn sys_object_read_map(
handle: Option<ObjID>,
slot: usize,
) -> Result<MapInfo, ObjectReadMapError> {
let (hi, lo) = handle.unwrap_or_else(|| 0.into()).split();
let mut map_info = MaybeUninit::<MapInfo>::uninit();
let args = [
hi,
lo,
slot as u64,
&mut map_info as *mut MaybeUninit<MapInfo> as usize as u64,
];
let (code, val) = unsafe { raw_syscall(Syscall::ObjectReadMap, &args) };
convert_codes_to_result(
code,
val,
|c, _| c != 0,
|_, _| unsafe { map_info.assume_init() },
justval,
)
}