Closed piegamesde closed 7 months ago
Code compiled for the wrong target will not work on the other target, this is expected.
Simply hardcode the non-mul branch in the asm.S
Why? The mul branch works perfectly fine on targets that have M extension.
Going one step further, I suggest compiling asm.S for the rv32i and rv64i targets only
This will not work anyway since there are multiple ABIs and targets with floating point require binaries with a different ABI.
Alternatively, define a pre-Rust trap handler which is initialized first in _start
What this handler would do? It's called before memory initialization and using it from Rust is extremely dangerous.
What this handler would do?
j abort
for example.
It's called before memory initialization and using it from Rust is extremely dangerous.
It's not called "pre-Rust" without a reason. It's implementation must not be written in Rust. It will be replaced with the actual Rust trap handling after the initialization.
At the moment, the trap handler is initialized rather late in the boot procedure (it is more or less the last thing to happen before jumping to
main
). However, traps may happen before this, and they will not be handled appropriately (as far as I can tell, my CPU lands in a reset loop).The most prominent situation in which this may happen is when I accidentally run the software compiled with multiplication instructions on a machine without them, because of these lines: https://github.com/rust-embedded/riscv-rt/blob/master/asm.S#L99-L110
I see multiple different approaches to improve the current situation:
asm.S
. Since the factor against we are multiplying is rather low (it's the number of harts of the machine), the run time overhead shouldn't hit that hard.asm.S
for therv32i
andrv64i
targets only. Most of these extensions aren't needed anyways during initialization._start
. Once the Rust runtime is ready,default_setup_interrupts
will override it to the actual implementation.