feat: bump heap allocator

This commit is contained in:
2021-10-14 19:28:04 +03:00
parent 6bd252f18e
commit 4facf30d0b
6 changed files with 104 additions and 7 deletions
+21 -2
View File
@@ -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");
+9 -3
View File
@@ -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
View File
@@ -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;
+63
View File
@@ -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));
}
+1
View File
@@ -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;
+7 -1
View File
@@ -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,