Skip to content

Commit 665ffdf

Browse files
Merge pull request #279 from rust-embedded/_default-symbols
`_default_start_trap` and `_default_setup_interrupts`
2 parents ef852e7 + a103366 commit 665ffdf

File tree

4 files changed

+31
-15
lines changed

4 files changed

+31
-15
lines changed

riscv-rt/CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3131
- Replace weak definition of `_pre_init_trap` with `PROVIDE(_pre_init_trap = _default_abort)`.
3232
- Now, `_default_abort` is 4-byte aligned (required by `_pre_init_trap`)
3333
- Removed `.init.trap` section, as it is no longer required.
34+
- Replace weak definition of `_start_trap` with `PROVIDE(_start_trap = _default_start_trap)`.
35+
- Replace weak definition of `_setup_interrupts` with `PROVIDE(_setup_interrupts = _default_setup_interrupts)`.
36+
- Now, `_default_start_trap` is 4-byte aligned instead of target width-aligned.
3437

3538
### Fixed
3639

riscv-rt/link.x.in

+15-4
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,18 @@ PROVIDE(abort = _default_abort);
3131
_pre_init_trap defaults to _default_abort. Note that _pre_init_trap must be 4-byte aligned */
3232
PROVIDE(_pre_init_trap = _default_abort);
3333

34-
/* Default trap entry point. The riscv-rt crate provides a weak alias of this function,
35-
which saves caller saved registers, calls _start_trap_rust, restores caller saved registers
36-
and then returns. Users can override this alias by defining the symbol themselves */
37-
EXTERN(_start_trap);
34+
/* Default trap entry point. If not _start_trap symbol is provided, then _start_trap maps to
35+
_default_start_trap, which saves caller saved registers, calls _start_trap_rust, restores
36+
caller saved registers and then returns. Note that _start_trap must be 4-byte aligned */
37+
EXTERN(_default_start_trap);
38+
PROVIDE(_start_trap = _default_start_trap);
39+
40+
/* Default interrupt setup entry point. If not _setup_interrupts symbol is provided, then
41+
_setup_interrupts maps to _default_setup_interrupts, which in direct mode sets the value
42+
of the xtvec register to _start_trap and, in vectored mode, sets its value to
43+
_vector_table and enables vectored mode. */
44+
EXTERN(_default_setup_interrupts);
45+
PROVIDE(_setup_interrupts = _default_setup_interrupts);
3846

3947
/* Default exception handler. By default, the exception handler is abort.
4048
Users can override this alias by defining the symbol themselves */
@@ -195,6 +203,9 @@ BUG(riscv-rt): start of .heap is not 4-byte aligned");
195203
ASSERT(_pre_init_trap % 4 == 0, "
196204
BUG(riscv-rt): _pre_init_trap is not 4-byte aligned");
197205

206+
ASSERT(_start_trap % 4 == 0, "
207+
BUG(riscv-rt): _start_trap is not 4-byte aligned");
208+
198209
ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), "
199210
ERROR(riscv-rt): The .text section must be placed inside the REGION_TEXT region.
200211
Set _stext to an address smaller than 'ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT)'");

riscv-rt/macros/src/lib.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -475,12 +475,13 @@ pub fn llvm_arch_patch(_input: TokenStream) -> TokenStream {
475475
q.into()
476476
}
477477

478-
/// Generates weak `_start_trap` function in assembly.
478+
/// Generates `_default_start_trap` function in assembly.
479+
/// If no `_start_trap` function is defined, the linker will use this function as the default.
479480
///
480481
/// This implementation stores all registers in the trap frame and calls `_start_trap_rust`.
481482
/// The trap frame is allocated on the stack and deallocated after the call.
482483
#[proc_macro]
483-
pub fn weak_start_trap(_input: TokenStream) -> TokenStream {
484+
pub fn default_start_trap(_input: TokenStream) -> TokenStream {
484485
let arch = RiscvArch::try_from_env().unwrap();
485486

486487
let width = arch.width();
@@ -504,9 +505,9 @@ pub fn weak_start_trap(_input: TokenStream) -> TokenStream {
504505
r#"
505506
core::arch::global_asm!(
506507
".section .trap, \"ax\"
507-
.align {width}
508-
.weak _start_trap
509-
_start_trap:
508+
.align 4 /* Alignment required for xtvec */
509+
.global _default_start_trap
510+
_default_start_trap:
510511
addi sp, sp, - {trap_size} * {width}
511512
{store}
512513
add a0, sp, zero

riscv-rt/src/asm.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -237,23 +237,24 @@ _mp_hook:
237237
j 1b
238238
2: li a0, 1
239239
ret",
240-
// Default implementation of `_setup_interrupts` sets the trap vector to `_start_trap`.
240+
// Default implementation of `_setup_interrupts` sets the trap vector to `_start_trap` in direct mode.
241+
// In vectored mode, it sets the trap vector to `_vector_table`.
241242
// Users can override this function by defining their own `_setup_interrupts`
242-
".weak _setup_interrupts
243-
_setup_interrupts:",
243+
".global _default_setup_interrupts
244+
_default_setup_interrupts:",
244245
#[cfg(not(feature = "v-trap"))]
245-
"la t0, _start_trap", // _start_trap is 16-byte aligned, so it corresponds to the Direct trap mode
246+
"la t0, _start_trap", // _start_trap is 4-byte aligned, so it corresponds to the Direct trap mode
246247
#[cfg(feature = "v-trap")]
247248
"la t0, _vector_table
248-
ori t0, t0, 0x1", // _vector_table is 16-byte aligned, so we must set the bit 0 to activate the Vectored trap mode
249+
ori t0, t0, 0x1", // _vector_table is at least 4-byte aligned, so we must set the bit 0 to activate the Vectored trap mode
249250
#[cfg(feature = "s-mode")]
250251
"csrw stvec, t0",
251252
#[cfg(not(feature = "s-mode"))]
252253
"csrw mtvec, t0",
253254
"ret",
254255
);
255256

256-
riscv_rt_macros::weak_start_trap!();
257+
riscv_rt_macros::default_start_trap!();
257258

258259
#[cfg(feature = "v-trap")]
259260
riscv_rt_macros::vectored_interrupt_trap!();

0 commit comments

Comments
 (0)