mirror of
https://github.com/panpaul/tiny_os
synced 2024-09-20 09:45:19 +08:00
feat: refactor cap
This commit is contained in:
parent
c371fd543f
commit
5c1e73a4ee
28
api/src/failure.rs
Normal file
28
api/src/failure.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use crate::cap::ObjectType;
|
||||||
|
|
||||||
|
pub enum Fault {
|
||||||
|
Ok,
|
||||||
|
CapFault(CapFault),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum CapFault {
|
||||||
|
// vallina
|
||||||
|
InvalidRoot,
|
||||||
|
MissingCapability {
|
||||||
|
bits_left: usize,
|
||||||
|
},
|
||||||
|
DepthMismatch {
|
||||||
|
bits_found: usize,
|
||||||
|
bits_left: usize,
|
||||||
|
},
|
||||||
|
GuardMismatch {
|
||||||
|
guard_found: usize,
|
||||||
|
bits_left: usize,
|
||||||
|
guard_size: usize,
|
||||||
|
},
|
||||||
|
// additional
|
||||||
|
TypeMismatch {
|
||||||
|
expected: ObjectType,
|
||||||
|
found: ObjectType,
|
||||||
|
},
|
||||||
|
}
|
@ -4,3 +4,4 @@
|
|||||||
extern crate num_derive;
|
extern crate num_derive;
|
||||||
|
|
||||||
pub mod cap;
|
pub mod cap;
|
||||||
|
pub mod failure;
|
||||||
|
@ -1,23 +1,26 @@
|
|||||||
use api::cap::ObjectType;
|
use api::cap::ObjectType;
|
||||||
|
use vspace::addr::PhysAddr;
|
||||||
|
|
||||||
/// RawCap is the specific implementation of capability which stores in CNode
|
/// RawCap is the specific implementation of capability which stores in CNode
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct RawCap {
|
pub struct RawCap {
|
||||||
/// args: in vanilla seL4 implementation, a cap use two 64-bit words to store all information,
|
/// args: in vanilla seL4 implementation, a cap use two 64-bit words to store all information,
|
||||||
/// but we'll waste some space rather than using bitfield to simplify the implementation
|
/// but we'll waste some space rather than using bitfield to simplify the implementation
|
||||||
args: [usize; 2],
|
pub args: [usize; 2],
|
||||||
|
/// ptr: vanilla seL4 stores the pointer with either higher bits or lower bits cut off,
|
||||||
|
/// which limits the address space. Use an independent field to store the pointer.
|
||||||
|
/// Kernel will not manage memory, userspace should pass PhysAddr to kernel
|
||||||
|
pub ptr: PhysAddr,
|
||||||
/// cap_type: every capability links to one specific object
|
/// cap_type: every capability links to one specific object
|
||||||
cap_type: ObjectType,
|
pub cap_type: ObjectType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RawCap {
|
impl RawCap {
|
||||||
pub fn new(arg0: usize, arg1: usize, cap_type: ObjectType) -> Self {
|
pub fn new(arg0: usize, arg1: usize, ptr: PhysAddr, cap_type: ObjectType) -> Self {
|
||||||
Self {
|
Self {
|
||||||
args: [arg0, arg1],
|
args: [arg0, arg1],
|
||||||
|
ptr,
|
||||||
cap_type,
|
cap_type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cap_type(&self) -> ObjectType {
|
|
||||||
self.cap_type
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,9 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use api::cap::ObjectType;
|
use api::{cap::ObjectType, failure::CapFault};
|
||||||
use cap::RawCap;
|
use cap::RawCap;
|
||||||
use core::cell::Cell;
|
use core::{cell::Cell, marker::PhantomData};
|
||||||
use core::marker::PhantomData;
|
|
||||||
|
|
||||||
pub mod cap;
|
pub mod cap;
|
||||||
pub mod null;
|
pub mod null;
|
||||||
@ -25,11 +24,29 @@ pub mod null;
|
|||||||
/// Cap is the high-level wrapper of RawCap, it's a typed reference to RawCap (which is untyped in Rust)
|
/// Cap is the high-level wrapper of RawCap, it's a typed reference to RawCap (which is untyped in Rust)
|
||||||
/// For the typed objects, we should bound it with an empty traits `KernelObject`
|
/// For the typed objects, we should bound it with an empty traits `KernelObject`
|
||||||
/// And for those objects, at least implement `mint` method and `decodeInvocation` (not enforcing in `KernelObject` for complexity)
|
/// And for those objects, at least implement `mint` method and `decodeInvocation` (not enforcing in `KernelObject` for complexity)
|
||||||
pub struct Cap<'a, T: KernelObject> {
|
pub struct Cap<'a, T: KernelObject + ?Sized> {
|
||||||
cap: &'a Cell<RawCap>,
|
cap: &'a Cell<RawCap>, // use Cell to avoid lifetime issues
|
||||||
cap_type: PhantomData<T>,
|
cap_type: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, T: KernelObject + ?Sized> TryFrom<&'a Cell<RawCap>> for Cap<'a, T> {
|
||||||
|
type Error = CapFault;
|
||||||
|
|
||||||
|
fn try_from(new: &'a Cell<RawCap>) -> Result<Self, Self::Error> {
|
||||||
|
if new.get().cap_type != T::OBJ_TYPE {
|
||||||
|
Err(CapFault::TypeMismatch {
|
||||||
|
expected: T::OBJ_TYPE,
|
||||||
|
found: new.get().cap_type,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Ok(Self {
|
||||||
|
cap: new,
|
||||||
|
cap_type: PhantomData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// KernelObject is the base trait for all kernel objects
|
/// KernelObject is the base trait for all kernel objects
|
||||||
pub trait KernelObject {
|
pub trait KernelObject {
|
||||||
// this should be optimized by compiler?
|
// this should be optimized by compiler?
|
||||||
|
@ -1,27 +1,17 @@
|
|||||||
use super::cap::RawCap;
|
use super::cap::RawCap;
|
||||||
use super::{Cap, KernelObject};
|
use super::{Cap, KernelObject};
|
||||||
use api::cap::ObjectType;
|
use api::cap::ObjectType;
|
||||||
use core::marker::PhantomData;
|
use vspace::addr::PhysAddr;
|
||||||
|
|
||||||
/// NullObject is used as empty (capability) slot
|
/// NullObject is used as empty (capability) slot
|
||||||
pub struct NullObject {}
|
pub struct NullObject {}
|
||||||
pub type NullCap<'a> = Cap<'a, NullObject>;
|
|
||||||
impl KernelObject for NullObject {
|
impl KernelObject for NullObject {
|
||||||
const OBJ_TYPE: ObjectType = ObjectType::Null;
|
const OBJ_TYPE: ObjectType = ObjectType::Null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type NullCap<'a> = Cap<'a, NullObject>;
|
||||||
impl<'a> NullCap<'a> {
|
impl<'a> NullCap<'a> {
|
||||||
pub fn mint() -> RawCap {
|
pub fn mint() -> RawCap {
|
||||||
let cap = RawCap::new(0, 0, ObjectType::Null);
|
RawCap::new(0, 0, PhysAddr(0), ObjectType::Null)
|
||||||
cap
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn retype<T: KernelObject>(self, new: RawCap) -> Cap<'a, T> {
|
|
||||||
assert!(T::OBJ_TYPE == new.cap_type());
|
|
||||||
self.cap.set(new);
|
|
||||||
Cap {
|
|
||||||
cap: self.cap,
|
|
||||||
cap_type: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user