From 0ed0720ba8cae5f1edb7e109acccea99773c252a Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Tue, 3 Sep 2024 19:27:37 +0800 Subject: [PATCH] feat: uapi: update spec --- uapi/src/fault.rs | 12 +++++----- uapi/src/syscall.rs | 53 +++++++++++++++++++++++++++++++-------------- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/uapi/src/fault.rs b/uapi/src/fault.rs index 8173e54..a4a5545 100644 --- a/uapi/src/fault.rs +++ b/uapi/src/fault.rs @@ -1,7 +1,7 @@ use crate::error::SysError; use utils::addr::VirtAddr; -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum LookupFailure { InvalidRoot, MissingCapability { @@ -29,32 +29,32 @@ impl From for SysError { } } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] pub struct CapFault { address: usize, in_receive_phase: bool, lookup_failure: LookupFailure, } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] pub struct UnknownSyscall { fault_ip: VirtAddr, syscall: usize, } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] pub struct UserException { fault_ip: VirtAddr, number: usize, code: usize, } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] pub struct VMFault { ip: VirtAddr, } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum Fault { Null, CapFault(CapFault), diff --git a/uapi/src/syscall.rs b/uapi/src/syscall.rs index 4dfe959..e3d6599 100644 --- a/uapi/src/syscall.rs +++ b/uapi/src/syscall.rs @@ -17,10 +17,14 @@ pub enum Syscall { /* Syscall convention: * > Call: - * > > [a0]: MessageInfo - * > > [a1]: Capability Pointer - * > > [a2..a7]: extra arguments - * > > length = (a0..a?).len() + * > > +----------+-------------------------+--------------------+ + * > > | [a0] | REG_MESSAGE_INFO | MessageInfo | + * > > | [a1] | REG_CAP_PTR | Capability Pointer | + * > > | [a2..a7] | REG_ARG_0..=REG_ARG_MAX | Arguments | + * > > | buffer | REG_ARG_MAX+1.. | Arguments | + * > > +----------+-------------------------+--------------------+ + * > > length = (a0..).len(), extra arguments are stored on ipc buffer + * > > if info.transfer_cap { Arguments[-2] = cap_ptr; Arguments[-1] = n_bits; } * > * > Reply: * > TODO: figure out how vanilla seL4 handle reply @@ -28,31 +32,42 @@ pub enum Syscall { pub const REG_MESSAGE_INFO: usize = 0; pub const REG_CAP_PTR: usize = 1; +pub const REG_ARG_0: usize = 2; +pub const REG_ARG_MAX: usize = 7; + +pub const LEN_ARG_OFFSET_CPTR: usize = 2; +pub const LEN_ARG_OFFSET_BITS: usize = 1; /* MessageInfo layout: - * > | label | bits | length | - * > | [63:13] | [12:7] | [6:0] | - * > label: Syscall - * > bits: cap_ptr n_bits - * > length: args.len() - * + * > +---------+--------+--------+--------------+ + * > | label | bits | length | transfer_cap | + * > | [63:14] | [13:8] | [7:1] | [0] | + * > +---------+--------+--------+--------------+ + * > label: syscall + * > bits: cap_ptr n_bits + * > length: args.len() + * > transfer_cap: whether to transfer cap */ #[derive(Clone, Copy)] pub struct MessageInfo(usize); impl MessageInfo { - const LABEL_MASK: usize = MASK!(63 - 13 + 1); - const LABEL_OFFSET: usize = 13; + const LABEL_MASK: usize = MASK!(63 - Self::LABEL_OFFSET + 1); + const LABEL_OFFSET: usize = 14; const BITS_MASK: usize = MASK!(6); - const BITS_OFFSET: usize = 7; + const BITS_OFFSET: usize = 8; const LENGTH_MASK: usize = MASK!(7); - const LENGTH_OFFSET: usize = 0; + const LENGTH_OFFSET: usize = 1; - pub fn new(label: Syscall, bits: usize, length: usize) -> Self { + const TRANSFER_CAP_MASK: usize = MASK!(1); + const TRANSFER_CAP_OFFSET: usize = 0; + + pub fn new(label: Syscall, bits: usize, length: usize, transfer_cap: bool) -> Self { let label = label.to_usize().unwrap_or(0); let bits = bits - 1; // stored as n_bits - 1 + let transfer_cap = transfer_cap as usize; assert!(label <= Self::LABEL_MASK); assert!(bits <= Self::BITS_MASK); @@ -60,7 +75,8 @@ impl MessageInfo { let info = ((label & Self::LABEL_MASK) << Self::LABEL_OFFSET) | ((bits & Self::BITS_MASK) << Self::BITS_OFFSET) - | ((length & Self::LENGTH_MASK) << Self::LENGTH_OFFSET); + | ((length & Self::LENGTH_MASK) << Self::LENGTH_OFFSET) + | ((transfer_cap & Self::TRANSFER_CAP_MASK) << Self::TRANSFER_CAP_OFFSET); Self(info) } @@ -76,6 +92,10 @@ impl MessageInfo { (self.0 >> Self::LENGTH_OFFSET) & Self::LENGTH_MASK } + pub fn transfer_cap(&self) -> bool { + (self.0 >> Self::TRANSFER_CAP_OFFSET) & Self::TRANSFER_CAP_MASK != 0 + } + pub fn as_usize(&self) -> usize { self.0 } @@ -87,6 +107,7 @@ impl Debug for MessageInfo { .field("label", &self.label()) .field("bits", &self.bits()) .field("length", &self.length()) + .field("transfer_cap", &self.transfer_cap()) .finish() } }