浏览代码

feat: compile supervisor level bootloader

Zhouqi Jiang 6 月之前
父节点
当前提交
f64f5e857b
共有 5 个文件被更改,包括 162 次插入3 次删除
  1. 40 0
      Cargo.lock
  2. 2 0
      supervisor/Cargo.toml
  3. 45 0
      supervisor/build.rs
  4. 0 3
      supervisor/src/lib.rs
  5. 75 0
      supervisor/src/main.rs

+ 40 - 0
Cargo.lock

@@ -14,6 +14,12 @@ version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
 
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
 [[package]]
 name = "critical-section"
 version = "1.1.2"
@@ -48,6 +54,27 @@ version = "0.4.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
 
+[[package]]
+name = "naked-function"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b8d5fca6ab1e6215b010aefd3b9ac5aae369dae0faea3a7f34f296cc9f719ac"
+dependencies = [
+ "cfg-if",
+ "naked-function-macro",
+]
+
+[[package]]
+name = "naked-function-macro"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b4123e70df5fe0bb370cff166ae453b9c5324a2cfc932c0f7e55498147a0475"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "panic-halt"
 version = "0.2.0"
@@ -132,6 +159,19 @@ dependencies = [
 [[package]]
 name = "rustsbi-supervisor"
 version = "0.1.0"
+dependencies = [
+ "naked-function",
+ "sbi-rt",
+]
+
+[[package]]
+name = "sbi-rt"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fbaa69be1eedc61c426e6d489b2260482e928b465360576900d52d496a58bd0"
+dependencies = [
+ "sbi-spec",
+]
 
 [[package]]
 name = "sbi-spec"

+ 2 - 0
supervisor/Cargo.toml

@@ -6,3 +6,5 @@ license.workspace = true
 repository.workspace = true
 
 [dependencies]
+naked-function = "0.1.5"
+sbi-rt = "0.0.3"

+ 45 - 0
supervisor/build.rs

@@ -0,0 +1,45 @@
+fn main() {
+    use std::{env, fs, path::PathBuf};
+
+    let ld = PathBuf::from(env::var_os("OUT_DIR").unwrap()).join("linker.ld");
+    fs::write(&ld, LINKER).unwrap();
+    println!("cargo:rerun-if-changed=build.rs");
+    println!("cargo:rerun-if-env-changed=LOG");
+    println!("cargo:rustc-link-arg=-T{}", ld.display());
+}
+
+const LINKER: &[u8] = b"
+OUTPUT_ARCH(riscv)
+ENTRY(_start)
+MEMORY {
+    RAM : ORIGIN = 0x0, LENGTH = 64M
+}
+SECTIONS {
+    .text : {
+        *(.text.entry)
+        *(.text .text.*)
+    } > RAM
+    .rodata : {
+        *(.rodata .rodata.*)
+        *(.srodata .srodata.*)
+    } > RAM
+    .data : {
+        sidata = LOADADDR(.data);
+        sdata = .;
+        *(.data .data.*)
+        *(.sdata .sdata.*)
+        edata = .;
+    } > RAM
+    .bss (NOLOAD) : {
+        *(.bss.uninit)
+        . = ALIGN(8);
+        sbss = .;
+        *(.bss .bss.*)
+        *(.sbss .sbss.*)
+        . = ALIGN(8);
+        ebss = .;
+    } > RAM
+    /DISCARD/ : {
+        *(.eh_frame)
+    }
+}";

+ 0 - 3
supervisor/src/lib.rs

@@ -1,3 +0,0 @@
-#![no_std]
-
-// TODO: RustSBI EFI module

+ 75 - 0
supervisor/src/main.rs

@@ -0,0 +1,75 @@
+#![no_std]
+#![no_main]
+
+// TODO: RustSBI EFI module
+#[no_mangle]
+extern "C" fn rust_main(_hart_id: usize, _opaque: usize) {
+    // TODO
+}
+
+#[no_mangle]
+extern "C" fn rust_sbi_exit() -> ! {
+    sbi_rt::system_reset(sbi_rt::Shutdown, sbi_rt::NoReason);
+    loop {
+        core::hint::spin_loop();
+    }
+}
+
+#[panic_handler]
+fn panic(_info: &core::panic::PanicInfo) -> ! {
+    // TODO panic handler
+    loop {
+        core::hint::spin_loop();
+    }
+}
+
+const LEN_STACK_PER_HART: usize = 16 * 1024;
+pub const NUM_HART_MAX: usize = 8;
+#[link_section = ".bss.uninit"]
+static mut STACK: [u8; NUM_HART_MAX * LEN_STACK_PER_HART] = [0; NUM_HART_MAX * LEN_STACK_PER_HART];
+
+// If booted with RISC-V SBI, a0 must include hart ID, while a1 must be an opaque register
+#[naked_function::naked]
+#[link_section = ".text.entry"]
+#[export_name = "_start"]
+unsafe extern "C" fn start() -> ! {
+    asm!(
+        // 1. Turn off interrupt
+        "   csrw    sie, zero",
+        // 2. Initialize programming langauge runtime
+        // only initialize if it is boot hart (hart ID 0)
+        "   bnez    a0, 3f",
+        // clear bss segment
+        "   la      t0, sbss
+            la      t1, ebss
+        2:  bgeu    t0, t1, 2f
+            sd      zero, 0(t0)
+            addi    t0, t0, 8
+            j       2b",
+        // prepare data segment
+        "   la      t3, sidata
+            la      t4, sdata
+            la      t5, edata
+        2:  bgeu    t4, t5, 2f
+            ld      t6, 0(t3)
+            sd      t6, 0(t4)
+            addi    t3, t3, 8
+            addi    t4, t4, 8
+            j       2b",
+        "3:",
+        // 3. Prepare stack for each hart
+        "   la      sp, {stack}
+            li      t1, {per_hart_stack_size}
+            addi    t2, a0, 1
+        2:  add     sp, sp, t1
+            addi    t2, t2, -1
+            bnez    t2, 2b",
+        // 4. Start main function
+        "   call    {main}",
+        "   call    {exit}",
+        stack = sym STACK,
+        per_hart_stack_size = const LEN_STACK_PER_HART,
+        main = sym rust_main,
+        exit = sym rust_sbi_exit
+    )
+}