I think I figured it out anyways.
Following the SiFive user-mode-example on github, they create a stack frame for user mode to use before they drop privilege.
1. create array with 16 byte alignment and initialize with zeros
2. determine the address of the end of the array (my_stack + sizeof(my_stack) in C)
3. setup mstatus appropriately
4. set the stack pointer to the address calculated in #2
Before I MRET into user mode, I added pmp configurations to encapsulate the user stack frame to prevent stack overflows. However, I was never able to enter user mode because it always trapped with a
StoreFault. Reading the stack pointer showed that it was outside of the user stack frame by a lot.
It turns out, that when I was setting the stack pointer before the MRET, I was using
&stack_ptr instead of just
stack_ptr. This fixes my problem, I probably should have posted some code before, but it is Rust code so I wan’t sure. A lot of my issues I encounter are borderline between Rust and RISC-V which makes it hard to know which forum to post my question on, plus I’m new to embedded development in general.