From 9e180a565adef0f18468ae059c57d890847120f1 Mon Sep 17 00:00:00 2001 From: gil Date: Sat, 18 May 2024 21:09:22 -0500 Subject: [PATCH] Rewrite heap allocation and linker section --- src/entry.rs | 62 ++++++++++++++++++++++++++++++++++++++++++-------- src/heap.rs | 12 +++++----- src/script.lds | 6 ++--- 3 files changed, 62 insertions(+), 18 deletions(-) diff --git a/src/entry.rs b/src/entry.rs index 50c4ee0..f7e3bba 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -1,15 +1,59 @@ -use crate::abort; +// src/entry.rs +#[no_mangle] +#[link_section = ".text.init"] +unsafe extern "C" fn _entry() { + use core::arch::asm; + // let id = riscv::register::mhartid::read(); + // write_tp(&id); + // TODO set up stack for all harts + // TODO set up CSRs for all harts + // if id != 0 { abort(); } + + asm!( + /* Global pointer register `gp` + + Push current option stack to temporarily disable relaxation, load + _global_pointer symbol (provided by linker), then pop option stack. + + Important to keep relaxation off for this instruction, so that + the instruction is emitted as: + 1: + auipc gp, %pcrel_hi(_global_pointer) + addi gp, gp, %pcrel_lo(1b)" + instead of: + mv gp, gp + which would do nothing. */ + ".option push", + ".option norelax", + "la gp, _global_pointer", + ".option pop", + ); + + riscv::register::satp::write(0); -unsafe extern "C" fn _enter() { - let id = riscv::register::mhartid::read(); - write_tp(&id); - // TODO: set up stack for all harts - // TODO: set up CSRs for all harts - if id != 0 { abort(); } + if id != 0 { crate::abort(); } - // TODO: clear BSS - // TODO: do hardware inits and wake other harts + // Clear BSS section + asm!( + "la t0, _bss_start", + "la t1, _bss_end", + "bgeu t0, t1, 2f", + "1:", + "sb zero, 0(t0)", + "addi t0, t0, 1", + "bne t0, t1, 1b", + + "2:", + "la sp, _stack_end", + + "li t0, (0b11 << 11) | (1 << 13)", + "csrw mstatus, t0", + "csrw mie, x0", + + ); + + // TODO do hardware inits and wake other harts } #[inline] diff --git a/src/heap.rs b/src/heap.rs index 910a0a5..c56b576 100644 --- a/src/heap.rs +++ b/src/heap.rs @@ -14,23 +14,23 @@ static ALLOCATOR: LockedHeap = LockedHeap::empty(); /// # Safety /// Must be called at most once. pub unsafe fn init() { - let heap_bottom; + let heap_start; let heap_size; // UNSAFE: This is fine, just loading some constants. unsafe { // using inline assembly is easier to access linker constants asm!( - "la {heap_bottom}, _kernel_heap_bottom", - "la {heap_size}, _kernel_heap_size", - heap_bottom = out(reg) heap_bottom, + "la {heap_start}, _heap_start", + "la {heap_size}, _heap_size", + heap_start = out(reg) heap_start, heap_size = out(reg) heap_size, options(nomem) ) }; println!( "Initialising kernel heap (bottom: {:#x}, size: {:#x})", - heap_bottom as usize, heap_size + heap_start as usize, heap_size ); // UNSAFE: Fine to call at most once. - unsafe { ALLOCATOR.lock().init(heap_bottom, heap_size) }; + unsafe { ALLOCATOR.lock().init(heap_start, heap_size) }; } diff --git a/src/script.lds b/src/script.lds index 68b1556..73a54dd 100644 --- a/src/script.lds +++ b/src/script.lds @@ -52,7 +52,7 @@ SECTIONS { PROVIDE(_memory_end = ORIGIN(ram) + LENGTH(ram)); - PROVIDE(_kernel_heap_bottom = _stack_end); # allocate heap to remaining physical memory - PROVIDE(_kernel_heap_top = ORIGIN(ram) + LENGTH(ram)); # top of heap is end of ram - PROVIDE(_kernel_heap_size = _kernel_heap_top - _kernel_heap_bottom); # capture size of heap + /* TODO Redefine heap sections */ + PROVIDE(_heap_start = _stack_end); # allocate heap to remaining physical memory + PROVIDE(_heap_size = _memory_end - _heap_start); # capture size of heap } \ No newline at end of file