rust-embedded / riscv

Low level access to RISC-V processors
841 stars 162 forks source link

`riscv-rt`: Pre initialization trap handling #156

Closed piegamesde closed 7 months ago

piegamesde commented 2 years ago

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:

Disasm commented 2 years 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.

piegamesde commented 2 years ago

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.