Przeglądaj źródła

lib: prepare programming language environment

Signed-off-by: Zhouqi Jiang <luojia@hust.edu.cn>
Zhouqi Jiang 11 miesięcy temu
rodzic
commit
7cfc12cf38
3 zmienionych plików z 117 dodań i 0 usunięć
  1. 5 0
      Cargo.toml
  2. 46 0
      build.rs
  3. 66 0
      src/main.rs

+ 5 - 0
Cargo.toml

@@ -11,6 +11,11 @@ forced-target = "riscv64imac-unknown-none-elf"
 [dependencies]
 panic-halt = "0.2.0"
 
+[[bin]]
+name = "rustsbi-prototyper"
+test = false
+bench = false
+
 [workspace]
 members = ["xtask"]
 

+ 46 - 0
build.rs

@@ -0,0 +1,46 @@
+use std::{env, path::PathBuf};
+
+fn main() {
+    let out = PathBuf::from(env::var_os("OUT_DIR").unwrap());
+    let ld = &out.join("rustsbi-prototyper.ld");
+
+    std::fs::write(ld, LINKER_SCRIPT).unwrap();
+
+    println!("cargo:rustc-link-arg=-T{}", ld.display());
+    println!("cargo:rustc-link-search={}", out.display());
+}
+
+const LINKER_SCRIPT: &[u8] = b"OUTPUT_ARCH(riscv)
+ENTRY(_start) 
+SECTIONS {
+    . = 0x80000000;
+    .text : ALIGN(8) { 
+        *(.text.entry)
+        *(.text .text.*)
+    }
+    .rodata : ALIGN(8) { 
+        srodata = .;
+        *(.rodata .rodata.*)
+        *(.srodata .srodata.*)
+        . = ALIGN(8);  
+        erodata = .;
+    } 
+    .data : ALIGN(8) { 
+        sdata = .;
+        *(.data .data.*)
+        *(.sdata .sdata.*)
+        . = ALIGN(8); 
+        edata = .;
+    }
+    sidata = LOADADDR(.data);
+    .bss (NOLOAD) : ALIGN(8) {  
+        *(.bss.uninit)
+        sbss = .;
+        *(.bss .bss.*)
+        *(.sbss .sbss.*)
+        ebss = .;
+    } 
+    /DISCARD/ : {
+        *(.eh_frame)
+    }
+}";

+ 66 - 0
src/main.rs

@@ -1,4 +1,70 @@
+#![feature(naked_functions, asm_const)]
 #![no_std]
 #![no_main]
 
 use panic_halt as _;
+
+extern "C" fn main(hart_id: usize, opaque: usize, a2: usize) -> usize {
+    let _ = (hart_id, opaque, a2);
+    0 // TODO
+}
+
+const LEN_STACK_PER_HART: usize = 16 * 1024;
+pub(crate) const NUM_HART_MAX: usize = 8;
+const LEN_STACK: usize = LEN_STACK_PER_HART * NUM_HART_MAX;
+
+// TODO contribute `Stack` struct into the crate `riscv`
+#[repr(C, align(128))]
+struct Stack<const N: usize>([u8; N]);
+
+#[link_section = ".bss.uninit"]
+static STACK: Stack<LEN_STACK> = Stack([0; LEN_STACK]);
+
+#[naked]
+#[link_section = ".text.entry"]
+#[export_name = "_start"]
+unsafe extern "C" fn start() -> ! {
+    core::arch::asm!(
+        // 1. Turn off interrupt
+        "   csrw    mie, zero",
+        // 2. Initialize programming langauge runtime
+        // only clear bss if hartid is zero
+        "   csrr    t0, mhartid",
+        "   bnez    t0, 2f",
+        // clear bss segment
+        "   la      t0, sbss
+            la      t1, ebss
+        1:  bgeu    t0, t1, 2f
+            sd      zero, 0(t0)
+            addi    t0, t0, 8
+            j       1b",
+        // prepare data segment
+        "   la      t3, sidata
+            la      t4, sdata
+            la      t5, edata
+        1:  bgeu    t4, t5, 2f
+            ld      t6, 0(t3)
+            sd      t6, 0(t4)
+            addi    t3, t3, 8
+            addi    t4, t4, 8
+            j       1b",
+        "2: ",
+        // 3. Prepare stack for each hart
+        "   la      sp, {stack}",
+        "   li      t0, {stack_size_per_hart}",
+        "   csrr    t1, mhartid",
+        "   addi    t1, t1, 1",
+        "1: ",
+        "   add     sp, sp, t0",
+        "   addi    t1, t1, -1",
+        "   bnez    t1, 1b",
+        // 4. Run Rust main function
+        "   j       {main}",
+        // 5. Jump to following boot sequences
+        "   jr      a0", // TODO
+        stack_size_per_hart = const LEN_STACK_PER_HART,
+        stack = sym STACK,
+        main = sym main,
+        options(noreturn)
+    )
+}