mirror of
https://github.com/panpaul/tiny_os
synced 2024-09-20 09:45:19 +08:00
feat: kernel/objects: drop mdb link
This commit is contained in:
parent
3a7517f8fc
commit
d2a4b4899d
@ -2,6 +2,7 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
// Features
|
// Features
|
||||||
|
#![feature(cell_update)]
|
||||||
#![feature(concat_idents)]
|
#![feature(concat_idents)]
|
||||||
#![feature(iter_array_chunks)]
|
#![feature(iter_array_chunks)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
use crate::objects::*;
|
use crate::objects::*;
|
||||||
use core::fmt::Debug;
|
use core::{cell::Cell, fmt::Debug};
|
||||||
use uapi::cap::ObjectType;
|
use uapi::cap::ObjectType;
|
||||||
use utils::addr::PhysAddr;
|
use utils::addr::PhysAddr;
|
||||||
use utils::{
|
|
||||||
linked_list::{Link, LinkHelper},
|
|
||||||
LinkHelperImpl,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// RawCap is the specific implementation of capability which stores in CNode
|
/// RawCap is the specific implementation of capability which stores in CNode
|
||||||
#[derive(Copy, Clone, Default, PartialEq, Eq)]
|
#[derive(Copy, Clone, Default, PartialEq, Eq)]
|
||||||
@ -30,46 +26,22 @@ impl RawCap {
|
|||||||
cap_type,
|
cap_type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// modify the capability
|
|
||||||
/// # Safety
|
|
||||||
/// This function breaks the safety rules of Rust, race condition may occur
|
|
||||||
pub unsafe fn update<F>(&self, f: F) -> &Self
|
|
||||||
where F: FnOnce(&mut Self) {
|
|
||||||
#[allow(invalid_reference_casting)]
|
|
||||||
f(unsafe { &mut *(self as *const _ as *mut Self) });
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const CAP_ENTRY_LINK_ID: usize = 1;
|
pub const CAP_ENTRY_LINK_ID: usize = 1;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct CapEntry {
|
pub struct CapEntry {
|
||||||
pub cap: RawCap,
|
pub cap: Cell<RawCap>,
|
||||||
pub link: Link<Self, CAP_ENTRY_LINK_ID>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LinkHelperImpl!(CapEntry { link } => CAP_ENTRY_LINK_ID);
|
|
||||||
|
|
||||||
impl CapEntry {
|
impl CapEntry {
|
||||||
pub fn new(cap: RawCap) -> Self {
|
pub fn new(cap: RawCap) -> Self {
|
||||||
Self {
|
Self { cap: Cell::new(cap) }
|
||||||
cap,
|
|
||||||
link: Link::default(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(&mut self) {
|
pub fn init(&mut self) {
|
||||||
self.cap = NullCap::mint();
|
self.cap.replace(NullCap::mint());
|
||||||
self.link = Link::default();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Clone for CapEntry {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
let mut cte = Self::new(self.cap);
|
|
||||||
cte.link = self.link.clone();
|
|
||||||
cte
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,9 +53,10 @@ impl From<RawCap> for CapEntry {
|
|||||||
|
|
||||||
impl Debug for CapEntry {
|
impl Debug for CapEntry {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
let cap_type = self.cap.cap_type;
|
let cap_type = self.cap.get().cap_type;
|
||||||
match cap_type {
|
match cap_type {
|
||||||
ObjectType::CNode => write!(f, "{:?}", CNodeCap::try_from(self)),
|
ObjectType::CNode => write!(f, "{:?}", CNodeCap::try_from(self)),
|
||||||
|
ObjectType::Endpoint => write!(f, "{:?}", EndpointCap::try_from(self)),
|
||||||
ObjectType::Frame => write!(f, "{:?}", FrameCap::try_from(self)),
|
ObjectType::Frame => write!(f, "{:?}", FrameCap::try_from(self)),
|
||||||
ObjectType::Null => write!(f, "{:?}", NullCap::try_from(self)),
|
ObjectType::Null => write!(f, "{:?}", NullCap::try_from(self)),
|
||||||
ObjectType::Table => write!(f, "{:?}", TableCap::try_from(self)),
|
ObjectType::Table => write!(f, "{:?}", TableCap::try_from(self)),
|
||||||
|
@ -56,15 +56,15 @@ impl<'a> CNodeCap<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn radix_bits(&self) -> usize {
|
fn radix_bits(&self) -> usize {
|
||||||
(self.cte.cap.args[0] >> Self::RADIX_OFFSET) & Self::RADIX_MASK
|
(self.cap().get().args[0] >> Self::RADIX_OFFSET) & Self::RADIX_MASK
|
||||||
}
|
}
|
||||||
|
|
||||||
fn guard_bits(&self) -> usize {
|
fn guard_bits(&self) -> usize {
|
||||||
(self.cte.cap.args[0] >> Self::GUARD_SIZE_OFFSET) & Self::GUARD_SIZE_MASK
|
(self.cap().get().args[0] >> Self::GUARD_SIZE_OFFSET) & Self::GUARD_SIZE_MASK
|
||||||
}
|
}
|
||||||
|
|
||||||
fn guard(&self) -> usize {
|
fn guard(&self) -> usize {
|
||||||
self.cte.cap.args[1]
|
self.cap().get().args[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CNodeObject length
|
/// CNodeObject length
|
||||||
@ -77,14 +77,14 @@ impl<'a> CNodeCap<'a> {
|
|||||||
|
|
||||||
pub fn as_object(&self) -> &CNodeObject {
|
pub fn as_object(&self) -> &CNodeObject {
|
||||||
unsafe {
|
unsafe {
|
||||||
let virt = mmap_phys_to_virt(self.cte.cap.ptr);
|
let virt = mmap_phys_to_virt(self.cap().get().ptr);
|
||||||
core::slice::from_raw_parts(virt.as_const_ptr(), self.length())
|
core::slice::from_raw_parts(virt.as_const_ptr(), self.length())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_object_mut(&mut self) -> &mut CNodeObject {
|
pub fn as_object_mut(&mut self) -> &mut CNodeObject {
|
||||||
unsafe {
|
unsafe {
|
||||||
let virt = mmap_phys_to_virt(self.cte.cap.ptr);
|
let virt = mmap_phys_to_virt(self.cap().get().ptr);
|
||||||
core::slice::from_raw_parts_mut(virt.as_mut_ptr(), self.length())
|
core::slice::from_raw_parts_mut(virt.as_mut_ptr(), self.length())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,7 +142,7 @@ impl Debug for CNodeCap<'_> {
|
|||||||
.field("guard_bits", &self.guard_bits())
|
.field("guard_bits", &self.guard_bits())
|
||||||
.field("guard", &self.guard())
|
.field("guard", &self.guard())
|
||||||
.field("length", &self.length())
|
.field("length", &self.length())
|
||||||
.field("ptr", &self.cte.cap.ptr)
|
.field("ptr", &self.cap().get().ptr)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,18 +175,17 @@ mod tests {
|
|||||||
cnode1.as_object_mut()[6] = cte2.clone();
|
cnode1.as_object_mut()[6] = cte2.clone();
|
||||||
cnode2.as_object_mut()[1] = cte3.clone();
|
cnode2.as_object_mut()[1] = cte3.clone();
|
||||||
cnode3.as_object_mut()[2] = NullCap::mint().into();
|
cnode3.as_object_mut()[2] = NullCap::mint().into();
|
||||||
unsafe {
|
cnode3.as_object_mut()[2].cap.update(|mut cap| {
|
||||||
cnode3.as_object_mut()[2].cap.update(|cap| {
|
|
||||||
cap.args[0] = 0xdeadbeef;
|
cap.args[0] = 0xdeadbeef;
|
||||||
cap.args[1] = 0xaa55aa55;
|
cap.args[1] = 0xaa55aa55;
|
||||||
|
cap
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// cte2.clone() cte3.clone() should not modify cte itself
|
// cte2.clone() cte3.clone() should not modify cte itself
|
||||||
info!("Testing whether RawCap and Cap held the same cap");
|
info!("Testing whether RawCap and Cap held the same cap");
|
||||||
assert!(cnode2.cte.cap == cte2.cap);
|
assert!(cnode2.cap().get() == cte2.cap.get());
|
||||||
assert!(cnode3.cte.cap == cte3.cap);
|
assert!(cnode3.cap().get() == cte3.cap.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
let root = cnode1;
|
let root = cnode1;
|
||||||
@ -231,8 +230,8 @@ mod tests {
|
|||||||
// * target length = 21
|
// * target length = 21
|
||||||
info!("Testing resolve to target");
|
info!("Testing resolve to target");
|
||||||
let target = root.resolve_address_bits(0x12cc6a, 21).unwrap();
|
let target = root.resolve_address_bits(0x12cc6a, 21).unwrap();
|
||||||
assert!(target.cap.args[0] == 0xdeadbeef);
|
assert!(target.cap.get().args[0] == 0xdeadbeef);
|
||||||
assert!(target.cap.args[1] == 0xaa55aa55);
|
assert!(target.cap.get().args[1] == 0xaa55aa55);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{objects::*, plat::trap::TrapContextOps};
|
use crate::{objects::*, plat::trap::TrapContextOps};
|
||||||
use core::cmp::min;
|
use core::{cmp::min, fmt::Debug};
|
||||||
use tcb::{ThreadState, EP_QUEUE_LINK_ID};
|
use tcb::{ThreadState, EP_QUEUE_LINK_ID};
|
||||||
use uapi::{cap::ObjectType, fault::Fault, syscall::*};
|
use uapi::{cap::ObjectType, fault::Fault, syscall::*};
|
||||||
use utils::{addr::*, array::*, linked_list::Link};
|
use utils::{addr::*, array::*, linked_list::Link};
|
||||||
@ -26,7 +26,7 @@ impl KernelObject for EndpointObject {
|
|||||||
* > args[0]: | cap_tag | can_grant_reply | can_grant | can_recv | can_send | base_ptr |
|
* > args[0]: | cap_tag | can_grant_reply | can_grant | can_recv | can_send | base_ptr |
|
||||||
* > | [63:59] | [58:58] | [57:57] | [56:56] | [55:55] | [54:0] |
|
* > | [63:59] | [58:58] | [57:57] | [56:56] | [55:55] | [54:0] |
|
||||||
* > args[1]: | badge |
|
* > args[1]: | badge |
|
||||||
* > | [63::0] |
|
* > | [63:0] |
|
||||||
*
|
*
|
||||||
* in our implementation, EndpointCap layout:
|
* in our implementation, EndpointCap layout:
|
||||||
* > args[0]: badge
|
* > args[0]: badge
|
||||||
@ -43,15 +43,15 @@ impl<'a> EndpointCap<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_send(&self) -> bool {
|
pub fn can_send(&self) -> bool {
|
||||||
self.cte.cap.args[0] & 0x2 != 0
|
self.cap().get().args[0] & 0x2 != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_recv(&self) -> bool {
|
pub fn can_recv(&self) -> bool {
|
||||||
self.cte.cap.args[0] & 0x1 != 0
|
self.cap().get().args[0] & 0x1 != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn badge(&self) -> usize {
|
pub fn badge(&self) -> usize {
|
||||||
self.cte.cap.args[1]
|
self.cap().get().args[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn state(&self) -> EndpointState {
|
pub fn state(&self) -> EndpointState {
|
||||||
@ -130,6 +130,18 @@ impl<'a> EndpointCap<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for EndpointCap<'_> {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
f.debug_struct("EndpointCap")
|
||||||
|
.field("ptr", &self.cap().get().ptr)
|
||||||
|
.field("badge", &self.badge())
|
||||||
|
.field("can_send", &self.can_send())
|
||||||
|
.field("can_recv", &self.can_recv())
|
||||||
|
.field("state", &self.state())
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn copy_message(send: &mut TcbObject, send_msg: MessageInfo, recv: &mut TcbObject, recv_msg: MessageInfo) -> SysResult<()> {
|
fn copy_message(send: &mut TcbObject, send_msg: MessageInfo, recv: &mut TcbObject, recv_msg: MessageInfo) -> SysResult<()> {
|
||||||
let send_len = send_msg.length() - if send_msg.transfer_cap() { 2 } else { 0 };
|
let send_len = send_msg.length() - if send_msg.transfer_cap() { 2 } else { 0 };
|
||||||
let recv_len = recv_msg.length() - if recv_msg.transfer_cap() { 2 } else { 0 };
|
let recv_len = recv_msg.length() - if recv_msg.transfer_cap() { 2 } else { 0 };
|
||||||
@ -184,9 +196,8 @@ fn transfer_cap(send: &mut TcbObject, send_msg: MessageInfo, recv: &mut TcbObjec
|
|||||||
let recv_cap = recv_cspace.resolve_address_bits(recv_cptr, recv_bits)?;
|
let recv_cap = recv_cspace.resolve_address_bits(recv_cptr, recv_bits)?;
|
||||||
|
|
||||||
let dest = NullCap::try_from(recv_cap)?;
|
let dest = NullCap::try_from(recv_cap)?;
|
||||||
dest.override_cap(send_cap.cap);
|
dest.override_cap(send_cap.cap.get());
|
||||||
|
send_cap.cap.replace(NullCap::mint());
|
||||||
unsafe { send_cap.cap.update(|cap| *cap = NullCap::mint()) };
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -64,56 +64,54 @@ impl<'a> FrameCap<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn attr(&self) -> MapAttr {
|
pub fn attr(&self) -> MapAttr {
|
||||||
let bits = (self.cte.cap.args[0] >> Self::VM_RIGHT_OFFSET) & Self::VM_RIGHT_MASK;
|
let bits = (self.cap().get().args[0] >> Self::VM_RIGHT_OFFSET) & Self::VM_RIGHT_MASK;
|
||||||
MapAttr::from_bits_truncate(bits)
|
MapAttr::from_bits_truncate(bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_device(&self) -> bool {
|
pub fn is_device(&self) -> bool {
|
||||||
let bits = (self.cte.cap.args[0] >> Self::IS_DEVICE_OFFSET) & Self::IS_DEVICE_MASK;
|
let bits = (self.cap().get().args[0] >> Self::IS_DEVICE_OFFSET) & Self::IS_DEVICE_MASK;
|
||||||
bits != 0
|
bits != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn size(&self) -> usize {
|
pub fn size(&self) -> usize {
|
||||||
let bits = (self.cte.cap.args[0] >> Self::FRAME_SIZE_OFFSET) & Self::FRAME_SIZE_MASK;
|
let bits = (self.cap().get().args[0] >> Self::FRAME_SIZE_OFFSET) & Self::FRAME_SIZE_MASK;
|
||||||
1 << bits
|
1 << bits
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mapped_asid(&self) -> usize {
|
pub fn mapped_asid(&self) -> usize {
|
||||||
(self.cte.cap.args[0] >> Self::ASID_OFFSET) & Self::ASID_MASK
|
(self.cap().get().args[0] >> Self::ASID_OFFSET) & Self::ASID_MASK
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_mapped_asid(&self, asid: usize) {
|
pub fn set_mapped_asid(&self, asid: usize) {
|
||||||
unsafe {
|
self.cap().update(|mut cap| {
|
||||||
self.cte.cap.update(|cap| {
|
|
||||||
let asid = (asid & Self::ASID_MASK) << Self::ASID_OFFSET;
|
let asid = (asid & Self::ASID_MASK) << Self::ASID_OFFSET;
|
||||||
let arg0 = cap.args[0] & !(Self::ASID_MASK << Self::ASID_OFFSET);
|
let arg0 = cap.args[0] & !(Self::ASID_MASK << Self::ASID_OFFSET);
|
||||||
cap.args[0] = arg0 | asid;
|
cap.args[0] = arg0 | asid;
|
||||||
})
|
cap
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mapped_vaddr(&self) -> VirtAddr {
|
pub fn mapped_vaddr(&self) -> VirtAddr {
|
||||||
VirtAddr(self.cte.cap.args[1])
|
VirtAddr(self.cap().get().args[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_mapped_vaddr(&self, vaddr: VirtAddr) {
|
pub fn set_mapped_vaddr(&self, vaddr: VirtAddr) {
|
||||||
unsafe {
|
self.cap().update(|mut cap| {
|
||||||
self.cte.cap.update(|cap| {
|
|
||||||
cap.args[1] = vaddr.0;
|
cap.args[1] = vaddr.0;
|
||||||
})
|
cap
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_object(&self) -> &FrameObject {
|
pub fn as_object(&self) -> &FrameObject {
|
||||||
unsafe {
|
unsafe {
|
||||||
let virt = mmap_phys_to_virt(self.cte.cap.ptr);
|
let virt = mmap_phys_to_virt(self.cap().get().ptr);
|
||||||
core::slice::from_raw_parts(virt.as_const_ptr(), self.size())
|
core::slice::from_raw_parts(virt.as_const_ptr(), self.size())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_object_mut(&mut self) -> &mut FrameObject {
|
pub fn as_object_mut(&mut self) -> &mut FrameObject {
|
||||||
unsafe {
|
unsafe {
|
||||||
let virt = mmap_phys_to_virt(self.cte.cap.ptr);
|
let virt = mmap_phys_to_virt(self.cap().get().ptr);
|
||||||
core::slice::from_raw_parts_mut(virt.as_mut_ptr(), self.size())
|
core::slice::from_raw_parts_mut(virt.as_mut_ptr(), self.size())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,7 +126,7 @@ impl<'a> FrameCap<'a> {
|
|||||||
pub fn map<T: TableLevel>(&self, root: &mut Table<T>, vaddr: VirtAddr, attr: MapAttr) -> SysResult {
|
pub fn map<T: TableLevel>(&self, root: &mut Table<T>, vaddr: VirtAddr, attr: MapAttr) -> SysResult {
|
||||||
let masked_attr = attr & self.attr();
|
let masked_attr = attr & self.attr();
|
||||||
|
|
||||||
root.map(vaddr, self.cte.cap.ptr, masked_attr)?;
|
root.map(vaddr, self.cap().get().ptr, masked_attr)?;
|
||||||
|
|
||||||
self.set_mapped_asid(0);
|
self.set_mapped_asid(0);
|
||||||
self.set_mapped_vaddr(vaddr);
|
self.set_mapped_vaddr(vaddr);
|
||||||
@ -143,7 +141,7 @@ impl<'a> FrameCap<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match root.lookup_mut(vaddr) {
|
match root.lookup_mut(vaddr) {
|
||||||
Some(entry) if entry.is_leaf() && entry.paddr() == self.cte.cap.ptr => {
|
Some(entry) if entry.is_leaf() && entry.paddr() == self.cap().get().ptr => {
|
||||||
entry.set_paddr(PhysAddr::default());
|
entry.set_paddr(PhysAddr::default());
|
||||||
entry.set_attr(MapAttr::empty());
|
entry.set_attr(MapAttr::empty());
|
||||||
|
|
||||||
@ -161,7 +159,7 @@ impl<'a> FrameCap<'a> {
|
|||||||
impl Debug for FrameCap<'_> {
|
impl Debug for FrameCap<'_> {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
f.debug_struct("FrameCap")
|
f.debug_struct("FrameCap")
|
||||||
.field("ptr", &self.cte.cap.ptr)
|
.field("ptr", &self.cap().get().ptr)
|
||||||
.field("size", &self.size())
|
.field("size", &self.size())
|
||||||
.field("attr", &self.attr())
|
.field("attr", &self.attr())
|
||||||
.field("is_device", &self.is_device())
|
.field("is_device", &self.is_device())
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::arch::layout::mmap_phys_to_virt;
|
use crate::arch::layout::mmap_phys_to_virt;
|
||||||
use core::marker::PhantomData;
|
use core::{cell::Cell, marker::PhantomData};
|
||||||
use uapi::{
|
use uapi::{
|
||||||
cap::ObjectType,
|
cap::ObjectType,
|
||||||
error::{SysError, SysResult},
|
error::{SysError, SysResult},
|
||||||
@ -33,7 +33,7 @@ pub mod untyped;
|
|||||||
|
|
||||||
pub use cap::{CapEntry, RawCap};
|
pub use cap::{CapEntry, RawCap};
|
||||||
pub use cnode::{CNodeCap, CNodeObject};
|
pub use cnode::{CNodeCap, CNodeObject};
|
||||||
pub use endpoint::{EndpointCap, EndpointObject};
|
pub use endpoint::EndpointCap;
|
||||||
pub use frame::{FrameCap, FrameObject};
|
pub use frame::{FrameCap, FrameObject};
|
||||||
pub use null::NullCap;
|
pub use null::NullCap;
|
||||||
pub use table::{TableCap, TableObject};
|
pub use table::{TableCap, TableObject};
|
||||||
@ -52,7 +52,7 @@ impl<'a, T: KernelObject + ?Sized> TryFrom<&'a CapEntry> for Cap<'a, T> {
|
|||||||
type Error = SysError;
|
type Error = SysError;
|
||||||
|
|
||||||
fn try_from(new: &'a CapEntry) -> SysResult<Self> {
|
fn try_from(new: &'a CapEntry) -> SysResult<Self> {
|
||||||
if new.cap.cap_type != T::OBJ_TYPE {
|
if new.cap.get().cap_type != T::OBJ_TYPE {
|
||||||
Err(SysError::CapTypeMismatch)
|
Err(SysError::CapTypeMismatch)
|
||||||
} else {
|
} else {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -64,22 +64,22 @@ impl<'a, T: KernelObject + ?Sized> TryFrom<&'a CapEntry> for Cap<'a, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: KernelObject + ?Sized> Cap<'a, T> {
|
impl<'a, T: KernelObject + ?Sized> Cap<'a, T> {
|
||||||
pub fn append(&mut self, new: &mut CapEntry) {
|
pub fn cap(&self) -> &Cell<RawCap> {
|
||||||
self.cte.link.append(new)
|
&self.cte.cap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: KernelObject> Cap<'a, T> {
|
impl<'a, T: KernelObject> Cap<'a, T> {
|
||||||
pub fn as_object(&self) -> &T {
|
pub fn as_object(&self) -> &T {
|
||||||
unsafe {
|
unsafe {
|
||||||
let virt = mmap_phys_to_virt(self.cte.cap.ptr);
|
let virt = mmap_phys_to_virt(self.cap().get().ptr);
|
||||||
&*(virt.as_const_ptr())
|
&*(virt.as_const_ptr())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_object_mut(&mut self) -> &mut T {
|
pub fn as_object_mut(&mut self) -> &mut T {
|
||||||
unsafe {
|
unsafe {
|
||||||
let virt = mmap_phys_to_virt(self.cte.cap.ptr);
|
let virt = mmap_phys_to_virt(self.cap().get().ptr);
|
||||||
&mut *(virt.as_mut_ptr())
|
&mut *(virt.as_mut_ptr())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ impl<'a> NullCap<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn override_cap(&self, new: RawCap) {
|
pub fn override_cap(&self, new: RawCap) {
|
||||||
unsafe { self.cte.cap.update(|cap| *cap = new) };
|
self.cap().replace(new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,50 +43,47 @@ impl<'a> TableCap<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_mapped(&self) -> bool {
|
pub fn is_mapped(&self) -> bool {
|
||||||
let bits = (self.cte.cap.args[0] >> Self::IS_MAPPED_OFFSET) & Self::IS_MAPPED_MASK;
|
let bits = (self.cap().get().args[0] >> Self::IS_MAPPED_OFFSET) & Self::IS_MAPPED_MASK;
|
||||||
bits != 0
|
bits != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_mapped(&self, mapped: bool) {
|
pub fn set_mapped(&self, mapped: bool) {
|
||||||
unsafe {
|
self.cap().update(|mut cap| {
|
||||||
self.cte.cap.update(|cap| {
|
|
||||||
let is_mapped = if mapped { 1 } else { 0 };
|
let is_mapped = if mapped { 1 } else { 0 };
|
||||||
let bits = (is_mapped & Self::IS_MAPPED_MASK) << Self::IS_MAPPED_OFFSET;
|
let bits = (is_mapped & Self::IS_MAPPED_MASK) << Self::IS_MAPPED_OFFSET;
|
||||||
let arg0 = cap.args[0] & !(Self::IS_MAPPED_MASK << Self::IS_MAPPED_OFFSET);
|
let arg0 = cap.args[0] & !(Self::IS_MAPPED_MASK << Self::IS_MAPPED_OFFSET);
|
||||||
cap.args[0] = arg0 | bits;
|
cap.args[0] = arg0 | bits;
|
||||||
})
|
cap
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn asid(&self) -> usize {
|
pub fn asid(&self) -> usize {
|
||||||
(self.cte.cap.args[0] >> Self::ASID_OFFSET) & Self::ASID_MASK
|
(self.cap().get().args[0] >> Self::ASID_OFFSET) & Self::ASID_MASK
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_mapped_asid(&self, asid: usize) {
|
pub fn set_mapped_asid(&self, asid: usize) {
|
||||||
unsafe {
|
self.cap().update(|mut cap| {
|
||||||
self.cte.cap.update(|cap| {
|
|
||||||
let bits = (asid & Self::ASID_MASK) << Self::ASID_OFFSET;
|
let bits = (asid & Self::ASID_MASK) << Self::ASID_OFFSET;
|
||||||
let arg0 = cap.args[0] & !(Self::ASID_MASK << Self::ASID_OFFSET);
|
let arg0 = cap.args[0] & !(Self::ASID_MASK << Self::ASID_OFFSET);
|
||||||
cap.args[0] = arg0 | bits;
|
cap.args[0] = arg0 | bits;
|
||||||
})
|
cap
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mapped_vaddr(&self) -> VirtAddr {
|
pub fn mapped_vaddr(&self) -> VirtAddr {
|
||||||
VirtAddr(self.cte.cap.args[1])
|
VirtAddr(self.cap().get().args[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_mapped_vaddr(&self, vaddr: VirtAddr) {
|
pub fn set_mapped_vaddr(&self, vaddr: VirtAddr) {
|
||||||
unsafe {
|
self.cap().update(|mut cap| {
|
||||||
self.cte.cap.update(|cap| {
|
|
||||||
cap.args[1] = vaddr.0;
|
cap.args[1] = vaddr.0;
|
||||||
})
|
cap
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_object<T: TableLevel>(&self) -> Table<T> {
|
pub fn as_object<T: TableLevel>(&self) -> Table<T> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let virt = mmap_phys_to_virt(self.cte.cap.ptr);
|
let virt = mmap_phys_to_virt(self.cap().get().ptr);
|
||||||
Table::new(virt)
|
Table::new(virt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,14 +94,14 @@ impl<'a> TableCap<'a> {
|
|||||||
|
|
||||||
pub fn clear<T: TableLevel>(&self) {
|
pub fn clear<T: TableLevel>(&self) {
|
||||||
let array: &mut [u8] = unsafe {
|
let array: &mut [u8] = unsafe {
|
||||||
let virt = mmap_phys_to_virt(self.cte.cap.ptr);
|
let virt = mmap_phys_to_virt(self.cap().get().ptr);
|
||||||
core::slice::from_raw_parts_mut(virt.as_mut_ptr(), T::ENTRIES * core::mem::size_of::<T::Entry>())
|
core::slice::from_raw_parts_mut(virt.as_mut_ptr(), T::ENTRIES * core::mem::size_of::<T::Entry>())
|
||||||
};
|
};
|
||||||
array.fill(0);
|
array.fill(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map<T: TableLevel>(&self, root: &mut Table<T>, vaddr: VirtAddr) -> SysResult {
|
pub fn map<T: TableLevel>(&self, root: &mut Table<T>, vaddr: VirtAddr) -> SysResult {
|
||||||
root.map(vaddr, self.cte.cap.ptr, MapAttr::PAGE_TABLE)?;
|
root.map(vaddr, self.cap().get().ptr, MapAttr::PAGE_TABLE)?;
|
||||||
|
|
||||||
self.set_mapped_asid(0);
|
self.set_mapped_asid(0);
|
||||||
self.set_mapped_vaddr(vaddr);
|
self.set_mapped_vaddr(vaddr);
|
||||||
@ -119,7 +116,7 @@ impl<'a> TableCap<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match root.lookup_mut(vaddr) {
|
match root.lookup_mut(vaddr) {
|
||||||
Some(entry) if !entry.is_leaf() && entry.paddr() == self.cte.cap.ptr => {
|
Some(entry) if !entry.is_leaf() && entry.paddr() == self.cap().get().ptr => {
|
||||||
entry.set_paddr(PhysAddr::default());
|
entry.set_paddr(PhysAddr::default());
|
||||||
entry.set_attr(MapAttr::empty());
|
entry.set_attr(MapAttr::empty());
|
||||||
|
|
||||||
@ -136,6 +133,6 @@ impl<'a> TableCap<'a> {
|
|||||||
|
|
||||||
impl Debug for TableCap<'_> {
|
impl Debug for TableCap<'_> {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
f.debug_struct("TableCap").field("ptr", &self.cte.cap.ptr).finish()
|
f.debug_struct("TableCap").field("ptr", &self.cap().get().ptr).finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,23 +42,22 @@ impl UntypedCap<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn free_offset(&self) -> usize {
|
fn free_offset(&self) -> usize {
|
||||||
self.cte.cap.args[0]
|
self.cap().get().args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_free_offset(&mut self, free_offset: usize) {
|
fn set_free_offset(&mut self, free_offset: usize) {
|
||||||
unsafe {
|
self.cap().update(|mut cap| {
|
||||||
self.cte.cap.update(|c| {
|
cap.args[0] = free_offset;
|
||||||
c.args[0] = free_offset;
|
cap
|
||||||
})
|
});
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_device(&self) -> bool {
|
pub fn is_device(&self) -> bool {
|
||||||
(self.cte.cap.args[1] >> 6) & 1 == 1
|
(self.cap().get().args[1] >> 6) & 1 == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_bits(&self) -> usize {
|
fn block_bits(&self) -> usize {
|
||||||
self.cte.cap.args[1] & MASK!(6)
|
self.cap().get().args[1] & MASK!(6)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_size(&self) -> usize {
|
fn block_size(&self) -> usize {
|
||||||
@ -111,7 +110,7 @@ impl UntypedCap<'_> {
|
|||||||
|
|
||||||
// Create new capabilities in slot
|
// Create new capabilities in slot
|
||||||
for (i, slot) in slots.iter_mut().enumerate() {
|
for (i, slot) in slots.iter_mut().enumerate() {
|
||||||
let addr = self.cte.cap.ptr + start_offset + i * obj_size;
|
let addr = self.cap().get().ptr + start_offset + i * obj_size;
|
||||||
let new_cap = match obj_type {
|
let new_cap = match obj_type {
|
||||||
ObjectType::Untyped => UntypedCap::mint(0, obj_type.bits(user_obj_bits), self.is_device(), addr),
|
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),
|
ObjectType::CNode => CNodeCap::mint(user_obj_bits, 0, 0, addr),
|
||||||
@ -122,8 +121,7 @@ impl UntypedCap<'_> {
|
|||||||
_ => return Err(SysError::InvalidArgument),
|
_ => return Err(SysError::InvalidArgument),
|
||||||
};
|
};
|
||||||
|
|
||||||
slot.cap = new_cap;
|
slot.cap.replace(new_cap);
|
||||||
self.append(slot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update free_offset
|
// Update free_offset
|
||||||
@ -139,7 +137,7 @@ impl Debug for UntypedCap<'_> {
|
|||||||
.field("free_offset", &self.free_offset())
|
.field("free_offset", &self.free_offset())
|
||||||
.field("block_bits", &self.block_bits())
|
.field("block_bits", &self.block_bits())
|
||||||
.field("is_device", &self.is_device())
|
.field("is_device", &self.is_device())
|
||||||
.field("ptr", &self.cte.cap.ptr)
|
.field("ptr", &self.cap().get().ptr)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user