mirror of
https://github.com/panpaul/tiny_os
synced 2024-09-20 09:45:19 +08:00
feat: objects: adapt to new vspace
This commit is contained in:
parent
36b061d9a1
commit
7d5875cb0c
@ -25,7 +25,7 @@ mod drivers;
|
||||
mod entry;
|
||||
mod lang;
|
||||
mod logging;
|
||||
// mod objects;
|
||||
mod objects;
|
||||
mod plat;
|
||||
mod scheduler;
|
||||
mod vspace;
|
||||
|
@ -1,20 +1,10 @@
|
||||
use super::{cap::RawCap, Cap, KernelObject};
|
||||
use crate::{
|
||||
arch::{
|
||||
layout::mmap_phys_to_virt,
|
||||
vspace::{Table, TableLevelSize},
|
||||
},
|
||||
objects::cap::CapEntry,
|
||||
};
|
||||
use crate::{arch::layout::mmap_phys_to_virt, objects::cap::CapEntry, vspace::*};
|
||||
use uapi::{
|
||||
cap::ObjectType,
|
||||
error::{SysError, SysResult},
|
||||
};
|
||||
use utils::MASK;
|
||||
use vspace::{
|
||||
addr::{AddressOps, PhysAddr, VirtAddr},
|
||||
paging::{EntryOps, MapAttr, PageError, TableLevel, TableOps},
|
||||
};
|
||||
use utils::{addr::*, MASK};
|
||||
|
||||
/// FrameObject refers to a region of physical memory, aka leaf PTE in pagetable
|
||||
pub type FrameObject = [u8];
|
||||
@ -57,12 +47,11 @@ impl<'a> FrameCap<'a> {
|
||||
const VM_RIGHT_MASK: usize = MASK!(Self::VM_RIGHT_BITS);
|
||||
const VM_RIGHT_OFFSET: usize = 0;
|
||||
|
||||
pub fn mint(ptr: PhysAddr, size: TableLevel, attr: MapAttr, is_device: bool) -> RawCap {
|
||||
let size_bits = size.level_size().ilog2() as usize;
|
||||
pub fn mint(ptr: PhysAddr, size: usize, attr: MapAttr, is_device: bool) -> RawCap {
|
||||
let size_bits = size.ilog2() as usize;
|
||||
debug_assert!(size_bits <= FrameCap::FRAME_SIZE_BITS);
|
||||
|
||||
// TODO: support huge page
|
||||
assert!(size == TableLevel::Level0, "only support leaf page for now");
|
||||
// NOTE: we are not checking frame size
|
||||
|
||||
let arg0 = 0
|
||||
| ((attr.bits() & Self::VM_RIGHT_MASK) << Self::VM_RIGHT_OFFSET)
|
||||
@ -137,15 +126,14 @@ impl<'a> FrameCap<'a> {
|
||||
self.as_object_mut().fill(fill.unwrap_or(0));
|
||||
}
|
||||
|
||||
pub fn map_page(&self, root: &mut Table, vaddr: VirtAddr, attr: MapAttr) -> SysResult {
|
||||
pub fn map_page<T: TableLevel>(&self, root: &mut Table<T>, vaddr: VirtAddr, attr: MapAttr) -> SysResult {
|
||||
let masked_attr = attr & self.attr();
|
||||
|
||||
// TODO: support huge page
|
||||
root.map(vaddr, self.cte.cap.get().ptr, masked_attr, TableLevel::Level0)
|
||||
.map_err(|e| match e {
|
||||
PageError::AlreadyMapped(_) => SysError::AlreadyMapped,
|
||||
PageError::MissingEntry(_) => SysError::MissingEntry,
|
||||
})?;
|
||||
root.map(vaddr, self.cte.cap.get().ptr, masked_attr).map_err(|e| match e {
|
||||
PageError::AlreadyMapped => SysError::AlreadyMapped,
|
||||
PageError::MissingEntry => SysError::MissingEntry,
|
||||
PageError::NotAligned => SysError::InvalidArgument,
|
||||
})?;
|
||||
|
||||
self.set_mapped_asid(0);
|
||||
self.set_mapped_vaddr(vaddr);
|
||||
@ -153,15 +141,15 @@ impl<'a> FrameCap<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn unmap(&self, root: &mut Table) -> SysResult {
|
||||
pub fn unmap<T: TableLevel>(&self, root: &mut Table<T>) -> SysResult {
|
||||
let vaddr = self.mapped_vaddr();
|
||||
if vaddr.0 == 0 {
|
||||
return Err(SysError::NotMapped);
|
||||
}
|
||||
|
||||
match root.lookup_mut(self.mapped_vaddr()) {
|
||||
Some(entry) if entry.is_leaf() && entry.addr() == self.cte.cap.get().ptr => {
|
||||
entry.set_addr(PhysAddr::default());
|
||||
Some(entry) if entry.is_leaf() && entry.paddr() == self.cte.cap.get().ptr => {
|
||||
entry.set_paddr(PhysAddr::default());
|
||||
entry.set_attr(MapAttr::empty());
|
||||
|
||||
self.set_mapped_asid(0);
|
||||
|
@ -1,19 +1,13 @@
|
||||
use crate::arch::{layout::mmap_phys_to_virt, vspace::Table};
|
||||
|
||||
use super::{cap::RawCap, Cap, KernelObject};
|
||||
use crate::{arch::layout::mmap_phys_to_virt, vspace::*};
|
||||
use uapi::{
|
||||
cap::ObjectType,
|
||||
error::{SysError, SysResult},
|
||||
vspace::MapAttr,
|
||||
};
|
||||
use utils::MASK;
|
||||
use vspace::{
|
||||
addr::{AddressOps, PhysAddr, VirtAddr},
|
||||
paging::{EntryOps, PageError, TableLevel, TableOps},
|
||||
};
|
||||
use utils::{addr::*, MASK};
|
||||
|
||||
/// TableObject is an object that represents a page table
|
||||
pub type TableObject = Table;
|
||||
pub struct TableObject([usize]);
|
||||
impl KernelObject for TableObject {
|
||||
const OBJ_TYPE: ObjectType = ObjectType::PageTable;
|
||||
}
|
||||
@ -87,33 +81,31 @@ impl<'a> TableCap<'a> {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn as_object(&self) -> &TableObject {
|
||||
pub fn as_object<T: TableLevel>(&self) -> Table<T> {
|
||||
unsafe {
|
||||
let virt = mmap_phys_to_virt(self.cte.cap.get().ptr);
|
||||
Table::new(virt)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_object_mut(&mut self) -> &mut TableObject {
|
||||
unsafe {
|
||||
let virt = mmap_phys_to_virt(self.cte.cap.get().ptr);
|
||||
Table::new(virt)
|
||||
}
|
||||
pub fn as_object_mut<T: TableLevel>(&mut self) -> Table<T> {
|
||||
self.as_object()
|
||||
}
|
||||
|
||||
pub fn clear(&self) {
|
||||
pub fn clear<T: TableLevel>(&self) {
|
||||
let array: &mut [u8] = unsafe {
|
||||
let virt = mmap_phys_to_virt(self.cte.cap.get().ptr);
|
||||
core::slice::from_raw_parts_mut(virt.as_mut_ptr(), Table::TABLE_SIZE)
|
||||
core::slice::from_raw_parts_mut(virt.as_mut_ptr(), T::ENTRIES * core::mem::size_of::<T::Entry>())
|
||||
};
|
||||
array.fill(0);
|
||||
}
|
||||
|
||||
pub fn map_table(&self, root: &mut Table, vaddr: VirtAddr, level: TableLevel) -> SysResult {
|
||||
root.map(vaddr, self.cte.cap.get().ptr, MapAttr::PAGE_TABLE, level)
|
||||
pub fn map_table<T: TableLevel>(&self, root: &mut Table<T>, vaddr: VirtAddr) -> SysResult {
|
||||
root.map(vaddr, self.cte.cap.get().ptr, MapAttr::PAGE_TABLE)
|
||||
.map_err(|e| match e {
|
||||
PageError::AlreadyMapped(_) => SysError::AlreadyMapped,
|
||||
PageError::MissingEntry(_) => SysError::MissingEntry,
|
||||
PageError::AlreadyMapped => SysError::AlreadyMapped,
|
||||
PageError::MissingEntry => SysError::MissingEntry,
|
||||
PageError::NotAligned => SysError::InvalidArgument,
|
||||
})?;
|
||||
|
||||
self.set_mapped_asid(0);
|
||||
@ -122,15 +114,15 @@ impl<'a> TableCap<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn unmap(&self, root: &mut Table) -> SysResult {
|
||||
pub fn unmap<T: TableLevel>(&self, root: &mut Table<T>) -> SysResult {
|
||||
let vaddr = self.mapped_vaddr();
|
||||
if vaddr.0 == 0 {
|
||||
return Err(SysError::NotMapped);
|
||||
}
|
||||
|
||||
match root.lookup_mut(self.mapped_vaddr()) {
|
||||
Some(entry) if !entry.is_leaf() && entry.addr() == self.cte.cap.get().ptr => {
|
||||
entry.set_addr(PhysAddr::default());
|
||||
Some(entry) if !entry.is_leaf() && entry.paddr() == self.cte.cap.get().ptr => {
|
||||
entry.set_paddr(PhysAddr::default());
|
||||
entry.set_attr(MapAttr::empty());
|
||||
|
||||
self.set_mapped_asid(0);
|
||||
|
Loading…
Reference in New Issue
Block a user