diff --git a/Cargo.lock b/Cargo.lock index 986e98c..b86f719 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -252,6 +252,7 @@ version = "0.1.0" dependencies = [ "num-derive", "num-traits", + "utils", ] [[package]] diff --git a/uapi/Cargo.toml b/uapi/Cargo.toml index 4e9f8fb..6c2bc7f 100644 --- a/uapi/Cargo.toml +++ b/uapi/Cargo.toml @@ -4,5 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] +utils = { path = "../lib/utils" } num-traits = { version = "0.2", default-features = false } num-derive = "0.4" diff --git a/uapi/src/lib.rs b/uapi/src/lib.rs index b00bfa1..d9519a5 100644 --- a/uapi/src/lib.rs +++ b/uapi/src/lib.rs @@ -6,4 +6,5 @@ extern crate num_derive; pub mod cap; pub mod error; +pub mod syscall; pub mod vspace; diff --git a/uapi/src/syscall.rs b/uapi/src/syscall.rs new file mode 100644 index 0000000..ff24318 --- /dev/null +++ b/uapi/src/syscall.rs @@ -0,0 +1,71 @@ +use core::fmt::Debug; + +use num_traits::{FromPrimitive, ToPrimitive}; +use utils::MASK; + +use crate::error::SysError; + +#[derive(Clone, Copy, Debug, Eq, PartialEq, FromPrimitive, ToPrimitive)] +pub enum Syscall { + Invalid = 0, +} + +/* in vanilla seL4, MessageInfo layout: + * > | label | caps | extra_caps | length | + * > | [63:12] | [11:9] | [8:7] | [6:0] | + * + * in out implementation, MessageInfo layout: + * > label: Syscall + * > length: args.len() + * + * Syscall convention: + * > Call: + * > > [a0]: MessageInfo + * > > [a1]: Capability Pointer + * > > [a3..a7]: extra arguments + * > > length = (a0..a?).len() + * > Reply: + * > TODO: figure out how vanilla seL4 handle reply + */ + +#[derive(Clone, Copy)] +pub struct MessageInfo(usize); + +impl MessageInfo { + const LABEL_MASK: usize = MASK!(63 - 12 + 1); + + pub fn new(label: Syscall, length: usize) -> Self { + Self((label.to_usize().unwrap_or(0)) << 12 | (length & 0x7f)) + } + + pub fn label(&self) -> Syscall { + Syscall::from_usize((self.0 >> 12) & Self::LABEL_MASK).unwrap_or(Syscall::Invalid) + } + + pub fn length(&self) -> usize { + self.0 & 0x7F + } + + pub fn as_usize(&self) -> usize { + self.0 + } +} + +impl Debug for MessageInfo { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("MessageInfo") + .field("label", &self.label()) + .field("length", &self.length()) + .finish() + } +} + +impl TryFrom for MessageInfo { + type Error = SysError; + + fn try_from(value: usize) -> Result { + let syscall = Syscall::from_usize((value >> 12) & MessageInfo::LABEL_MASK).ok_or(SysError::InvalidArgument)?; + let length = value & 0x7F; + Ok(Self::new(syscall, length)) + } +}