riscv-rust / riscv-crates

A workspace for hacking on riscv crates
13 stars 0 forks source link

examples/blinky_clint.rs does not work properly #5

Open irandms opened 5 years ago

irandms commented 5 years ago

Hello,

I'm working on a project using the FE310 as a controller for a simple phone and I've been using this repo as a resource for learning Rust/embedded Rust specifically, and I've noticed that this example doesn't work as-is on my HiFive1 board; I've found that the way that the MTIMECMP register is set is incompatible with how the MachineTimer interrupt works, as the current code under examples/blinky_clint.rs tries to set the MTIMECMP register outside of the trap handler; this causes a problem because as soon as trap_handler finishes execution, control would be returned to main, but I've found that an interrupt storm occurs instead, as the value within MTIMECMP is greater than MTIME, causing the interrupt pending bit to stay set.

I have a potential fix, but I'm not extremely familiar with Rust, so it is kind of hacky - using a global variable to the MTIMECMP register to call set_mtimecmp from within trap_handler. The fix can be found here, and I'm welcome to any advice on how to make it more Rust-y: https://github.com/irandms/riscv-phone-sw/blob/master/examples/blinky_clint.rs#L68

I'm not 100% sure if this bug is unique to my hardware or not, as I only have the one board right now. If anyone else has a HiFive1 and can try and confirm the behavior of this example, I'd be glad to hear it.

Disasm commented 5 years ago

Thanks! I will try to reproduce this. According to the RISC-V priv spec v1.9 this behavior is expected:

Platforms provide a 64-bit memory-mapped machine-mode timer compare register (mtimecmp), which causes a timer interrupt to be posted when the mtime register contains a value greater than or equal to the value in the mtimecmp register. The interrupt remains posted until it is cleared by writing the mtimecmp register.