From a906d89cc18a3fa2d7919976022923056a2db197 Mon Sep 17 00:00:00 2001 From: Kevin Vigor Date: Thu, 2 Nov 2023 10:24:56 -0600 Subject: [PATCH 1/5] Ignore hartid in single-hart mode. Don't bother checking hart ID on startup in single-hart mode. Allows use of cores with unusual mhartid values and saves a few instructions. --- CHANGELOG.md | 1 + src/lib.rs | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a68160..c3557b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Removed bors in favor of GitHub Merge Queue - `start_trap_rust` is now marked as `unsafe` - Implement `r0` as inline assembly +- mhartid CSR is no longer read in single-hart mode, assumed zero ## [v0.11.0] - 2023-01-18 diff --git a/src/lib.rs b/src/lib.rs index 3e86c49..422f3f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -372,7 +372,10 @@ use core::sync::atomic::{compiler_fence, Ordering}; use riscv::register::{scause as xcause, stvec as xtvec, stvec::TrapMode as xTrapMode}; #[cfg(not(feature = "s-mode"))] -use riscv::register::{mcause as xcause, mhartid, mtvec as xtvec, mtvec::TrapMode as xTrapMode}; +use riscv::register::{mcause as xcause, mtvec as xtvec, mtvec::TrapMode as xTrapMode}; + +#[cfg(all(not(feature = "single-hart"), not(feature = "s-mode")))] +use riscv::register::mhartid; pub use riscv_rt_macros::{entry, pre_init}; @@ -404,13 +407,20 @@ pub unsafe extern "C" fn start_rust(a0: usize, a1: usize, a2: usize) -> ! { fn _mp_hook(hartid: usize) -> bool; } - // sbi passes hartid as first parameter (a0) - #[cfg(feature = "s-mode")] - let hartid = a0; - #[cfg(not(feature = "s-mode"))] - let hartid = mhartid::read(); + #[cfg(not(feature = "single-hart"))] + let run_init = { + // sbi passes hartid as first parameter (a0) + #[cfg(feature = "s-mode")] + let hartid = a0; + #[cfg(not(feature = "s-mode"))] + let hartid = mhartid::read(); + + _mp_hook(hartid) + }; + #[cfg(feature = "single-hart")] + let run_init = true; - if _mp_hook(hartid) { + if run_init { __pre_init(); // Initialize RAM @@ -661,6 +671,7 @@ pub unsafe extern "Rust" fn default_pre_init() {} #[doc(hidden)] #[no_mangle] #[rustfmt::skip] +#[cfg(not(feature = "single-hart"))] pub extern "Rust" fn default_mp_hook(hartid: usize) -> bool { match hartid { 0 => true, From 93f2bba6e2373a551649db8979c1cf7b6adb5134 Mon Sep 17 00:00:00 2001 From: Chien Wong Date: Fri, 10 Nov 2023 19:16:42 +0800 Subject: [PATCH 2/5] Fix setting incorrect sp if single-hart If single-hart is enabled, the sp is set to _stack_start - _hart_stack_size, rather than _stack_start. Fix this. Fixes: 9a02223ac3b6 ("Add feature single-hart") Signed-off-by: Chien Wong --- src/asm.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/asm.rs b/src/asm.rs index c29d918..a0af873 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -85,7 +85,8 @@ _abs_start: .option push .option norelax la gp, __global_pointer$ - .option pop", + .option pop + // Allocate stacks", #[cfg(all(not(feature = "single-hart"), feature = "s-mode"))] "mv t2, a0 // the hartid is passed as parameter by SMODE", #[cfg(all(not(feature = "single-hart"), not(feature = "s-mode")))] @@ -93,9 +94,7 @@ _abs_start: #[cfg(not(feature = "single-hart"))] "lui t0, %hi(_max_hart_id) add t0, t0, %lo(_max_hart_id) - bgtu t2, t0, abort", - "// Allocate stacks - la sp, _stack_start + bgtu t2, t0, abort lui t0, %hi(_hart_stack_size) add t0, t0, %lo(_hart_stack_size)", #[cfg(all(not(feature = "single-hart"), riscvm))] @@ -109,9 +108,10 @@ _abs_start: addi t1, t1, -1 bnez t1, 1b 2: ", - "sub sp, sp, t0 - - // Set frame pointer + "la sp, _stack_start", + #[cfg(not(feature = "single-hart"))] + "sub sp, sp, t0", + "// Set frame pointer add s0, sp, zero jal zero, _start_rust From 13364069ace221c01991f2b2bc8a2337ab1b74ba Mon Sep 17 00:00:00 2001 From: Chien Wong Date: Fri, 10 Nov 2023 19:20:40 +0800 Subject: [PATCH 3/5] Add 'single-hart' changelog entry Signed-off-by: Chien Wong --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3557b3..5e022be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - New GitHub workflow for checking invalid labels in PRs - New GitHub workflow for checking modifications on CHANGELOG.md - New GitHub workflow for checking clippy lints in PRs +- Optional cargo feature `single-hart` for single CPU targets ### Changed From 97f9b6a3c5c2542f1eb01713898e9bd05034faf9 Mon Sep 17 00:00:00 2001 From: Chien Wong Date: Fri, 10 Nov 2023 19:23:53 +0800 Subject: [PATCH 4/5] Update doc on single-hart Signed-off-by: Chien Wong --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 422f3f2..54e5c01 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -327,7 +327,7 @@ //! //! ## `single-hart` //! -//! This feature saves a little code size by removing unnecessary stack space calculation if there is only one hart on the target. +//! This feature saves a little code size if there is only one hart on the target. //! //! ## `s-mode` //! From 30c1b93c3a4871f8432ef17e78de9993e4522b21 Mon Sep 17 00:00:00 2001 From: Chien Wong Date: Fri, 10 Nov 2023 20:44:57 +0800 Subject: [PATCH 5/5] Ensure sp is 16-byte aligned Signed-off-by: Chien Wong --- CHANGELOG.md | 1 + src/asm.rs | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e022be..70178bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `start_trap_rust` is now marked as `unsafe` - Implement `r0` as inline assembly - mhartid CSR is no longer read in single-hart mode, assumed zero +- Ensure stack pointer is 16-byte aligned before jumping to Rust entry point ## [v0.11.0] - 2023-01-18 diff --git a/src/asm.rs b/src/asm.rs index a0af873..0eedebe 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -108,10 +108,11 @@ _abs_start: addi t1, t1, -1 bnez t1, 1b 2: ", - "la sp, _stack_start", + "la t1, _stack_start", #[cfg(not(feature = "single-hart"))] - "sub sp, sp, t0", - "// Set frame pointer + "sub t1, t1, t0", + "andi sp, t1, -16 // Force 16-byte alignment + // Set frame pointer add s0, sp, zero jal zero, _start_rust @@ -135,6 +136,8 @@ _abs_start: #[rustfmt::skip] macro_rules! trap_handler { ($STORE:ident, $LOAD:ident, $BYTES:literal, $TRAP_SIZE:literal, [$(($REG:ident, $LOCATION:literal)),*]) => { + // ensure we do not break that sp is 16-byte aligned + const _: () = assert!(($TRAP_SIZE * $BYTES) % 16 == 0); global_asm!( " .section .trap, \"ax\"