浏览代码

Introduce _mp_hook

Vadim Kaushan 5 年之前
父节点
当前提交
5c1bbc64e4
共有 4 个文件被更改,包括 29 次插入7 次删除
  1. 1 1
      riscv-rt/Cargo.toml
  2. 0 3
      riscv-rt/asm.S
  3. 9 0
      riscv-rt/link.x
  4. 19 3
      riscv-rt/src/lib.rs

+ 1 - 1
riscv-rt/Cargo.toml

@@ -10,7 +10,7 @@ license = "ISC"
 
 [dependencies]
 r0 = "0.2.2"
-riscv = "0.5.1"
+riscv = "0.5.3"
 riscv-rt-macros = { path = "macros", version = "0.1.5" }
 
 [features]

+ 0 - 3
riscv-rt/asm.S

@@ -73,9 +73,6 @@ _start:
     la t0, _start_trap
     csrw mtvec, t0
 
-    // Park non-zero harts
-    bnez a2, abort
-
     jal zero, _start_rust
 
     .cfi_endproc

+ 9 - 0
riscv-rt/link.x

@@ -11,6 +11,15 @@ PROVIDE(trap_handler = default_trap_handler);
    then the function this points to will be called before the RAM is initialized. */
 PROVIDE(__pre_init = default_pre_init);
 
+/* # Multi-processing hook function
+   fn _mp_hook() -> bool;
+
+   This function is called from all the harts and should return true only for one hart,
+   which will perform memory initialization. For other harts it should return false
+   and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
+*/
+PROVIDE(_mp_hook = default_mp_hook);
+
 PHDRS
 {
     load PT_LOAD;

+ 19 - 3
riscv-rt/src/lib.rs

@@ -241,12 +241,16 @@ pub unsafe extern "C" fn start_rust() -> ! {
 
         // This symbol will be provided by the user via `#[pre_init]`
         fn __pre_init();
+
+        fn _mp_hook() -> bool;
     }
 
-    __pre_init();
+    if _mp_hook() {
+        __pre_init();
 
-    r0::zero_bss(&mut _sbss, &mut _ebss);
-    r0::init_data(&mut _sdata, &mut _edata, &_sidata);
+        r0::zero_bss(&mut _sbss, &mut _ebss);
+        r0::init_data(&mut _sdata, &mut _edata, &_sidata);
+    }
 
     // TODO: Enable FPU when available
 
@@ -284,3 +288,15 @@ pub fn default_trap_handler() {}
 #[doc(hidden)]
 #[no_mangle]
 pub unsafe extern "Rust" fn default_pre_init() {}
+
+#[doc(hidden)]
+#[no_mangle]
+pub extern "Rust" fn default_mp_hook() -> bool {
+    use riscv::register::mhartid;
+    match mhartid::read() {
+        0 => true,
+        _ => loop {
+            unsafe { riscv::asm::wfi() }
+        },
+    }
+}