When to set PMP

The riscv_rt crate offers two attributes #[entry] and #[pre_init]. My current goal is to setup my PMP (physical memory protection) registers, which will envelope the main function, then enter into my main function as user level privilege and never return. Does it makes sense to do this security setup in the runtime #[pre_init] and label the main function with #[entry]? The #[pre_init] is described in the doc as

to run code *before* `static` variables are initialized

It would look something like

#![no_std]
#![no_main]

extern crate panic_halt;

use riscv_rt::{entry, pre_init};

#[pre_init]
//code to intialize PMP registers

// use `main` as the entry point of this application
// `main` is not allowed to return
#[entry]
fn main() -> ! {
    // do something here
    loop { }
}

You need to set PMP in main() and call a different “user” function from there. pre_init is definitely not a valid place to do this.

1 Like

What would be something you would use pre_init for?

Also, I don’t mean to bother you too much, but what do you think about Ferrous_Systems’ defmt? I’ve generated their template for testing. Using probe-run --list-chips I get

Generic Riscv
    Variants:
        riscv

I’m not sure if it will work, but defmt seems like it would replace sprintln! with more efficiency.

pre_init is mainly used for things like watchdog deactivation, because if you do this in main, you can easily have a giant time gap in-between. For example, on K210 chip you have 6 megabytes of RAM and this RAM is erased between pre_init and main. This may take… a while.

I haven’t used defmt, but from what I see, it uses probe-rs and in probe-rs this “Generic Riscv” is in fact HiFive1 RevB :slight_smile: So give it a try, it might work!

I gave it whirl, and was able to get all of the configuration correct for RISC-V. However, it failed to build because their app template does not support RISC-V linking. I opened an issue for it, and they said they would keep it on their radar as an enhancement feature.