feat: uapi: update spec

This commit is contained in:
Paul Pan 2024-09-03 19:27:37 +08:00
parent 66386aa00b
commit 0ed0720ba8
2 changed files with 43 additions and 22 deletions

View File

@ -1,7 +1,7 @@
use crate::error::SysError; use crate::error::SysError;
use utils::addr::VirtAddr; use utils::addr::VirtAddr;
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, PartialEq)]
pub enum LookupFailure { pub enum LookupFailure {
InvalidRoot, InvalidRoot,
MissingCapability { MissingCapability {
@ -29,32 +29,32 @@ impl From<LookupFailure> for SysError {
} }
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, PartialEq)]
pub struct CapFault { pub struct CapFault {
address: usize, address: usize,
in_receive_phase: bool, in_receive_phase: bool,
lookup_failure: LookupFailure, lookup_failure: LookupFailure,
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, PartialEq)]
pub struct UnknownSyscall { pub struct UnknownSyscall {
fault_ip: VirtAddr, fault_ip: VirtAddr,
syscall: usize, syscall: usize,
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, PartialEq)]
pub struct UserException { pub struct UserException {
fault_ip: VirtAddr, fault_ip: VirtAddr,
number: usize, number: usize,
code: usize, code: usize,
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, PartialEq)]
pub struct VMFault { pub struct VMFault {
ip: VirtAddr, ip: VirtAddr,
} }
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, PartialEq)]
pub enum Fault { pub enum Fault {
Null, Null,
CapFault(CapFault), CapFault(CapFault),

View File

@ -17,10 +17,14 @@ pub enum Syscall {
/* Syscall convention: /* Syscall convention:
* > Call: * > Call:
* > > [a0]: MessageInfo * > > +----------+-------------------------+--------------------+
* > > [a1]: Capability Pointer * > > | [a0] | REG_MESSAGE_INFO | MessageInfo |
* > > [a2..a7]: extra arguments * > > | [a1] | REG_CAP_PTR | Capability Pointer |
* > > length = (a0..a?).len() * > > | [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: * > Reply:
* > TODO: figure out how vanilla seL4 handle 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_MESSAGE_INFO: usize = 0;
pub const REG_CAP_PTR: usize = 1; 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: /* MessageInfo layout:
* > | label | bits | length | * > +---------+--------+--------+--------------+
* > | [63:13] | [12:7] | [6:0] | * > | label | bits | length | transfer_cap |
* > label: Syscall * > | [63:14] | [13:8] | [7:1] | [0] |
* > bits: cap_ptr n_bits * > +---------+--------+--------+--------------+
* > length: args.len() * > label: syscall
* * > bits: cap_ptr n_bits
* > length: args.len()
* > transfer_cap: whether to transfer cap
*/ */
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct MessageInfo(usize); pub struct MessageInfo(usize);
impl MessageInfo { impl MessageInfo {
const LABEL_MASK: usize = MASK!(63 - 13 + 1); const LABEL_MASK: usize = MASK!(63 - Self::LABEL_OFFSET + 1);
const LABEL_OFFSET: usize = 13; const LABEL_OFFSET: usize = 14;
const BITS_MASK: usize = MASK!(6); const BITS_MASK: usize = MASK!(6);
const BITS_OFFSET: usize = 7; const BITS_OFFSET: usize = 8;
const LENGTH_MASK: usize = MASK!(7); 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 label = label.to_usize().unwrap_or(0);
let bits = bits - 1; // stored as n_bits - 1 let bits = bits - 1; // stored as n_bits - 1
let transfer_cap = transfer_cap as usize;
assert!(label <= Self::LABEL_MASK); assert!(label <= Self::LABEL_MASK);
assert!(bits <= Self::BITS_MASK); assert!(bits <= Self::BITS_MASK);
@ -60,7 +75,8 @@ impl MessageInfo {
let info = ((label & Self::LABEL_MASK) << Self::LABEL_OFFSET) let info = ((label & Self::LABEL_MASK) << Self::LABEL_OFFSET)
| ((bits & Self::BITS_MASK) << Self::BITS_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) Self(info)
} }
@ -76,6 +92,10 @@ impl MessageInfo {
(self.0 >> Self::LENGTH_OFFSET) & Self::LENGTH_MASK (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 { pub fn as_usize(&self) -> usize {
self.0 self.0
} }
@ -87,6 +107,7 @@ impl Debug for MessageInfo {
.field("label", &self.label()) .field("label", &self.label())
.field("bits", &self.bits()) .field("bits", &self.bits())
.field("length", &self.length()) .field("length", &self.length())
.field("transfer_cap", &self.transfer_cap())
.finish() .finish()
} }
} }