Basic doubts regarding RISCV Privilege specification

448 views
Skip to first unread message

Abhinaya Agrawal

unread,
Oct 10, 2016, 8:05:31 AM10/10/16
to isa...@groups.riscv.org
Hi all,

I am working on a simple RV32 based core. I had a few queries regarding the implementation of CSRs for  my design that I am listing below:

1. How does the execution pass to a less privileged mode? My doubt here is that the execution begins with the machine being in M-mode. If an application has to be run in (say) U-mode, how is this done? Migration from lower privilege mode to a higher privilege mode can be done through traps but the opposite is not true. I am assuming that this is done by the M-mode code which may manipulate the MPP and MPIE fields in the MSTATUS register and then call MRET.

2. When a *RET instruction is called, the stack must be popped and the bottom of the stack is set to the least privileged mode with interrupts enabled. Does this mean that the reset value of MPP field must be 0 and MPIE be 1 so as to cater to the case when the execution starts in machine mode on reset and a faulty MRET is called? Also, once the the least privileged mode is reached, will this always be now the bottom of the stack (until reset)? I am assuming that this will be the case and execution will pass to other privilege modes only to handle traps and then return back to the least privilege mode eventually.

3. What happens when an ECALL is executed? All I know is that an Environment Call Exception corresponding to the current privilege level is generated and a trap handler is called. Can someone please briefly give me an insight as to what is done by this trap handler or redirect me to a blog/article/document where I can read more about this?

I would greatly appreciate it if someone could help me out with these or tell where I can read more about it.

Thanks,
Abhinaya Agrawal

Stefan O'Rear

unread,
Oct 11, 2016, 11:17:30 PM10/11/16
to Abhinaya Agrawal, RISC-V ISA Dev
On Mon, Oct 10, 2016 at 5:05 AM, Abhinaya Agrawal
<agrawal....@gmail.com> wrote:
> Hi all,
>
> I am working on a simple RV32 based core. I had a few queries regarding the
> implementation of CSRs for my design that I am listing below:
>
> 1. How does the execution pass to a less privileged mode?

Use MRET.

> My doubt here is
> that the execution begins with the machine being in M-mode. If an
> application has to be run in (say) U-mode, how is this done?

Most ISAs require you to set up a fictitious exception frame and then
"return" from it in order to enter user mode for the first time.
RISC-V is not unusual here.

> Migration from
> lower privilege mode to a higher privilege mode can be done through traps
> but the opposite is not true. I am assuming that this is done by the M-mode
> code which may manipulate the MPP and MPIE fields in the MSTATUS register
> and then call MRET.

Yes.

> 2. When a *RET instruction is called, the stack must be popped and the
> bottom of the stack is set to the least privileged mode with interrupts
> enabled. Does this mean that the reset value of MPP field must be 0 and MPIE
> be 1 so as to cater to the case when the execution starts in machine mode on
> reset and a faulty MRET is called?

No, you don't need to cater for a faulty monitor. If the monitor
calls MRET at the wrong time, it's the monitor's problem, not yours.

> Also, once the the least privileged mode
> is reached, will this always be now the bottom of the stack (until reset)? I

Until you change the CSRs so that it isn't. IMO it's not terribly
useful to think of the previous-mode bits as a stack.

> am assuming that this will be the case and execution will pass to other
> privilege modes only to handle traps and then return back to the least
> privilege mode eventually.
>
> 3. What happens when an ECALL is executed? All I know is that an Environment
> Call Exception corresponding to the current privilege level is generated and
> a trap handler is called. Can someone please briefly give me an insight as
> to what is done by this trap handler or redirect me to a

Trap handler emulates the system call and then adds 4 to MEPC so that
execution will continue at the next instruction.

Curious fact: except for the value written into *ECAUSE, ECALL is
functionally equivalent to an illegal instruction. Classic Mac OS
used the illegal instruction trap for system calls; almost any trap
can be pressed into this role.

> blog/article/document where I can read more about this?

This is an extremely general kernel programming question. Searching
"what happens in a system call" turns up a bunch of results, none of
which are terribly useful. There are probably books. Maybe take a
look at https://pdos.csail.mit.edu/6.828/2014/xv6/book-rev8.pdf#page=42
or thereabouts.

Basically you save registers, go to C code, the C code executes a
system call, then restore registers and MRET.

> I would greatly appreciate it if someone could help me out with these or
> tell where I can read more about it.

-s

Alex Elsayed

unread,
Oct 11, 2016, 11:23:40 PM10/11/16
to isa...@groups.riscv.org
On Tuesday, 11 October 2016 20:17:25 PDT Stefan O'Rear wrote:
> On Mon, Oct 10, 2016 at 5:05 AM, Abhinaya Agrawal
>
> <agrawal....@gmail.com> wrote:

<snip>

> > am assuming that this will be the case and execution will pass to other
> > privilege modes only to handle traps and then return back to the least
> > privilege mode eventually.
> >
> > 3. What happens when an ECALL is executed? All I know is that an
> > Environment Call Exception corresponding to the current privilege level
> > is generated and a trap handler is called. Can someone please briefly
> > give me an insight as to what is done by this trap handler or redirect me
> > to a
>
> Trap handler emulates the system call and then adds 4 to MEPC so that
> execution will continue at the next instruction.
>
> Curious fact: except for the value written into *ECAUSE, ECALL is
> functionally equivalent to an illegal instruction. Classic Mac OS
> used the illegal instruction trap for system calls; almost any trap
> can be pressed into this role.

Yup. Original L4 on x86 used LOCK NOP, so as to avoid whatever sequences
_other_ kernels used, and make virtualizing their programs easier.

> > blog/article/document where I can read more about this?
>
> This is an extremely general kernel programming question. Searching
> "what happens in a system call" turns up a bunch of results, none of
> which are terribly useful. There are probably books. Maybe take a
> look at https://pdos.csail.mit.edu/6.828/2014/xv6/book-rev8.pdf#page=42
> or thereabouts.
>
> Basically you save registers, go to C code, the C code executes a
> system call, then restore registers and MRET.

At one point, LWN did an exemplary pair of articles titled "Anatomy of a
System Call" - it's somewhat Linux-focused, but it contains pretty much all of
the relevant information.

Part 1: https://lwn.net/Articles/604287/
Part 2: https://lwn.net/Articles/604515/


Reply all
Reply to author
Forward
0 new messages