I am trying to use PMP on a 16-byte region to protect a specific memory region. However, I am getting an instruction access fault when jumping to U mode when the PMP configuration is enabled.
Details:
My program starts in M mode and at some point jump to U mode using mret. I am not using virtual memory for this test.
Memory region that I want to protect starts at 0x80020180.
I set the pmpaddr0 to 0x20008061 (right shift 0x80020180 by 2 and make the last two digits 0b'01 to mark the 16-byte region).
pmp0cfg is set to 0b'0001 1000 (NAPOT is used and read, write, execute is not permitted).
I have a store operation that tries to store to 0x80020184 in U mode. But the code gives instruction access fault when jumping to the U mode.
The first instruction in U mode is located at PC 0x800004c0, which should not match with the pmpaddr0.
I am trying to figure out why it is giving instruction access fault when jumping to U mode. Could anyone please help me to understand what's happening?
I am running my code on Spike, I am seeing the same behavior on rocket-core simulation as well.
I found the answer to my own question, posting as thin might help someone else.
It turns out I missed an important sentence in the spec about the PMP priority.
If no PMP entry matches an M-mode access, the access succeeds. If no PMP entry matches an
S-mode or U-mode access, but at least one PMP entry is implemented, the access fails.
So I had to add a second PMP entry to match all addresses in U mode and that solved the issue.