The RISC-V current SW privilege level is not set in any CSR. Nevertheless the spec states that "Attempts to access a CSR without appropriate privilege level ... raise illegal instruction". How can it be implemented then (in the HW)?
Well, on interrupts - "xPP holds the previous privilege mode (x=M,S or U). The xPP fields can only hold privilege modes up to x, so MPP is two bits wide, SPP is one bit wide, and UPP is implicitly zero."
Actually, what I have found now is that the xRET instruction enables the processor to store (internally) the current mode - "The MRET, SRET, or URET instructions are used to return from traps in M-mode, S-mode, or U-mode respectively. When executing an xRET instruction, supposing xPP holds the value y, x IE is set to x PIE; the privilege mode is changed to y; x PIE is set to 1; and xPP is set to U (or M if user-mode is not supported)."
I found this answer from sifive forums quite helpful when I was looking for the same question.
RISC-V deliberately doesn’t make it easy for code to discover what mode it is running it because this is a virtualisation hole. As a general principle, code should be designed for and implicitly know what mode it will run in. Applications code should assume it is in U mode. The operating system should assume it is in S mode (it might in fact be virtualised and running in U mode, with things U mode can’t do trapped and emulated by the hypervisor).
https://forums.sifive.com/t/how-to-determine-the-current-execution-privilege-mode/2823
The privilege level is reflected in the MPP bits of the mstatus register.
We have mstatus.mPP. that holdS the previous privilege mode. Current privilege mode is not visible to software.
on interrupt the mstatus.mPP is saved to mcause.mPP.. on mrwt, its just written back to mstatus.mPP.
You can't use mstatus.MPP
because you can only read mstatus
in Machine mode anyway. You'll get an illegal instruction exception in other modes.
Anyway you would need to check mstatus.SPP
too and magically know whether mret
or sret
was executed.
One option is to try to read mstatus
and sstatus
and see if you get an illegal instruction exception. However that is quite tricky to deal with. You need control over the trap handler.
If you already have control over the trap handler it is much simpler just to add a syscall that inspects mcause
. mcause
has different values for ecall
s from User, Supervisor and Machine mode, so you can simply return the mode that executed the ecall
.
© 2022 - 2024 — McMap. All rights reserved.