跳到主要内容

特权架构

RISC-V 特权架构定义了处理器的特权级别和相应的控制机制,用于支持操作系统和系统软件的实现。

特权级别

RISC-V 定义了四个特权级别:

级别编码名称缩写典型用途
000用户模式U-mode应用程序
101监督模式S-mode操作系统内核
210虚拟监督模式HS-mode虚拟机监视器
311机器模式M-mode固件/BIOS

特权级别的作用

特权级别用于:

  • 保护系统资源
  • 隔离不同软件层
  • 控制硬件访问权限
  • 实现安全机制

特权指令

不同特权级别可以执行的指令不同:

机器模式专用指令

mret          # 从机器模式异常返回
ecall # 环境调用(系统调用)
ebreak # 断点

监督模式专用指令

sret          # 从监督模式异常返回
sfence.vma # 刷新 TLB

控制状态寄存器(CSR)

CSR 用于配置处理器行为和查询处理器状态。

CSR 地址编码

CSR 地址为 12 位,按照特权级别分组:

地址范围权限用途
0x000-0x3FF只读用户级信息
0x400-0x7FF读写用户级
0x800-0xBFF只读监督级信息
0xC00-0xFFF读写监督级
0xF00-0xFFF只读机器级信息
0x300-0x3FF读写机器级

机器模式 CSR

mstatus - 机器状态寄存器

位域:
[63] MBE - 机器模式大端
[34:33] UXL - 用户模式位宽(RV64)
[12:11] MPP - 之前的特权模式
[11] SPP - 之前的监督模式
[7] MPIE - 之前的中断使能
[5] SPIE - 之前的监督中断使能
[3] MIE - 机器模式中断使能
[1] SIE - 监督模式中断使能
[0] UIE - 用户模式中断使能

mtvec - 机器陷阱向量

[31:2] BASE - 处理程序基地址
[1:0] MODE - 向量模式
00 = 直接模式
01 = 向量模式

mepc - 机器异常程序计数器

保存发生异常时的 pc 值。

mcause - 机器异常原因

[31]    Interrupt - 1 表示中断,0 表示异常
[30:0] Exception Code - 异常/中断编码

mtval - 机器陷阱值

保存异常的附加信息。

mie - 机器中断使能

[11] MEIE - 机器外部中断使能
[7] MTIE - 机器定时器中断使能
[3] MSIE - 机器软件中断使能

mip - 机器中断挂起

[11] MEIP - 机器外部中断挂起
[7] MTIP - 机器定时器中断挂起
[3] MSIP - 机器软件中断挂起

监督模式 CSR

sstatus - 监督状态寄存器

位域:
[34:33] UXL - 用户模式位宽(RV64)
[8] SPP - 之前的特权模式
[5] SPIE - 之前的中断使能
[1] SIE - 监督模式中断使能

stvec - 监督陷阱向量

[31:2] BASE - 处理程序基地址
[1:0] MODE - 向量模式

sepc - 监督异常程序计数器

scause - 监督异常原因

stval - 监督陷阱值

satp - 监督地址翻译和保护

[63:60] MODE - 地址翻译模式
0000 = 裸机模式(无翻译)
1000 = Sv39(39 位虚拟地址)
1001 = Sv48(48 位虚拟地址)
[59:44] ASID - 地址空间标识符
[43:0] PPN - 根页表物理页号

用户模式 CSR

cycle - 周期计数器

只读,记录处理器周期数。

time - 时间计数器

只读,记录实时时间。

instret - 指令计数器

只读,记录已完成的指令数。

CSR 访问指令

CSR 读写指令

csrrw  rd, csr, rs1    # 读 CSR 到 rd,写 rs1 到 CSR
csrrs rd, csr, rs1 # 读 CSR 到 rd,设置 CSR 中 rs1 对应的位
csrrc rd, csr, rs1 # 读 CSR 到 rd,清除 CSR 中 rs1 对应的位

立即数版本

csrrwi rd, csr, imm    # 读 CSR 到 rd,写立即数到 CSR
csrrsi rd, csr, imm # 读 CSR 到 rd,设置 CSR 中立即数对应的位
csrrci rd, csr, imm # 读 CSR 到 rd,清除 CSR 中立即数对应的位

常用伪指令

csrr   rd, csr         # 读 CSR
csrw csr, rs1 # 写 CSR
csrc csr, rs1 # 清除 CSR 位
csrs csr, rs1 # 设置 CSR 位
csrwi csr, imm # 写立即数到 CSR

特权模式切换

从用户模式进入更高特权模式

用户模式通过以下方式进入更高特权模式:

  1. 系统调用(ecall)
ecall              # 触发环境调用异常
  1. 异常
  • 非法指令
  • 断点
  • 加载/存储访问错误
  1. 中断
  • 定时器中断
  • 外部中断
  • 软件中断

从高特权模式返回低特权模式

使用 mret 或 sret 指令返回:

mret              # 从机器模式返回
sret # 从监督模式返回

模式切换示例

用户模式调用系统调用

# 用户模式代码
li a7, 64 # 系统调用号(write)
li a0, 1 # 文件描述符
la a1, buffer # 缓冲区地址
li a2, 100 # 长度
ecall # 进入机器模式

机器模式处理系统调用

# 异常处理程序
trap_handler:
csrr t0, mcause
li t1, 8 # 环境调用异常码
bne t0, t1, other_trap

# 处理系统调用
# a7 包含系统调用号
# a0-a5 包含参数

# ... 处理系统调用 ...

# 返回用户模式
csrr t0, mepc
addi t0, t0, 4 # 跳过 ecall 指令
csrw mepc, t0
mret

异常和中断

异常原因编码

编码名称描述
0Instruction address misaligned指令地址未对齐
1Instruction access fault指令访问错误
2Illegal instruction非法指令
3Breakpoint断点
4Load address misaligned加载地址未对齐
5Load access fault加载访问错误
6Store/AMO address misaligned存储地址未对齐
7Store/AMO access fault存储访问错误
8Environment call from U-mode用户模式环境调用
9Environment call from S-mode监督模式环境调用
11Environment call from M-mode机器模式环境调用
12Instruction page fault指令页错误
13Load page fault加载页错误
15Store/AMO page fault存储页错误

中断原因编码

编码名称描述
1Supervisor software interrupt监督软件中断
3Machine software interrupt机器软件中断
5Supervisor timer interrupt监督定时器中断
7Machine timer interrupt机器定时器中断
9Supervisor external interrupt监督外部中断
11Machine external interrupt机器外部中断

中断使能

# 使能机器模式中断
li t0, (1 << 3) | (1 << 7) | (1 << 11) # MSIE | MTIE | MEIE
csrs mie, t0

# 使能全局中断
csrs mstatus, (1 << 3) # MIE

异常处理流程

异常进入

  1. 保存当前 pc 到 mepc(或 sepc)
  2. 设置 mcause(或 scause)记录异常原因
  3. 设置 mtval(或 stval)记录附加信息
  4. 设置 mstatus(或 sstatus)的 MPP(或 SPP)字段记录之前特权模式
  5. 清除 MIE(或 SIE)禁用中断
  6. 跳转到 mtvec(或 stvec)指定的处理程序

异常返回

  1. 从 mepc(或 sepc)恢复 pc
  2. 从 mstatus(或 sstatus)恢复之前的特权模式和中断使能状态
  3. 执行 mret(或 sret)指令

异常处理程序示例

.section .text
.globl trap_handler

trap_handler:
# 保存上下文
addi sp, sp, -128
sw ra, 124(sp)
sw gp, 120(sp)
sw tp, 116(sp)
# ... 保存其他寄存器 ...

# 读取异常原因
csrr t0, mcause

# 判断是中断还是异常
blt t0, zero, handle_interrupt

# 处理异常
li t1, 2
beq t0, t1, handle_illegal_instruction
li t1, 8
beq t0, t1, handle_ecall_user
# ... 其他异常处理 ...

handle_interrupt:
# 处理中断
andi t1, t0, 0x7
li t2, 7
beq t1, t2, handle_timer_interrupt
# ... 其他中断处理 ...

trap_return:
# 恢复上下文
lw ra, 124(sp)
lw gp, 120(sp)
lw tp, 116(sp)
# ... 恢复其他寄存器 ...
addi sp, sp, 128

mret

委托机制

机器模式可以将异常和中断委托给监督模式处理。

medeleg / mideleg

medeleg - 机器异常委托

位 n = 1 表示异常 n 委托给监督模式处理

mideleg - 机器中断委托

位 n = 1 表示中断 n 委托给监督模式处理

委托示例

# 委托用户模式系统调用给监督模式
li t0, (1 << 8) # 异常 8:用户模式环境调用
csrw medeleg, t0

# 委托监督模式中断给监督模式
li t0, (1 << 1) | (1 << 5) | (1 << 9) # SSI | STI | SEI
csrw mideleg, t0

小结

本章介绍了 RISC-V 特权架构:

  • 特权级别:用户模式、监督模式、机器模式
  • CSR 寄存器:mstatus、mtvec、mepc、mcause 等
  • CSR 访问指令:csrrw、csrrs、csrrc 等
  • 模式切换:ecall、mret、sret
  • 异常和中断:原因编码、处理流程
  • 委托机制:medeleg、mideleg

特权架构是操作系统和系统软件开发的基础。下一章将详细介绍中断和异常处理。