C Microkernel Realtime eXecutive
Realtime Operating System for Cortex-M based microcontrollers
 
Loading...
Searching...
No Matches
RISC-V Exception Frame

Unified exception frame for RISC-V trap handlers and context switching. More...

Data Structures

struct  ExceptionFrame
 Full RISC-V trap context frame. More...
 

Macros

#define EF_RA   0
 
#define EF_T0   4
 
#define EF_T1   8
 
#define EF_T2   12
 
#define EF_A0   16
 
#define EF_A1   20
 
#define EF_A2   24
 
#define EF_A3   28
 
#define EF_A4   32
 
#define EF_A5   36
 
#define EF_A6   40
 
#define EF_A7   44
 
#define EF_T3   48
 
#define EF_T4   52
 
#define EF_T5   56
 
#define EF_T6   60
 
#define EF_S0   64
 
#define EF_S1   68
 
#define EF_S2   72
 
#define EF_S3   76
 
#define EF_S4   80
 
#define EF_S5   84
 
#define EF_S6   88
 
#define EF_S7   92
 
#define EF_S8   96
 
#define EF_S9   100
 
#define EF_S10   104
 
#define EF_S11   108
 
#define EF_MEPC   112
 
#define EF_MSTATUS   116
 
#define EXCEPTION_FRAME_SIZE   128
 Total frame size in bytes.
 
#define _RISCV_EFS(x)   #x
 
#define RISCV_EFS(x)   _RISCV_EFS(x)
 
#define SAVE_CONTEXT()
 Save application context.
 
#define LOAD_CONTEXT()
 Load application context.
 
#define EXCEPTION_FRAME_WORDS   (sizeof(ExceptionFrame) / sizeof(uint32_t))
 How many uint32_t slots the exception frame occupies.
 
#define CMRX_RISCV_INITIAL_MSTATUS   ((1u << 7) | (3u << 11))
 Initial mstatus value for newly created threads.
 

Functions

static uint32_t riscv_exception_get_arg (const ExceptionFrame *frame, unsigned argno)
 Retrieve a syscall argument from the exception frame.
 
static uint8_t riscv_exception_get_syscall_id (const ExceptionFrame *frame)
 Retrieve the syscall ID from the exception frame (a7 per RISC-V ecall ABI).
 
static void riscv_exception_set_retval (ExceptionFrame *frame, int32_t retval)
 Write the syscall return value into the exception frame (a0).
 

Detailed Description

Unified exception frame for RISC-V trap handlers and context switching.

This header defines the standard full-context frame saved on trap entry and restored on trap exit. It is the RISC-V equivalent of the ARM ExceptionFrame in cortex.h.

The layout covers all general-purpose registers that must be preserved across a trap (x1/ra, x5-x31), plus the mepc and mstatus CSRs. Registers x0 (zero), x2 (sp), x3 (gp), and x4 (tp) are excluded: x0 is hardwired to zero; sp is saved separately in the thread control block; gp and tp are program-global constants in M-mode.

The frame is 32 words (128 bytes), keeping the stack 16-byte aligned per the RISC-V psABI (riscv-abi documentation, section 2.1).

References:

  • RISC-V Privileged Specification (mepc, mstatus, mcause)
  • RISC-V psABI (register conventions, stack alignment)

Macro Definition Documentation

◆ _RISCV_EFS

#define _RISCV_EFS (   x)    #x

◆ CMRX_RISCV_INITIAL_MSTATUS

#define CMRX_RISCV_INITIAL_MSTATUS   ((1u << 7) | (3u << 11))

Initial mstatus value for newly created threads.

MPIE = 1 (bit 7): after mret, MIE is set so interrupts are enabled. MPP = 3 (bits 12:11): stay in M-mode after mret.

These are standard RISC-V privileged specification bit positions.

◆ EF_A0

#define EF_A0   16

◆ EF_A1

#define EF_A1   20

◆ EF_A2

#define EF_A2   24

◆ EF_A3

#define EF_A3   28

◆ EF_A4

#define EF_A4   32

◆ EF_A5

#define EF_A5   36

◆ EF_A6

#define EF_A6   40

◆ EF_A7

#define EF_A7   44

◆ EF_MEPC

#define EF_MEPC   112

◆ EF_MSTATUS

#define EF_MSTATUS   116

◆ EF_RA

#define EF_RA   0

◆ EF_S0

#define EF_S0   64

◆ EF_S1

#define EF_S1   68

◆ EF_S10

#define EF_S10   104

◆ EF_S11

#define EF_S11   108

◆ EF_S2

#define EF_S2   72

◆ EF_S3

#define EF_S3   76

◆ EF_S4

#define EF_S4   80

◆ EF_S5

#define EF_S5   84

◆ EF_S6

#define EF_S6   88

◆ EF_S7

#define EF_S7   92

◆ EF_S8

#define EF_S8   96

◆ EF_S9

#define EF_S9   100

◆ EF_T0

#define EF_T0   4

◆ EF_T1

#define EF_T1   8

◆ EF_T2

#define EF_T2   12

◆ EF_T3

#define EF_T3   48

◆ EF_T4

#define EF_T4   52

◆ EF_T5

#define EF_T5   56

◆ EF_T6

#define EF_T6   60

◆ EXCEPTION_FRAME_SIZE

#define EXCEPTION_FRAME_SIZE   128

Total frame size in bytes.

◆ EXCEPTION_FRAME_WORDS

#define EXCEPTION_FRAME_WORDS   (sizeof(ExceptionFrame) / sizeof(uint32_t))

How many uint32_t slots the exception frame occupies.

◆ LOAD_CONTEXT

#define LOAD_CONTEXT ( )

Load application context.

Restores all GP registers and CSRs (mepc, mstatus) from the ExceptionFrame on the current stack and pops the frame. Does NOT execute mret — the caller handles that.

Note
This is defined as a macro so it can live inside naked functions.

◆ RISCV_EFS

#define RISCV_EFS (   x)    _RISCV_EFS(x)

◆ SAVE_CONTEXT

#define SAVE_CONTEXT ( )

Save application context.

Pushes a full ExceptionFrame onto the current stack: all GP registers (ra, t0-t6, a0-a7, s0-s11) plus mepc and mstatus. Uses t0/t1 as scratch for CSR reads (they are saved beforehand).

Note
This is defined as a macro so it can live inside naked functions.

Function Documentation

◆ riscv_exception_get_arg()

static uint32_t riscv_exception_get_arg ( const ExceptionFrame frame,
unsigned  argno 
)
inlinestatic

Retrieve a syscall argument from the exception frame.

Parameters
frameexception frame pointer
argnoargument index (0-3 maps to a0-a3)

◆ riscv_exception_get_syscall_id()

static uint8_t riscv_exception_get_syscall_id ( const ExceptionFrame frame)
inlinestatic

Retrieve the syscall ID from the exception frame (a7 per RISC-V ecall ABI).

◆ riscv_exception_set_retval()

static void riscv_exception_set_retval ( ExceptionFrame frame,
int32_t  retval 
)
inlinestatic

Write the syscall return value into the exception frame (a0).