diff --git a/.cargo/config.toml b/.cargo/config.toml index c7c38b4..72f0ac0 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -24,4 +24,5 @@ runner = """ qemu-system-riscv64 -s -nographic -serial mon:stdio - -bios """ \ No newline at end of file + -bios none + -kernel """ \ No newline at end of file diff --git a/build.rs b/build.rs index 3165444..c859a73 100644 --- a/build.rs +++ b/build.rs @@ -2,7 +2,7 @@ fn main() { // Tell ld to use linker script. - println!("cargo::rustc-link-arg=-Tsrc/script.lds"); + println!("cargo::rustc-link-arg=-Tlds/kernel.lds"); // Don't do any magic linker stuff. println!("cargo::rustc-link-arg=--omagic"); } diff --git a/src/script.lds b/lds/kernel.lds similarity index 99% rename from src/script.lds rename to lds/kernel.lds index 4d94276..242ed20 100644 --- a/src/script.lds +++ b/lds/kernel.lds @@ -1,7 +1,7 @@ /* src/script.lds */ OUTPUT_ARCH("riscv") -ENTRY(_enter) +ENTRY(_entry) MEMORY { ram (wxa) : ORIGIN = 0x80000000, LENGTH = 128M diff --git a/src/entry.S b/src/entry.S new file mode 100644 index 0000000..37cbd36 --- /dev/null +++ b/src/entry.S @@ -0,0 +1,43 @@ +# entry.S +.option norvc +.section .data + +.section .text.init +.global _entry +_entry: + # Any hardware threads (hart) that are not bootstrapping + # need to wait for an IPI + csrr t0, mhartid + bnez t0, 3f + + # SATP should be zero, but let's make sure + csrw satp, zero + +.option push +.option norelax + la gp, _global_pointer +.option pop + + li t5, 0xffff + csrw medeleg, t5 + csrw mideleg, t5 + + la sp, _stack_end + + li t0, (0b11 << 11) | (1 << 7) | (1 << 3) + csrw mstatus, t0 + + 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: + j 4f +3: + wfi + j 3b +4: + tail start \ No newline at end of file diff --git a/src/entry.rs b/src/entry.rs index e075f2b..4f17779 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -56,16 +56,6 @@ unsafe extern "C" fn entry() { ); } -#[no_mangle] -extern "C" fn start() { - // TODO start (start for hart 0) -} - -#[no_mangle] -extern "C" fn hstart() { - // TODO starth (start for other harts) -} - // TODO ...then kinit #[no_mangle] diff --git a/src/main.rs b/src/main.rs index 5bf3808..eb30fea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,79 +10,9 @@ mod heap; mod trap; mod uart; -#[naked] +core::arch::global_asm!(include_str!("entry.S")); + #[no_mangle] -#[link_section = ".text.init"] -unsafe extern "C" fn _enter() -> ! { - // FIXME see if possible to replace this somehow... - use core::arch::asm; - asm!( - // load hartid into `tp`` - // if hartid =/= 0, then jump to busy loop - "csrr tp, mhartid", - "bnez tp, 3f", - - // before we use the `la` pseudo-instruction for the first time, - // we need to set `gp` (look up linker relaxation) - ".option push", // pushes the current option stack - ".option norelax", // disable relaxation so we can properly set `gp` - // this instruction compiles to: - // 1: - // auipc gp, %pcrel_hi(_global_pointer) - // addi gp, gp, %pcrel_lo(1b) - // if relaxation were on, this would simply be `mv gp, gp` or `addi gp, gp, 0` - "la gp, _global_pointer", - ".option pop", // pops the current option stack - - // delegate all traps to S-mode trap handler - "li t5, 0xffff", - "csrw medeleg, t5", // delegate all machine exceptions - "csrw mideleg, t5", // delegate all machine interrupts - - // set the stack pointer - "la sp, _stack_end", - - // Make sure machine mode is set, and enable coarse interrupts - "li t0, (0b11 << 11) | (1 << 7) | (1 << 3)", - "csrw mstatus, t0", - - // Set mtvec to the location of our trap handler function - "la t1, {trap_vector}", - "csrw mtvec, t1", - - // Set MSIE, MTIE, and MEIE on machine interrupt enable CSR: - // (1 << 3) = MSIE to enable machine-/M-mode software interrupts - // | (1 << 7) = MTIE to enable M-mode timer interrupts (disabled for now) - // | (1 << 11) = MEIE to enable M-mode external interrupts - "li t2, (1 << 3) | (1 << 11)", - "csrw mie, t2", - - // clear the BSS - "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:", - "j 4f", - // BSS is clear! - - // busy loop if hartid =/= 0 - "3:", - "wfi", // wait for interrupt (or nop) - "j 3b", - - "4:", - // "tail-call" to {start} (call without saving a return address) - "tail {start}", - start = sym start, // {start} refers to the function [start] below - trap_vector = sym trap::trap_handler, // {trap_vector} refers to function [trap::trap_handler] - options(noreturn) // we must handle "returning" from assembly - ); -} - extern "C" fn start() -> ! { // UNSAFE: Called exactly once, right here. unsafe { heap::init() }; @@ -125,4 +55,4 @@ extern "C" fn abort() -> ! { loop { riscv::asm::wfi(); } } -// TODO unit testing +// TODO unit testing \ No newline at end of file