i686: free translation tables
This commit is contained in:
parent
c907fe032a
commit
ce8ccf4af9
@ -64,6 +64,16 @@ impl KernelTableManager for KernelTableManagerImpl {
|
|||||||
.expect("Invalid virtual address")
|
.expect("Invalid virtual address")
|
||||||
.into_u64()
|
.into_u64()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn unmap_physical_address(virt: usize) {
|
||||||
|
if virt < KERNEL_VIRT_OFFSET {
|
||||||
|
panic!("Invalid 'virtualized' address: {:#x}", virt);
|
||||||
|
}
|
||||||
|
let virt = virt - KERNEL_VIRT_OFFSET;
|
||||||
|
if virt >= fixed::FIXED_MAP_COUNT << L0::SHIFT {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets up fixed MMU translation tables.
|
/// Sets up fixed MMU translation tables.
|
||||||
|
@ -5,14 +5,16 @@ use libk_mm_interface::{
|
|||||||
address::{AsPhysicalAddress, PhysicalAddress},
|
address::{AsPhysicalAddress, PhysicalAddress},
|
||||||
pointer::PhysicalRefMut,
|
pointer::PhysicalRefMut,
|
||||||
process::ProcessAddressSpaceManager,
|
process::ProcessAddressSpaceManager,
|
||||||
table::{EntryLevel, EntryLevelExt, MapAttributes, NextPageTable, TableAllocator},
|
table::{
|
||||||
|
EntryLevel, EntryLevelDrop, EntryLevelExt, MapAttributes, NextPageTable, TableAllocator,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use yggdrasil_abi::error::Error;
|
use yggdrasil_abi::error::Error;
|
||||||
|
|
||||||
use crate::{mem::flush_tlb_entry, KernelTableManagerImpl};
|
use crate::{mem::flush_tlb_entry, KernelTableManagerImpl};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
fixed::clone_kernel_tables,
|
fixed::{clone_kernel_tables, KERNEL_SPLIT_L0},
|
||||||
table::{PageEntry, PageTable, L0, L3},
|
table::{PageEntry, PageTable, L0, L3},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,9 +48,7 @@ impl<TA: TableAllocator> ProcessAddressSpaceManager<TA> for ProcessAddressSpaceI
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn clear(&mut self) {
|
unsafe fn clear(&mut self) {
|
||||||
// TODO
|
self.l0.drop_range::<TA>(0..KERNEL_SPLIT_L0);
|
||||||
// self.l0
|
|
||||||
// .drop_range::<TA>(0..((Self::UPPER_LIMIT_PFN * L3::SIZE).page_index::<L0>()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate(&self, address: usize) -> Result<(PhysicalAddress, MapAttributes), Error> {
|
fn translate(&self, address: usize) -> Result<(PhysicalAddress, MapAttributes), Error> {
|
||||||
@ -123,3 +123,15 @@ impl<TA: TableAllocator> ProcessAddressSpaceImpl<TA> {
|
|||||||
Some((page, l3[l3i].attributes().into()))
|
Some((page, l3[l3i].attributes().into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<TA: TableAllocator> Drop for ProcessAddressSpaceImpl<TA> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
// SAFETY: with safe usage of the ProcessAddressSpaceImpl, clearing and dropping
|
||||||
|
// is safe, no one refers to the memory
|
||||||
|
unsafe {
|
||||||
|
self.clear();
|
||||||
|
let l0_phys = self.l0.as_physical_address();
|
||||||
|
TA::free_page_table(l0_phys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
use core::{
|
use core::{
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
ops::{Index, IndexMut},
|
ops::{Index, IndexMut, Range},
|
||||||
};
|
};
|
||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use libk_mm_interface::{
|
use libk_mm_interface::{
|
||||||
address::{AsPhysicalAddress, PhysicalAddress},
|
address::{AsPhysicalAddress, PhysicalAddress},
|
||||||
pointer::{PhysicalRef, PhysicalRefMut},
|
pointer::{PhysicalRef, PhysicalRefMut},
|
||||||
table::{EntryLevel, MapAttributes, NextPageTable, NonTerminalEntryLevel, TableAllocator},
|
table::{
|
||||||
|
EntryLevel, EntryLevelDrop, MapAttributes, NextPageTable, NonTerminalEntryLevel,
|
||||||
|
TableAllocator,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use yggdrasil_abi::error::Error;
|
use yggdrasil_abi::error::Error;
|
||||||
|
|
||||||
@ -132,6 +135,16 @@ impl<L: EntryLevel> PageTable<L> {
|
|||||||
|
|
||||||
Ok(table)
|
Ok(table)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Recursively clears and deallocates the translation table.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The caller must ensure the table is no longer in use and is not referenced anymore.
|
||||||
|
pub unsafe fn free<TA: TableAllocator>(this: PhysicalRefMut<Self, KernelTableManagerImpl>) {
|
||||||
|
let physical = this.as_physical_address();
|
||||||
|
TA::free_page_table(physical);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NextPageTable for PageTable<L0> {
|
impl NextPageTable for PageTable<L0> {
|
||||||
@ -184,6 +197,39 @@ impl<L: EntryLevel> IndexMut<usize> for PageTable<L> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EntryLevelDrop for PageTable<L3> {
|
||||||
|
const FULL_RANGE: Range<usize> = 0..1024;
|
||||||
|
|
||||||
|
unsafe fn drop_range<TA: TableAllocator>(&mut self, _range: Range<usize>) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntryLevelDrop for PageTable<L0> {
|
||||||
|
const FULL_RANGE: Range<usize> = 0..1024;
|
||||||
|
|
||||||
|
unsafe fn drop_range<TA: TableAllocator>(&mut self, range: Range<usize>) {
|
||||||
|
for index in range {
|
||||||
|
let entry = self[index];
|
||||||
|
|
||||||
|
if let Some(table) = entry.as_table() {
|
||||||
|
let mut table_ref: PhysicalRefMut<PageTable<L3>, KernelTableManagerImpl> =
|
||||||
|
PhysicalRefMut::map(table);
|
||||||
|
|
||||||
|
table_ref.drop_all::<TA>();
|
||||||
|
|
||||||
|
TA::free_page_table(table);
|
||||||
|
} else if entry.is_present() {
|
||||||
|
// Memory must've been cleared beforehand, so no non-table entries must be present
|
||||||
|
panic!(
|
||||||
|
"Expected a table containing only tables, got table[{}] = {:#x?}",
|
||||||
|
index, entry.0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
self[index] = PageEntry::INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<MapAttributes> for PageAttributes {
|
impl From<MapAttributes> for PageAttributes {
|
||||||
fn from(value: MapAttributes) -> Self {
|
fn from(value: MapAttributes) -> Self {
|
||||||
let mut res = PageAttributes::WRITABLE;
|
let mut res = PageAttributes::WRITABLE;
|
||||||
|
@ -66,14 +66,15 @@ pub fn load_kernel_symbol_table<P: AsRef<Path>>(
|
|||||||
let mut map = DefaultHashTable::new();
|
let mut map = DefaultHashTable::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut len = [0; size_of::<usize>()];
|
let mut len = [0; size_of::<u32>()];
|
||||||
|
let mut value = [0; size_of::<u64>()];
|
||||||
|
|
||||||
if symbol_file.read(&mut len)? != len.len() {
|
if symbol_file.read(&mut len)? != len.len() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let len = u32::from_le_bytes(len) as usize;
|
let len = u32::from_le_bytes(len) as usize;
|
||||||
symbol_file.read_exact(&mut string_buffer[..len])?;
|
symbol_file.read_exact(&mut string_buffer[..len])?;
|
||||||
let name = core::str::from_utf8(&string_buffer[..len]).unwrap();
|
let name = core::str::from_utf8(&string_buffer[..len]).unwrap();
|
||||||
let mut value = [0; size_of::<u64>()];
|
|
||||||
symbol_file.read_exact(&mut value)?;
|
symbol_file.read_exact(&mut value)?;
|
||||||
let value = u64::from_le_bytes(value).try_into().unwrap();
|
let value = u64::from_le_bytes(value).try_into().unwrap();
|
||||||
map.insert(name.into(), value);
|
map.insert(name.into(), value);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user