feat: bump heap allocator
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
//! aarch64 common boot logic
|
||||
|
||||
use crate::arch::{aarch64::asm::CPACR_EL1, machine};
|
||||
use crate::dev::{Device, fdt::DeviceTree};
|
||||
use crate::mem::virt;
|
||||
use crate::dev::{fdt::DeviceTree, Device};
|
||||
use crate::mem::{
|
||||
self,
|
||||
heap,
|
||||
phys::{self, PageUsage},
|
||||
virt,
|
||||
};
|
||||
use cortex_a::asm::barrier::{self, dsb, isb};
|
||||
use cortex_a::registers::{DAIF, SCTLR_EL1, VBAR_EL1};
|
||||
use tock_registers::interfaces::{ReadWriteable, Writeable};
|
||||
@@ -32,6 +37,18 @@ extern "C" fn __aa64_bsp_main(fdt_base: usize) {
|
||||
// Enable MMU
|
||||
virt::enable().expect("Failed to initialize virtual memory");
|
||||
|
||||
// Most basic machine init: initialize proper debug output
|
||||
// physical memory
|
||||
machine::init_board_early().unwrap();
|
||||
|
||||
// Setup a heap
|
||||
unsafe {
|
||||
let heap_base_phys = phys::alloc_contiguous_pages(PageUsage::KernelHeap, 4096)
|
||||
.expect("Failed to allocate memory for heap");
|
||||
let heap_base_virt = mem::virtualize(heap_base_phys);
|
||||
heap::init(heap_base_virt, 16 * 1024 * 1024);
|
||||
}
|
||||
|
||||
machine::init_board().unwrap();
|
||||
|
||||
if fdt_base != 0 {
|
||||
@@ -42,6 +59,8 @@ extern "C" fn __aa64_bsp_main(fdt_base: usize) {
|
||||
} else {
|
||||
debugln!("Failed to init FDT");
|
||||
}
|
||||
} else {
|
||||
debugln!("No FDT present");
|
||||
}
|
||||
|
||||
debugln!("Machine init finished");
|
||||
|
||||
@@ -17,24 +17,30 @@ use error::Errno;
|
||||
|
||||
pub use gic::IrqNumber;
|
||||
|
||||
// TODO extract this from device tree
|
||||
const UART0_BASE: usize = 0x09000000;
|
||||
const RTC_BASE: usize = 0x09010000;
|
||||
const GICD_BASE: usize = 0x08000000;
|
||||
const GICC_BASE: usize = 0x08010000;
|
||||
// TODO extract this from device tree
|
||||
const ECAM_BASE: usize = 0x4010000000;
|
||||
|
||||
const PHYS_BASE: usize = 0x40000000;
|
||||
const PHYS_SIZE: usize = 0x10000000;
|
||||
|
||||
#[allow(missing_docs)]
|
||||
pub fn init_board() -> Result<(), Errno> {
|
||||
pub fn init_board_early() -> Result<(), Errno> {
|
||||
unsafe {
|
||||
// Enable UART early on
|
||||
UART0.enable()?;
|
||||
|
||||
phys::init_from_region(PHYS_BASE, PHYS_SIZE);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
pub fn init_board() -> Result<(), Errno> {
|
||||
unsafe {
|
||||
GIC.enable()?;
|
||||
|
||||
UART0.init_irqs()?;
|
||||
@@ -43,7 +49,7 @@ pub fn init_board() -> Result<(), Errno> {
|
||||
RTC.init_irqs()?;
|
||||
|
||||
PCIE.enable()?;
|
||||
PCIE.map()?;
|
||||
// PCIE.map()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
+3
-1
@@ -8,7 +8,8 @@
|
||||
const_fn_fn_ptr_basics,
|
||||
const_fn_trait_bound,
|
||||
const_panic,
|
||||
panic_info_message
|
||||
panic_info_message,
|
||||
alloc_error_handler,
|
||||
)]
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
@@ -16,6 +17,7 @@
|
||||
|
||||
#[macro_use]
|
||||
extern crate cfg_if;
|
||||
extern crate alloc;
|
||||
|
||||
#[macro_use]
|
||||
pub mod debug;
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
use crate::util::InitOnce;
|
||||
use crate::sync::IrqSafeNullLock;
|
||||
use core::alloc::{GlobalAlloc, Layout};
|
||||
use core::ptr::null_mut;
|
||||
|
||||
struct SystemAlloc;
|
||||
|
||||
struct Heap {
|
||||
base: usize,
|
||||
size: usize,
|
||||
ptr: usize,
|
||||
}
|
||||
|
||||
unsafe impl GlobalAlloc for SystemAlloc {
|
||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||
HEAP.get().lock().alloc(layout)
|
||||
}
|
||||
|
||||
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
||||
HEAP.get().lock().dealloc(ptr, layout)
|
||||
}
|
||||
}
|
||||
|
||||
impl Heap {
|
||||
unsafe fn alloc(&mut self, layout: Layout) -> *mut u8 {
|
||||
// Simple bump allocation
|
||||
assert!(layout.align() <= 16);
|
||||
let size = (layout.size() + 15) & !15;
|
||||
if self.ptr + size >= self.size {
|
||||
return null_mut();
|
||||
}
|
||||
|
||||
let ptr = self.ptr;
|
||||
self.ptr += size;
|
||||
|
||||
(self.base + ptr) as *mut u8
|
||||
}
|
||||
|
||||
unsafe fn dealloc(&mut self, _ptr: *mut u8, _layout: Layout) {
|
||||
}
|
||||
}
|
||||
|
||||
#[alloc_error_handler]
|
||||
fn alloc_error_handler(layout: Layout) -> ! {
|
||||
panic!("Allocation failed: {:?}", layout)
|
||||
}
|
||||
|
||||
#[global_allocator]
|
||||
static SYSTEM_ALLOC: SystemAlloc = SystemAlloc;
|
||||
|
||||
static HEAP: InitOnce<IrqSafeNullLock<Heap>> = InitOnce::new();
|
||||
|
||||
pub unsafe fn init(base: usize, size: usize) {
|
||||
let heap = Heap {
|
||||
base,
|
||||
size,
|
||||
ptr: 0
|
||||
};
|
||||
|
||||
debugln!("Kernel heap: {:#x}..{:#x}", base, base + size);
|
||||
|
||||
HEAP.init(IrqSafeNullLock::new(heap));
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
pub mod phys;
|
||||
pub mod virt;
|
||||
pub mod heap;
|
||||
|
||||
/// Virtual offset applied to kernel address space
|
||||
pub const KERNEL_OFFSET: usize = 0xFFFFFF8000000000;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::mem::PAGE_SIZE;
|
||||
use core::mem::size_of;
|
||||
use error::Errno;
|
||||
|
||||
mod reserved;
|
||||
mod manager;
|
||||
@@ -15,7 +16,8 @@ const MAX_PAGES: usize = 1024 * 1024;
|
||||
pub enum PageUsage {
|
||||
Reserved,
|
||||
Available,
|
||||
Kernel
|
||||
Kernel,
|
||||
KernelHeap
|
||||
}
|
||||
|
||||
pub struct PageInfo {
|
||||
@@ -46,6 +48,10 @@ impl Iterator for SimpleMemoryIterator {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloc_contiguous_pages(pu: PageUsage, count: usize) -> Result<usize, Errno> {
|
||||
MANAGER.lock().as_mut().unwrap().alloc_contiguous_pages(pu, count)
|
||||
}
|
||||
|
||||
fn find_contiguous<T: Iterator<Item = MemoryRegion>>(
|
||||
iter: T,
|
||||
count: usize,
|
||||
|
||||
Reference in New Issue
Block a user