这是一个非常核心的概念。理解了 CSR你就理解了 RISC-V CPU 的“控制面板”。1. CSR 到底是什么CSR (Control and Status Registers控制与状态寄存器)。你可以把它和通用寄存器GPR做对比通用寄存器 (x0-x31)是 CPU 的工作台。用来存放计算用的数据加数、减数、地址等由软件自由读写。CSR是 CPU 的控制面板。用来配置 CPU 的行为、查询 CPU 的状态。它们不在通用寄存器组里而是有一个独立的地址空间。举个例子你想开启中断去改 CSR (mie)。你想设置页表去写 CSR (satp)。你想知道刚才为什么发生异常去读 CSR (mcause)。你想知道当前 CPU 是几个核心去读 CSR (mhartid)。2. CSR 的地址空间与权限RISC-V 规定 CSR 有 12 位地址范围是0x000~0xFFF共 4096 个。最关键的设计在于地址的高 2 位决定了权限。地址高位 (二进制)地址范围 (Hex)权限含义00xx...0x000 - 0x0FFUser用户模式可读写主要是性能计数器等。01xx...0x100 - 0x1FFSupervisor监管者模式可读写页表、中断代理等。10xx...0x200 - 0x2FFHypervisor虚拟化扩展使用。11xx...0x300 - 0x3FFMachine机器模式可读写最高权限启动配置等。这就是为什么之前说mstatus(0x300) 在 S-mode 下不能访问因为它的地址以11开头。3. 不同 Mode 下的具体表现当 CPU 处于不同特权模式时对 CSR 的访问表现截然不同。A. Machine Mode (M-mode) - “上帝模式”权限拥有最高权限。表现可以访问所有CSRUser、Supervisor、Machine。如果 M-mode 代码去写sstatus(S-mode 的状态寄存器)硬件是允许的但这通常是不规范的操作。核心作用M-mode 负责配置底层的硬件特性比如内存映射PMP、异常委托、时钟频率等。B. Supervisor Mode (S-mode) - “操作系统模式”权限受限制。表现合法访问读写sstatus、stvec、satp等0x1xx地址的寄存器。非法访问如果尝试读写mstatus(0x300)、mtvec(0x305) 等0x3xx地址的寄存器CPU 硬件会立即产生一个非法指令异常。陷阱机制当 S-mode 试图访问 M-mode CSR 时CPU 会自动跳转到 M-mode 的异常处理程序去“告状”。C. User Mode (U-mode) - “应用程序模式”权限极度受限。表现只能访问0x000-0x0FF范围的 CSR。通常只能读取一些状态信息如读取当前时间time或读取性能计数器。任何试图访问0x100以上地址的操作都会触发异常。4. 一个重要的概念影子寄存器这是 RISC-V 设计的精髓也是初学者最容易晕的地方。你可能会发现M-mode 有mstatusS-mode 有sstatus。它们是两个独立的物理寄存器吗答案不是。sstatus其实是mstatus的一个子集。物理上只有一份mstatus寄存器64位。逻辑上当你在 M-mode 读写mstatus时你看到的是全貌所有位。当你在 S-mode 读写sstatus时硬件自动把你映射到mstatus的某几个位SIE, SPIE, SPP 等你看不到 M-mode 相关的位MIE, MPIE 等。这样做的好处操作系统在 S-mode 下运行时可以直接读写sstatus来开启/关闭中断而不需要陷入 M-mode。这既保证了安全S-mode 改不了 M-mode 的配置又提高了效率不需要频繁切换模式。总结图示操作 \ 当前模式M-mode (特权级 3)S-mode (特权级 1)U-mode (特权级 0)读mstatus(0x300)✅ 成功❌异常(跳回 M-mode)❌异常读sstatus(0x100)✅ 成功 (但不推荐)✅ 成功❌异常读time(0xC01)✅ 成功✅ 成功✅ 成功一句话总结CSR 是 CPU 的控制旋钮地址的高位决定了谁能拧动它。M-mode 可以拧所有的旋钮S-mode 只能拧自己的旋钮乱拧会被“电”一下触发异常。RISC-V 的 CSR 数量繁多但在实际开发中最常用的其实只有那一二十个。为了方便理解我将它们按功能模块分类并标注了地址和所属模式。以下是详细的 CSR 列表及说明1. 核心身份与状态这些寄存器用来回答“我是谁”以及“我现在在哪”。CSR 名称地址权限说明mhartid0xF14MRO硬件线程 ID。在多核 CPU 中这个寄存器告诉你当前是第几个核心Core 0, Core 1…。常用于多核启动时判断自身身份。mstatus0x300MRWM-mode 状态寄存器。最重要的寄存器之一控制全局中断使能MIE、保存中断前的权限等级MPP等。sstatus0x100SRWS-mode 状态寄存器。mstatus的子集S-mode 只能改自己权限下的中断位SIE和状态。misa0x301MROISA 扩展寄存器。告诉你 CPU 支持哪些指令集如 I, M, A, F, D 扩展以及是 RV32 还是 RV64。2. 异常与中断处理这是操作系统的核心决定了“出事了怎么办”。CSR 名称地址权限说明mtvec0x305MRWM-mode 异常向量基址。发生异常如断电、非法指令时CPU 跳转到这里。存放的是异常处理函数的入口地址。stvec0x105SRWS-mode 异常向量基址。同上供操作系统内核使用。mcause0x342MRWM-mode 异常原因。告诉你刚才为什么跳到异常处理函数是缺页是非法指令还是外部中断。scause0x142SRWS-mode 异常原因。同上。mepc0x341MRWM-mode 异常程序计数器。发生异常时CPU 把当时的指令地址存这里。执行mret返回时CPU 会跳回这个地址。sepc0x141SRWS-mode 异常程序计数器。同上供sret使用。mtval0x343MRWM-mode 异常值。辅助信息。例如如果是断点异常这里存断点地址如果是非法指令存该指令编码。stval0x143SRWS-mode 异常值。同上。3. 中断控制决定了“谁能打断我”。CSR 名称地址权限说明mie0x304MRWM-mode 中断使能。位图寄存器每一位控制一种中断如外部中断、软件中断、定时器中断是否开启。sie0x104SRWS-mode 中断使能。同上控制 S-mode 能接收的中断。mip0x344MRWM-mode 中断挂起。位图寄存器某一位为 1 表示该中断正在发生正在敲门等待处理。sip0x144SRWS-mode 中断挂起。同上。4. 内存地址翻译与保护这是实现虚拟内存的关键。CSR 名称地址权限说明satp0x180SRWS-mode 地址翻译与保护。这是开启虚拟内存的总开关。高位存放页表根地址PPN低位存放模式。写它之前是物理地址模式写之后 CPU 就开始查页表了。pmpcfg0-150x3A0-3AFMRW物理内存保护配置。M-mode 用来限制 S-mode 或 U-mode 能访问哪些物理内存地址。pmpaddr0-630x3B0-3EFMRW物理内存保护地址。配合上面的 cfg 使用划定内存禁区。5. 性能计数器与定时器用于性能分析和时间管理。CSR 名称地址权限说明mtime0xB01MRW机器时间。这是一个实时计数器每个时钟周期加 1。通常由主板上的 MMIO 模块提供而不是 CPU 内部。mtimecmp0xB41MRW机器时间比较器。当mtimemtimecmp时触发定时器中断。操作系统用它来实现“滴答”调度。mcycle0xB00MRW周期计数器。CPU 执行了多少个周期。minstret0xB02MRW指令计数器。CPU 执行了多少条指令。用它除以mcycle可以算 CPI每指令周期数。重点详解mstatus(最复杂的寄存器)你刚才打印的mstatus是最核心的寄存器它的位定义如下以 RV64 为例MIE (bit 3): M-mode 全局中断开关。1开0关。MPIE (bit 7): 保存进入异常前的 MIE 值。进入异常时硬件自动把 MIE 存到这里并关中断退出异常 (mret) 时用这里恢复 MIE。SIE (bit 1): S-mode 全局中断开关。SPIE (bit 5): 保存进入异常前的 SIE 值。MPP (bits 11-12):Machine Previous Privilege。这是权限切换的关键。当发生异常进入 M-mode 时硬件把之前的权限比如 S-mode1记在这里。执行mret时CPU 读取这个值决定是回到 S-mode 还是 U-mode。XS / FS / VS: 扩展状态位用于浮点、向量单元的状态保存优化。SD (bit 63): 脏位。如果 FS 或 XS 被修改过表示浮点寄存器里有脏数据此位硬件自动置 1。用于上下文切换加速如果 SD0就不需要保存浮点寄存器。总结M-mode 寄存器 (0x3xx)是地基。负责配置 CPU 的启动、物理内存保护和最底层的异常处理。S-mode 寄存器 (0x1xx)是装修。负责操作系统层面的虚拟内存、进程调度和系统调用处理。U-mode 寄存器 (0x0xx)是窗户。用户程序只能透过它们看时间、看性能不能动结构。