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 utils::addr::VirtAddr;
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum LookupFailure {
InvalidRoot,
MissingCapability {
@ -29,32 +29,32 @@ impl From<LookupFailure> 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),

View File

@ -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
* > +---------+--------+--------+--------------+
* > | 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()
}
}