Browse Source

Merge branch 'riscv-rt-asm' of github.com:rust-embedded/riscv into riscv-rt-asm

Román Cárdenas Rodríguez 1 year ago
parent
commit
eb03dd0c74
2 changed files with 112 additions and 0 deletions
  1. 8 0
      riscv-rt/CHANGELOG.md
  2. 104 0
      riscv-rt/src/asm.rs

+ 8 - 0
riscv-rt/CHANGELOG.md

@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 
 ## [Unreleased]
 
+### Changed
+
+- Moved all the assembly code to `asm.rs`
+
+### Removed
+
+- start_rust is no longer needed, as it is now wrtten in assembly
+
 ## [v0.12.1] - 2024-01-24
 
 ### Added

+ 104 - 0
riscv-rt/src/asm.rs

@@ -203,6 +203,110 @@ riscv_rt_macros::loop_global_asm!("    fmv.d.x f{}, x0", 32);
 #[cfg(all(riscvf, not(riscvd)))]
 riscv_rt_macros::loop_global_asm!("    fmv.w.x f{}, x0", 32);
 
+// SET UP INTERRUPTS, RESTORE a0..a2, AND JUMP TO MAIN RUST FUNCTION
+cfg_global_asm!(
+    "call _setup_interrupts",
+    #[cfg(riscv32)]
+    "lw a0, 4 * 0(sp)
+    lw a1, 4 * 1(sp)
+    lw a2, 4 * 2(sp)
+    addi sp, sp, 4 * 3",
+    #[cfg(riscv64)]
+    "ld a0, 8 * 0(sp)
+    ld a1, 8 * 1(sp)
+    ld a2, 8 * 2(sp)
+    addi sp, sp, 8 * 3",
+    "jal zero, main
+    "andi sp, t1, -16 // align stack to 16-bytes
+    add s0, sp, zero",
+);
+
+// STORE A0..A2 IN THE STACK, AS THEY WILL BE NEEDED LATER BY main
+cfg_global_asm!(
+    #[cfg(riscv32)]
+    "addi sp, sp, -4 * 3
+    sw a0, 4 * 0(sp)
+    sw a1, 4 * 1(sp)
+    sw a2, 4 * 2(sp)",
+    #[cfg(riscv64)]
+    "addi sp, sp, -8 * 3
+    sd a0, 8 * 0(sp)
+    sd a1, 8 * 1(sp)
+    sd a2, 8 * 2(sp)",
+);
+
+// SKIP RAM INITIALIZATION IF CURRENT HART IS NOT THE BOOT HART
+#[cfg(not(feature = "single-hart"))]
+cfg_global_asm!(
+    #[cfg(not(feature = "s-mode"))]
+    "csrr a0, mhartid",
+    "call _mp_hook
+    mv t0, a0
+
+    beqz a0, 4f",
+);
+// IF CURRENT HART IS THE BOOT HART CALL __pre_init AND INITIALIZE RAM
+cfg_global_asm!(
+    "call __pre_init
+    // Copy .data from flash to RAM
+    la t0, _sdata
+    la t2, _edata
+    la t1, _sidata
+    bgeu t0, t2, 2f
+1:  ",
+    #[cfg(target_arch = "riscv32")]
+    "lw t3, 0(t1)
+    addi t1, t1, 4
+    sw t3, 0(t0)
+    addi t0, t0, 4
+    bltu t0, t2, 1b",
+    #[cfg(target_arch = "riscv64")]
+    "ld t3, 0(t1)
+    addi t1, t1, 8
+    sd t3, 0(t0)
+    addi t0, t0, 8
+    bltu t0, t2, 1b",
+    "
+2:  // Zero out .bss
+    la t0, _sbss
+    la t2, _ebss
+    bgeu  t0, t2, 4f
+3:  ",
+    #[cfg(target_arch = "riscv32")]
+    "sw  zero, 0(t0)
+    addi t0, t0, 4
+    bltu t0, t2, 3b",
+    #[cfg(target_arch = "riscv64")]
+    "sd zero, 0(t0)
+    addi t0, t0, 8
+    bltu t0, t2, 3b",
+    "
+4: // RAM initilized",
+);
+
+// INITIALIZE FLOATING POINT UNIT
+#[cfg(any(riscvf, riscvd))]
+cfg_global_asm!(
+    "
+    li t0, 0x4000 // bit 14 is FS most significant bit
+    li t2, 0x2000 // bit 13 is FS least significant bit
+    ",
+    #[cfg(feature = "s-mode")]
+    "csrrc x0, sstatus, t0
+    csrrs x0, sstatus, t2",
+    #[cfg(not(feature = "s-mode"))]
+    "csrrc x0, mstatus, t0
+    csrrs x0, mstatus, t2",
+    "fscsr x0",
+);
+// ZERO OUT FLOATING POINT REGISTERS
+#[cfg(all(riscv32, riscvd))]
+riscv_rt_macros::loop_global_asm!("    fcvt.d.w f{}, x0", 32);
+#[cfg(all(riscv64, riscvd))]
+riscv_rt_macros::loop_global_asm!("    fmv.d.x f{}, x0", 32);
+#[cfg(all(riscvf, not(riscvd)))]
+riscv_rt_macros::loop_global_asm!("    fmv.w.x f{}, x0", 32);
+
 // SET UP INTERRUPTS, RESTORE a0..a2, AND JUMP TO MAIN RUST FUNCTION
 cfg_global_asm!(
     "call _setup_interrupts",