Physical Memory Management Improvements.
This commit is contained in:
parent
f33cd1a109
commit
2e23e313ac
4 changed files with 212 additions and 18 deletions
131
rust/lib/mammoth/src/physical_box.rs
Normal file
131
rust/lib/mammoth/src/physical_box.rs
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
use core::{
|
||||
marker::PhantomData,
|
||||
ops::{Deref, DerefMut, Index, IndexMut},
|
||||
ptr::NonNull,
|
||||
};
|
||||
|
||||
use alloc::{slice, vec::Vec};
|
||||
|
||||
use crate::mem::MemoryRegion;
|
||||
|
||||
pub struct PhysicalBox<T: ?Sized> {
|
||||
data: NonNull<T>,
|
||||
region: MemoryRegion,
|
||||
physical_address: usize,
|
||||
_marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: ?Sized> PhysicalBox<T> {
|
||||
pub fn physical_address(&self) -> usize {
|
||||
self.physical_address
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Deref for PhysicalBox<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
// SAFETY:
|
||||
// - Alignment: This is page aligned.
|
||||
// - Dereferenceable: Guaranteed in same allocation.
|
||||
// - Aliasing: The borrow rules ensure this
|
||||
unsafe { self.data.as_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> DerefMut for PhysicalBox<T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
// SAFETY:
|
||||
// - Alignment: This is page aligned.
|
||||
// - Dereferenceable: Guaranteed in same allocation.
|
||||
// - Aliasing: The borrow rules ensure this
|
||||
unsafe { self.data.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PhysicalBox<[T]> {
|
||||
pub fn default_with_count(default: T, len: usize) -> Self
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
let layout = core::alloc::Layout::array::<T>(len).expect("Layout overflow");
|
||||
|
||||
// TODO: Implement a function like alloc that takes a layout. let (memory_region, paddr) =
|
||||
let (memory_region, paddr) =
|
||||
MemoryRegion::contiguous_physical(layout.size() as u64).expect("Failed to allocate");
|
||||
|
||||
let ptr: *mut T = memory_region.mut_ptr_at_offset(0);
|
||||
for i in 0..len {
|
||||
unsafe {
|
||||
ptr.add(i).write(default.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let slice_ptr = core::ptr::slice_from_raw_parts_mut(ptr, len);
|
||||
|
||||
Self {
|
||||
// UNWRAP: We know this isn't null.
|
||||
data: NonNull::new(slice_ptr).unwrap(),
|
||||
region: memory_region,
|
||||
physical_address: paddr as usize,
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_vec(mut vec: Vec<T>) -> Self {
|
||||
let len = vec.len();
|
||||
let layout = core::alloc::Layout::array::<T>(len).expect("Layout overflow");
|
||||
|
||||
// TODO: Implement a function like alloc that takes a layout.
|
||||
let (memory_region, paddr) =
|
||||
MemoryRegion::contiguous_physical(layout.size() as u64).expect("Failed to allocate");
|
||||
|
||||
let ptr: *mut T = memory_region.mut_ptr_at_offset(0);
|
||||
for (i, item) in vec.into_iter().enumerate() {
|
||||
unsafe {
|
||||
ptr.add(i).write(item);
|
||||
}
|
||||
}
|
||||
|
||||
let slice_ptr = core::ptr::slice_from_raw_parts_mut(ptr, len);
|
||||
|
||||
Self {
|
||||
// UNWRAP: We know this isn't null.
|
||||
data: NonNull::new(slice_ptr).unwrap(),
|
||||
region: memory_region,
|
||||
physical_address: paddr as usize,
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
pub fn len(&self) -> usize {
|
||||
(**self).len()
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T> Index<I> for PhysicalBox<[T]>
|
||||
where
|
||||
I: slice::SliceIndex<[T]>,
|
||||
{
|
||||
type Output = I::Output;
|
||||
|
||||
fn index(&self, index: I) -> &Self::Output {
|
||||
&(**self)[index]
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T> IndexMut<I> for PhysicalBox<[T]>
|
||||
where
|
||||
I: slice::SliceIndex<[T]>,
|
||||
{
|
||||
fn index_mut(&mut self, index: I) -> &mut Self::Output {
|
||||
&mut (**self)[index]
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Drop for PhysicalBox<T> {
|
||||
fn drop(&mut self) {
|
||||
// SAFETY:
|
||||
// - We own this data.
|
||||
unsafe { core::ptr::drop_in_place(self.data.as_ptr()) }
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue