mirror of
https://github.com/panpaul/tiny_os
synced 2024-09-20 09:45:19 +08:00
feat: uapi: update spec
This commit is contained in:
parent
66386aa00b
commit
0ed0720ba8
@ -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),
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user