diff options
author | Nathan Ringo <nathan@remexre.com> | 2024-09-14 23:04:03 -0500 |
---|---|---|
committer | Nathan Ringo <nathan@remexre.com> | 2024-09-14 23:04:03 -0500 |
commit | 22231ec036268ca2adb1f0b0feed0a91ea68728f (patch) | |
tree | 79dc49db7bd7758a7eb40a64828628461930b228 /crates/kernel/src/alloc.rs | |
parent | 0392b41e7081c11caa9d04aa738bdac97062e9dd (diff) |
Start of virtual memory allocator; got an ICE, though!
Diffstat (limited to 'crates/kernel/src/alloc.rs')
-rw-r--r-- | crates/kernel/src/alloc.rs | 58 |
1 files changed, 46 insertions, 12 deletions
diff --git a/crates/kernel/src/alloc.rs b/crates/kernel/src/alloc.rs index 93d8b15..690b428 100644 --- a/crates/kernel/src/alloc.rs +++ b/crates/kernel/src/alloc.rs @@ -1,13 +1,14 @@ //! Global structures for the allocators. use crate::paging::{ - BuddyAllocator, MapError, MappingFlags, PageTable, ASID, LOMEM_TOP, MAX_PAGE_SIZE_BITS, - PAGE_SIZE, PAGE_SIZES, + BuddyAllocator, MapError, MappingFlags, PageTable, ASID, HIMEM_BOT, LOMEM_TOP, + MAX_PAGE_SIZE_BITS, PAGE_SIZE, PAGE_SIZES, PAGE_SIZE_BITS, }; -use allocator_api2::alloc::AllocError; +use allocator_api2::alloc::{AllocError, Global, GlobalAlloc, Layout}; use contracts::requires; use core::{num::NonZero, ptr::NonNull}; use spin::mutex::FairMutex; +use vernos_alloc_vma_tree::VMATree; /// The global instance of the physical page allocator. static BUDDY_ALLOCATOR: FairMutex<Option<BuddyAllocator>> = FairMutex::new(None); @@ -15,16 +16,24 @@ static BUDDY_ALLOCATOR: FairMutex<Option<BuddyAllocator>> = FairMutex::new(None) /// The global kernel page table. static KERNEL_PAGE_TABLE: FairMutex<Option<&'static mut PageTable>> = FairMutex::new(None); +/// The kernel's virtual memory allocator. +static KERNEL_VM_ALLOC: FairMutex<VMATree<PAGE_SIZE_BITS, Global>> = + FairMutex::new(VMATree::new_in(Global)); + +/// The global allocator. +#[global_allocator] +static GLOBAL_ALLOC: GlobalGenMalloc = GlobalGenMalloc; + /// Initializes the kernel page table and enables paging. /// /// # Safety /// /// - Paging must not have been enabled previously. /// - The buddy allocator must be valid. -#[requires(BUDDY_ALLOCATOR.lock().is_none())] #[requires(KERNEL_PAGE_TABLE.lock().is_none())] -#[ensures(BUDDY_ALLOCATOR.lock().is_some())] +#[requires(BUDDY_ALLOCATOR.lock().is_none())] #[ensures(KERNEL_PAGE_TABLE.lock().is_some())] +#[ensures(BUDDY_ALLOCATOR.lock().is_some())] pub unsafe fn init_kernel_page_table(buddy_allocator: BuddyAllocator) { // Just making this mut above gets a warning thanks to the contracts macros... let mut buddy_allocator = buddy_allocator; @@ -59,8 +68,8 @@ pub unsafe fn init_kernel_page_table(buddy_allocator: BuddyAllocator) { vernos_utils::dbg!(&page_table); // Save the buddy allocator and kernel page table. - *BUDDY_ALLOCATOR.lock() = Some(buddy_allocator); *KERNEL_PAGE_TABLE.lock() = Some(page_table); + *BUDDY_ALLOCATOR.lock() = Some(buddy_allocator); } /// Initializes the virtual memory allocator and the regular allocator. @@ -68,11 +77,19 @@ pub unsafe fn init_kernel_page_table(buddy_allocator: BuddyAllocator) { /// # Safety /// /// - `himem_top` must be accurate. -#[requires(BUDDY_ALLOCATOR.lock().is_some())] #[requires(KERNEL_PAGE_TABLE.lock().is_some())] +#[requires(BUDDY_ALLOCATOR.lock().is_some())] #[requires(himem_top & (PAGE_SIZE - 1) == 0)] +#[requires(HIMEM_BOT < himem_top)] pub unsafe fn init_kernel_virtual_memory_allocator(himem_top: usize) { - todo!() + // TODO: Bootstrap the allocator. + + // The error here _really_ ought to be impossible, because we just bootstrapped the allocator! + // It definitely has free memory. + let mut kernel_vm_alloc = KERNEL_VM_ALLOC.lock(); + kernel_vm_alloc + .add(HIMEM_BOT..himem_top) + .expect("failed to set up the kernel's virtual memory allocator"); } /// Tries to allocate a page of physical memory of the given size, returning its physical address. @@ -112,12 +129,29 @@ pub fn kernel_map( len: usize, flags: MappingFlags, ) -> Result<(), MapError> { - let mut buddy_allocator = BUDDY_ALLOCATOR.lock(); let mut kernel_page_table = KERNEL_PAGE_TABLE.lock(); - let buddy_allocator = buddy_allocator.as_mut().unwrap(); + let mut buddy_allocator = BUDDY_ALLOCATOR.lock(); let kernel_page_table = kernel_page_table.as_mut().unwrap(); + let buddy_allocator = buddy_allocator.as_mut().unwrap(); kernel_page_table.map(&mut *buddy_allocator, vaddr, paddr, len, flags)?; - log::warn!("TODO: sfence.vma"); - log::warn!("TODO: TLB shootdown"); + vernos_utils::first_time! { + { + log::warn!("TODO: sfence.vma"); + log::warn!("TODO: TLB shootdown"); + } + } Ok(()) } + +/// A global allocator backed by a hart-local `vernos_alloc_genmalloc::Heap`. +struct GlobalGenMalloc; + +unsafe impl GlobalAlloc for GlobalGenMalloc { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + todo!("GlobalGenMalloc.alloc({layout:?})") + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + todo!("GlobalGenMalloc.dealloc({ptr:?}, {layout:?})") + } +} |