I have been studying the RISC-V architecture for some time, and I have summarized some essential knowledge points for beginners in RISC-V, which I would like to share with new learners.
What is RISC-V?
The most commonly heard processor architectures are probably x86 and ARM. The x86 architecture is mainly used in PCs, while ARM is primarily used in mobile devices. Those learning embedded systems are certainly familiar with ARM, but since ARM is foreign, designing a chip based on the ARM architecture requires authorization from ARM, which incurs costs. This raises a question: what if one day ARM does not grant authorization?

The RISC-V architecture was created to solve this problem! RISC-V originated in 2010 at the University of California, Berkeley. Frustrated with the complexity of existing processor architectures and the limitations of related intellectual property, Berkeley decided to invent a completely new, simple, and open-source
instruction set architecture.

As the name suggests, RISC-V is the fifth generation of the RISC instruction set architecture. The goal of RISC-V is to “become a completely open instruction set architecture that can be freely used by any academic institution or commercial organization.”
Development of RISC-V
The RISC-V Foundation was established in 2015 as a non-profit organization primarily to maintain and develop RISC-V.
Currently, most of the IP suppliers for RISC-V are domestic companies, such as SiFive, Alibaba Tsinghua Unigroup, Andes, and so on. The chip manufacturers based on the RISC-V architecture are also mostly domestic.
It can be seen that chips designed based on the RISC-V architecture do not have the various restrictions like ARM’s authorization, allowing for greater autonomy and control. However, since RISC-V is still in the development stage, there are many areas that are not yet perfect. There are rumors that in the future, a tripartite balance may form among x86, ARM, and RISC-V, but whether this situation can be achieved will require everyone’s joint efforts.
RISC-V Instruction Set
The RISC-V instruction set consists of a “base instruction set + extension instruction set.” The base instruction set is mandatory, while the extension instruction set is optional. This means that you can choose the instructions you need based on your actual requirements. For example, in a project, if compressed instructions are not needed, there is no need to include them, allowing for customization, which is a significant feature of RISC-V.
The RISC-V instruction set includes RV32I, RV32E, RV64I, RV64E, RV64I, etc. RV stands for RISC-V, and 32/64 represents 32-bit or 64-bit. I and E are both base instruction sets, and on top of I and E, you can add D (double-precision floating-point extension), M (integer multiplication and division), A (atomic extension), C (compressed extension), and other extension instructions. For example, based on RV64I, if you add atomic, integer multiplication and division, double-precision floating-point, and compressed instructions, the instruction set is called RV64IMADC.
The base instruction set and extension instruction set are described as follows:

RISC-V Privileged Architecture
ARM has seven operating modes, and RISC-V also has different modes, which are referred to as privileged architectures in RISC-V.
RISC-V has a total of four modes: U, S, H, and M modes: U mode is encoded as 00, S mode is encoded as 01, H mode is encoded as 10, and M mode is encoded as 11. The higher the level, the higher the privilege. According to the privilege levels, from high to low, they are M, H, S, and U.
The mode encoded as 10 in the figure is reserved; this mode is actually the H mode, which is used for virtualization. However, RISC-V’s support for virtualization is still not very mature, and it is basically unsupported. Therefore, the figure does not mark the H mode but treats it as reserved. This is why people often refer to RISC-V’s modes as three: U, S, and M.
- U mode: User mode
- S mode: Supervisor mode
- M mode: Machine mode
For example, in RISC-V Linux, Linux applications run in U mode, the Linux kernel/uboot runs in S mode, and M mode is OpenSBI. M mode has the highest access privileges. If the Linux kernel needs to access CSR registers, it must switch from S mode to M mode, have OpenSBI read the CSR registers, and then return the data to the kernel.
M mode is mandatory, and RISC-V bare-metal code runs in M mode.
RISC-V General Registers
Register | ABI Name | Description |
---|---|---|
x0 | zero | Zero register, hard-coded to 0, writes are ignored, reads return 0 |
x1 | ra | Used for return address |
x2 | sp | Used for stack pointer |
x3 | gp | Used for global pointer |
x4 | tp | Used for thread pointer |
x5 | t0 | Used for temporary data or spare link register |
x6~x7 | t1~t2 | Used for temporary data registers |
x8 | s0/fp | Register that needs to be saved or frame pointer register |
x9 | s1 | Register that needs to be saved |
x10~x11 | a0~a1 | Function argument or return value registers |
x12~x17 | a2-a7 | Function parameter passing registers |
x18~x27 | s2-s11 | Registers that need to be saved |
x28~x31 | t3~t6 | Used for temporary data registers |
RISC-V has a total of 32 general registers from x0 to x31, each with its own purpose. For example, x2 serves as the sp stack pointer, and a0~a1 are used to store function parameters or return values. The x0 register is hard-coded to 0, serving as a zero register.
The ABI names are aliases for these general registers, and in RISC-V assembly, ABI names are used to represent these registers.
RISC-V CSR Registers
CSR stands for Control and Status Register. In RISC-V, CSR registers need to be accessed using specific instructions such as csrr, csrw, csrrw, etc.
Both M mode and S mode have their own CSR registers, but they are generally similar. Below are some commonly used CSRs.
M Mode CSR Registers
mstatus
Status register that saves the global interrupt enable state and other states, such as saving the current mode before switching modes.
mtvec
Exception entry base address register. It saves the address to jump to when an exception occurs.
medeleg
and mideleg
medeleg is for exception delegation, and mideleg is for interrupt delegation. For example, when an exception or interrupt occurs in M mode, these two registers can delegate the interrupt/exception to S mode or another mode for handling.
mip
and mie
mie is the interrupt enable register, enabling the corresponding bits for interrupts that need to be enabled.
mip is the interrupt pending register, indicating the interrupts that are currently being prepared for processing.
hpm
Full name Hardware Performance Monitor, used for performance counting. It includes two types of registers: mhpmcounter and mhpmevent
- mhpmcounter: Performance counter
- mhpmevent: Used to configure performance events
mcounteren
and mcountinhibit
These two are also hpm-related registers, mainly used to control the enabling and counting prohibition of hpm.
- mcounteren: Counter enable
- mcountinhibit: Count prohibition
mscratch
Used to save the pointer to the hart context in M mode and exchange it with user registers when entering the M mode handler.
mepc
When an interrupt occurs, the current program’s PC value is saved in mepc, and when returning from the interrupt, the PC value is read from mepc.
mcause
Used to save the situation of the interrupt or exception. The interrupt and exception descriptions are as follows:

1 represents an interrupt, and 0 represents an exception. Each exception/interrupt has a corresponding encoding value, and through the value of mcause, one can clearly know what interrupt or exception occurred, which is particularly useful during debugging. mcause
plays a significant role.
mvtal
Exception value register, for example, saving the erroneous address when an exception occurs.
S Mode CSR Registers
The CSR registers in S mode are basically the same as those in M mode, except that the first letter ‘m’ is changed to ‘s’, for example, mcause
becomes scause
, and mvtal
becomes svtal
. Their functions are essentially the same, so I will not elaborate further.
It is important to note that in addition to having the same CSR functions as M mode, S mode also adds a stap
register.
stap
register is mainly used for MMU, saving the base address of the page table. The MMU can find the first-level page table through stap
, thereby locating the physical address. The content related to the stap
register is quite extensive, and I will elaborate on it in detail later.
Conclusion
The above is the basic knowledge that needs to be mastered for getting started with RISC-V, mainly focusing on the functions of some registers and the privileged architecture. The content is not extensive and is relatively basic, but to truly master RISC-V, one must look at assembly code and bare-metal code to deeply understand the role of each register and the differences under different privileged architectures. This article is primarily a summary of introductory knowledge about RISC-V.
END
Source: Embedded Linux Charging StationCopyright belongs to the original author. If there is any infringement, please contact for deletion.▍Recommended ReadingHuawei C/C++ Coding Standards LeakedThe include in C language is not as simple as you think!The truth I learned after becoming a Linux driver engineer…
→ Follow to avoid getting lost ←