mirror of
https://github.com/panpaul/tiny_os
synced 2024-09-20 09:45:19 +08:00
feat: adjust Cell granularity for CapEntry
This commit is contained in:
parent
cadfafca12
commit
e6abb50f86
@ -29,44 +29,41 @@ impl RawCap {
|
||||
|
||||
#[derive(Copy, Clone, Default)]
|
||||
pub struct Link {
|
||||
pub prev: Option<NonNull<Cell<CapEntry>>>,
|
||||
pub next: Option<NonNull<Cell<CapEntry>>>,
|
||||
pub prev: Option<NonNull<CapEntry>>,
|
||||
pub next: Option<NonNull<CapEntry>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct CapEntry {
|
||||
pub cap: RawCap,
|
||||
pub link: Link,
|
||||
pub cap: Cell<RawCap>,
|
||||
pub link: Cell<Link>,
|
||||
}
|
||||
|
||||
pub type CapTableEntry = Cell<CapEntry>;
|
||||
|
||||
impl CapEntry {
|
||||
pub fn new(cap: RawCap) -> Self {
|
||||
Self {
|
||||
cap: cap,
|
||||
link: Link::default(),
|
||||
cap: Cell::new(cap),
|
||||
link: Cell::new(Link::default()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(&mut self) {
|
||||
self.cap = RawCap::default();
|
||||
self.link = Link::default();
|
||||
self.cap = Cell::new(RawCap::default());
|
||||
self.link = Cell::new(Link::default());
|
||||
}
|
||||
|
||||
pub fn prev(&self) -> Option<NonNull<Cell<CapEntry>>> {
|
||||
self.link.prev
|
||||
pub fn prev(&self) -> Option<NonNull<CapEntry>> {
|
||||
self.link.get().prev
|
||||
}
|
||||
|
||||
pub fn next(&self) -> Option<NonNull<Cell<CapEntry>>> {
|
||||
self.link.next
|
||||
pub fn next(&self) -> Option<NonNull<CapEntry>> {
|
||||
self.link.get().next
|
||||
}
|
||||
|
||||
pub fn set_prev(&mut self, prev: Option<NonNull<Cell<CapEntry>>>) {
|
||||
self.link.prev = prev;
|
||||
pub fn set_prev(&mut self, prev: Option<NonNull<CapEntry>>) {
|
||||
self.link.get_mut().prev = prev;
|
||||
}
|
||||
|
||||
pub fn set_next(&mut self, next: Option<NonNull<Cell<CapEntry>>>) {
|
||||
self.link.next = next;
|
||||
pub fn set_next(&mut self, next: Option<NonNull<CapEntry>>) {
|
||||
self.link.get_mut().next = next;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
use core::cell::Cell;
|
||||
|
||||
use super::{
|
||||
cap::{CapTableEntry, RawCap},
|
||||
cap::{CapEntry, RawCap},
|
||||
Cap, KernelObject,
|
||||
};
|
||||
use crate::arch::layout::mmap_phys_to_virt;
|
||||
@ -11,7 +9,7 @@ use vspace::addr::{AddressOps, PhysAddr};
|
||||
|
||||
/// CNodeObject is a array of Capabilities (`RawCap`)
|
||||
/// The size of the array is stored in CNodeCap
|
||||
pub type CNodeObject = [CapTableEntry];
|
||||
pub type CNodeObject = [CapEntry];
|
||||
|
||||
impl KernelObject for CNodeObject {
|
||||
const OBJ_TYPE: ObjectType = ObjectType::CNode;
|
||||
@ -48,25 +46,25 @@ impl<'a> CNodeCap<'a> {
|
||||
|
||||
// init memory
|
||||
let cte = super::cap::CapEntry::new(cap);
|
||||
CNodeCap::try_from(&Cell::new(cte))
|
||||
CNodeCap::try_from(&cte)
|
||||
.unwrap()
|
||||
.as_object_mut()
|
||||
.iter_mut()
|
||||
.for_each(|cap| cap.get_mut().init());
|
||||
.for_each(|cap| cap.init());
|
||||
|
||||
cap
|
||||
}
|
||||
|
||||
fn radix(&self) -> usize {
|
||||
(self.cte.get().cap.args[0] >> Self::RADIX_OFFSET) & Self::RADIX_MASK
|
||||
(self.cte.cap.get().args[0] >> Self::RADIX_OFFSET) & Self::RADIX_MASK
|
||||
}
|
||||
|
||||
fn guard_size(&self) -> usize {
|
||||
(self.cte.get().cap.args[0] >> Self::GUARD_SIZE_OFFSET) & Self::GUARD_SIZE_MASK
|
||||
(self.cte.cap.get().args[0] >> Self::GUARD_SIZE_OFFSET) & Self::GUARD_SIZE_MASK
|
||||
}
|
||||
|
||||
fn guard(&self) -> usize {
|
||||
self.cte.get().cap.args[1]
|
||||
self.cte.cap.get().args[1]
|
||||
}
|
||||
|
||||
/// CNodeObject length
|
||||
@ -79,19 +77,19 @@ impl<'a> CNodeCap<'a> {
|
||||
|
||||
fn as_object(&self) -> &CNodeObject {
|
||||
unsafe {
|
||||
let virt = mmap_phys_to_virt(self.cte.get().cap.ptr);
|
||||
let virt = mmap_phys_to_virt(self.cte.cap.get().ptr);
|
||||
core::slice::from_raw_parts(virt.as_const_ptr(), self.length())
|
||||
}
|
||||
}
|
||||
|
||||
fn as_object_mut(&mut self) -> &mut CNodeObject {
|
||||
unsafe {
|
||||
let virt = mmap_phys_to_virt(self.cte.get().cap.ptr);
|
||||
let virt = mmap_phys_to_virt(self.cte.cap.get().ptr);
|
||||
core::slice::from_raw_parts_mut(virt.as_mut_ptr(), self.length())
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_address_bits(&self, cap_ptr: usize, n_bits: usize) -> Result<&CapTableEntry, CapFault> {
|
||||
fn resolve_address_bits(&self, cap_ptr: usize, n_bits: usize) -> Result<&CapEntry, CapFault> {
|
||||
let mut bits_remaining = n_bits;
|
||||
let mut slot = self.cte;
|
||||
|
||||
|
@ -18,7 +18,7 @@ use api::{
|
||||
cap::ObjectType,
|
||||
error::{SysError, SysResult},
|
||||
};
|
||||
use cap::CapTableEntry;
|
||||
use cap::CapEntry;
|
||||
use core::{marker::PhantomData, ptr::NonNull};
|
||||
|
||||
pub mod cap;
|
||||
@ -30,15 +30,15 @@ pub mod untyped;
|
||||
/// 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)
|
||||
pub struct Cap<'a, T: KernelObject + ?Sized> {
|
||||
cte: &'a CapTableEntry,
|
||||
cte: &'a CapEntry,
|
||||
cap_type: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<'a, T: KernelObject + ?Sized> TryFrom<&'a CapTableEntry> for Cap<'a, T> {
|
||||
impl<'a, T: KernelObject + ?Sized> TryFrom<&'a CapEntry> for Cap<'a, T> {
|
||||
type Error = SysError;
|
||||
|
||||
fn try_from(new: &'a CapTableEntry) -> SysResult<Self> {
|
||||
if new.get().cap.cap_type != T::OBJ_TYPE {
|
||||
fn try_from(new: &'a CapEntry) -> SysResult<Self> {
|
||||
if new.cap.get().cap_type != T::OBJ_TYPE {
|
||||
Err(SysError::CapTypeMismatch)
|
||||
} else {
|
||||
Ok(Self {
|
||||
@ -50,22 +50,26 @@ impl<'a, T: KernelObject + ?Sized> TryFrom<&'a CapTableEntry> for Cap<'a, T> {
|
||||
}
|
||||
|
||||
impl<'a, T: KernelObject + ?Sized> Cap<'a, T> {
|
||||
pub fn append(&mut self, new: &mut CapTableEntry) {
|
||||
let next = self.cte.get().next();
|
||||
pub fn append(&mut self, new: &mut CapEntry) {
|
||||
let next = self.cte.next();
|
||||
|
||||
// update new cap's link
|
||||
new.get_mut().set_prev(Some(NonNull::from(self.cte)));
|
||||
new.get_mut().set_next(next);
|
||||
new.set_prev(Some(NonNull::from(self.cte)));
|
||||
new.set_next(next);
|
||||
|
||||
// record new cap's addr
|
||||
let new_addr = Some(NonNull::from(new));
|
||||
|
||||
// update next cap's link.prev
|
||||
next.map(|mut next| unsafe { next.as_mut().get().set_prev(new_addr) });
|
||||
if let Some(mut next) = next {
|
||||
unsafe { next.as_mut().set_prev(new_addr) };
|
||||
}
|
||||
|
||||
// update self's link.next
|
||||
let mut raw = self.cte.get();
|
||||
raw.set_next(new_addr);
|
||||
self.cte.link.update(|mut link| {
|
||||
link.next = new_addr;
|
||||
link
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::cap::{CapEntry, RawCap};
|
||||
use super::cap::RawCap;
|
||||
use super::cnode::{CNodeCap, CNodeObject};
|
||||
use super::null::NullCap;
|
||||
use super::{Cap, KernelObject};
|
||||
@ -43,22 +43,22 @@ impl UntypedCap<'_> {
|
||||
}
|
||||
|
||||
fn free_offset(&self) -> usize {
|
||||
self.cte.get().cap.args[0]
|
||||
self.cte.cap.get().args[0]
|
||||
}
|
||||
|
||||
fn set_free_offset(&mut self, free_offset: usize) {
|
||||
self.cte.update(|mut c| {
|
||||
c.cap.args[0] = free_offset;
|
||||
self.cte.cap.update(|mut c| {
|
||||
c.args[0] = free_offset;
|
||||
c
|
||||
});
|
||||
}
|
||||
|
||||
fn is_device(&self) -> bool {
|
||||
(self.cte.get().cap.args[1] >> 6) & 1 == 1
|
||||
(self.cte.cap.get().args[1] >> 6) & 1 == 1
|
||||
}
|
||||
|
||||
fn block_bits(&self) -> usize {
|
||||
self.cte.get().cap.args[1] & MASK!(6)
|
||||
self.cte.cap.get().args[1] & MASK!(6)
|
||||
}
|
||||
|
||||
fn block_size(&self) -> usize {
|
||||
@ -112,7 +112,7 @@ impl UntypedCap<'_> {
|
||||
|
||||
// Create new capabilities in slot
|
||||
for (i, slot) in slots.iter_mut().enumerate() {
|
||||
let addr = self.cte.get().cap.ptr + start_offset + i * obj_size;
|
||||
let addr = self.cte.cap.get().ptr + start_offset + i * obj_size;
|
||||
let new_cap = match obj_type {
|
||||
ObjectType::Untyped => UntypedCap::mint(0, obj_type.bits(user_obj_bits), self.is_device(), addr),
|
||||
ObjectType::CNode => CNodeCap::mint(user_obj_bits, 0, 0, addr),
|
||||
@ -120,7 +120,7 @@ impl UntypedCap<'_> {
|
||||
_ => return Err(SysError::InvalidArgument),
|
||||
};
|
||||
|
||||
slot.get_mut().cap = new_cap;
|
||||
slot.cap.set(new_cap);
|
||||
self.append(slot);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user