Menu Close

控制和状态(CSR)寄存器详解

RiscV架构则定义了一些控制和状态寄存器(CSR),用于配置或记录一些运行的状态。CSR寄存器是处理器内核内部的寄存器,使用专有的12位地址编码空间,对一个hart,可以配置4k的CSR寄存器。

    蜂鸟203支持以下的CSR寄存器:

类型 CSR地址 读写属性 名称 全称
riscv标准csr 0x001 MRW fflags 浮点累积异常(Floating accrued Exception)
0x002 MRW frm 浮点动态舍入模式(floating-point dynamic rounding mode)
0x003 MRW fcsr 浮点控制和状态寄存器(floating-point control and status register)
0x300 MRW mstatus 机器模式状态寄存器(machine status register)
0x301 MRW misa 机器模式指令集架构寄存器(machine ISA register)
0x304 MRW mie 机器模式中断使能寄存器(machine interrupt enable register)
0x305 MRW mtvec 机器模式异常入口基地址寄存器(machine trap-vector base-address register)
0x340 MRW mscratch 机器模式擦写寄存器(machine srcatch register)
0x341 MRW mepc 机器模式异常pc寄存器(machine exception program counter)
0x342 MRW mcause 机器模式异常原因寄存器(machine cause register)
0x343 MRW mtval(mbadaddr) 机器模式异常值寄存器(machine trap value register)
0x344 MRW mip 机器模式中断等待寄存器(machine interrupt pending register)
0xb00 MRW mcycle 周期计数器的低32位(lower 32bits of cycle counter)
0xb80 MRW mcycleh 周期计数器的高32位(upper 32bits of cycle counter)
0xb02 MRW minstret 退休指令计数器的低32位(lower 32bits of instruction-retired counter)
0xb82 MRW minstreth 退休指令计数器的高32位(upper 32bits of instruction-retired counter)
0xf11 MRW mvendorid 机器模式供应商编号寄存器(machine vendor ID register),readonly, 供应商编号,如果为0,表示此寄存器未实现或不是一个商业核
0xf12 MRW marchid 机器模式架构编号寄存器(machine architecture ID register),readonly,微架构编号,如果为0,表示未实现该寄存器
0xf13 MRO mimpid 机器模式硬件实现编号寄存器(machine implementation ID register),readonly,硬件实现编号,如果为0,表示未实现该寄存器
0xf14 MRO mhartid hart编号寄存器(hart ID register),readonly,hart的编号。多hart系统中,起码有一个hart编号为0
N/A MRO mtime 机器模式计时器寄存器(machine-mode timer register)
N/A MRW mtimecmp 机器模式计数器比较寄存器(machine-mode timer compare register)
N/A MRW msip 机器模式软件中断等待寄存器(machine-mode software interrupt pending register)
e203自定义 0xbff MRW mcounterstop 自定义寄存器用于停止mtime, mcycle, mcycleh,minstret,minstreth对应的计数器

常用的CSR寄存器详细介绍如下,先来看下一些概念。

Reserved Writes Preserve Values, Reads Ignore Values (WPRI)

Write/Read Only Legal Values (WLRL)

Write Any Values, Reads Legal Values (WARL)

misa

misa寄存器用于指示当前处理器所支持的架构特性。

最高两位表示当前处理器支持的架构位数,值为1表示当前为32位架构(RV32),值为2表示当前为RV64架构,值为3表示当前为128位架构(RV128)。

低26位表示当前支持的扩展指令集模块,如果支持某模块,则对应的位为1。比如E203,支持IMAC,则低26位为:

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 1 x x x x 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 1
bits 扩展指令集 描述
0 A Atomic extension
1 B Tentatively reserved for Bit-Manipulation extension
2 C Compressed extension
3 D Double-precision floating-point extension
4 E RV32E base ISA
5 F Single-precision floating-point extension
6 G Additional standard extensions present
7 H Hypervisor extension
8 I RV32I/64I/128I base ISA
9 J Tentatively reserved for Dynamically Translated Languages extension
10 K Reserved
11 L Tentatively reserved for Decimal Floating-Point extension
12 M Integer Multiply/Divide extension
13 N User-level interrupts supported
14 O Reserved
15 P Tentatively reserved for Packed-SIMD extension
16 Q Quad-precision floating-point extension
17 R Reserved
18 S Supervisor mode implemented
19 T Tentatively reserved for Transactional Memory extension
20 U User mode implemented
21 V Tentatively reserved for Vector extension
22 W Reserved
23 X Non-standard extensions present
24 Y Reserved
25 Z Reserved

fflags

fflags 为浮点控制状态寄存器(fcsr)中的异常标志位域的别名。

详见https://www.cnblogs.com/mikewolf2002/p/9878603.html

frm

frm寄存器为浮点控制状态寄存器中浮点舍入模式域的别名。

详见https://www.cnblogs.com/mikewolf2002/p/9878603.html

fcsr

risc-v架构规定,如果支持单精度浮点指令或者双精度浮点指令,则需要增加一个浮点控制状态寄存器。该寄存器包含了浮点异常标志位域和浮点舍入模式域。

详见https://www.cnblogs.com/mikewolf2002/p/9878603.html

mtvec

      Riscv 架构规定,在处理器的程序执行过程中,一旦发生异常,则终止当前的程序流,处理器被强行跳转到一个新的PC地址。该过程在RiscV的架构中定义为trap(陷阱)。

      Riscv处理器trap后跳入的PC地址由一个叫做机器模式异常入口基地址寄存器mtvec的csr寄存器指定。mtvec是一个可读可写的寄存器,软件可以编程设定它的值。

      mtvec格式如下,其中低2位是mode域,高30位是base域。

xlen-1 2 1 0
Interrupt BASE[xlen-1:2](WARL)
xlen-2 2

       假设mode的值为0,则所有的异常响应时处理器均跳转到base值指示的pc地址。

       假设mode的值为1,则狭义的异常发生时候,处理器均跳转到base值指示的pc地址。狭义的中断发生时候,处理器跳转到base+4*cause值指示的pc地址。cause的值表示中断对应的异常编号(exception code)。譬如,机器计时器中断(machine timer interrupt)的异常编号为7,则跳转地址为base+4*7=base+28=base+0x1c

mcause

      Riscv架构规定,进入异常时候,机器模式异常原因寄存器mcause被同时更新,以反映当前的异常种类,软件可以通过读此寄存器查询造成异常的具体原因。

      mcause寄存器格式如下,其中最高位为Interrupt位,为1表示是中断,否则为异常,低31位(对于RV32)为异常编号域。

xlen-1 xlen-2 0
Interrupt 异常编码(WLRL)
1 xlen-1

异常编号域定义了中断和异常类型,如下表所示:

是否中断 异常编码 描述
1 0  User software interrupt
1 1  Supervisor software interrupt
1 2  Reserved for future standard use
1 3  Machine software interrupt
1 4  User timer interrupt
1 5  Supervisor timer interrupt
1 6  Reserved for future standard use
1 7  Machine timer interrupt
1 8  User external interrupt
1 9  Supervisor external interrupt
1 10  Reserved for future standard use
1 11  Machine external interrupt
1  12–15  Reserved for future standard use
1  ≥16  Reserved for platform use
0 0  Instruction address misaligned
0 1  Instruction access fault
0 2  Illegal instruction
0 3  Breakpoint
0 4  Load address misaligned
0 5  Load access fault
0 6  Store/AMO address misaligned
0 7  Store/AMO access fault
0 8  Environment call from U-mode
0 9  Environment call from S-mode
0 10  Reserved
0 11  Environment call from M-mode
0 12  Instruction page fault
0 13  Load page fault
0 14  Reserved for future standard use
0 15  Store/AMO page fault
0  16–23  Reserved for future standard use
0  24–31  Reserved for custom use
0  32–47  Reserved for future standard use
0  48–63  Reserved for custom use
0  ≥64  Reserved for future standard use

mepc

      mepc是xlen位的读写寄存器,mepc[0]总是等于0,如果IALIGN=32,则mepc[1:0]总是等于0。

xlen-1 0
mepc
xlen

       Riscv架构定义异常的返回地址由机器模式异常PC寄存器mepc保存。在进入异常时候,硬件将自动更新mepc寄存器的值为当前遇到异常的指令PC值(即当前程序的停止执行点)。该寄存器的值将作为异常的返回地址,在异常结束后,能够使用它保存的pc值返回之前停止执行的程序点。注意:mepc虽然被自动更新,但它是可读可写的,软件可以直接读写该寄存器的值。

      对于狭义的中断和狭义的异常而言,RiscV架构定义其返回地址,稍有差异。

  • 出现中断时候,中断返回地址mepc的值被更新为下一条尚未执行的指令。
  • 出现异常时候,中断返回地址mepc的值被更新为当前发生异常的指令pc。注意:如果异常是有ecall和ebreak产生,由于mepc的值被更新为ecall或者ebreak指令自己的PC。因此,在异常返回时候,如果直接使用mepc保存的pc值作为返回地址,则会再次进入异常,形成死循环。正确的做法是在异常处理程序中软件改变mepc指向下一条指令,由于现在ecall/ebreak(c.ebreak)是4字节(2字节)指令,因此更改设定mepc=mepc+4(或+2)即可。

     

mtval(mbadaddr)

mtval是一个读写寄存器,它的格式如下:

mtval xlen-1 0
mtval
xlen

      Riscv规定,在进入异常时候,硬件将自动更新机器模式异常值寄存器mtval,以反映引起当前异常的存储器访问地址或者指令编码。

  • 如果是由访问存储器造成的异常,比如硬件断点,取指令,存储器读写造成的异常,则将存储器访问的地址更新到mtval。
  • 如果是由非法指令造成的异常,则将该指令的指令编码更新到mtval寄存器中。

mstatus

mstatus是机器模式下的状态寄存器。在E203中我们仅关注SD,XS,FS,MPP,MPIE,MIE

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
SD WPRI TSR TW TVM MXR SUM MPRV XS[1] XS[0] FS[1] FS[0] MPP[1] MPP[0] WPRI SPP MPIE WPRI SPIE UPIE MIE WPRI SIE UIE
  1. MIE域表示全局中断使能。当该MIE域值为1时,表示所有中断的全局开关打开,当MIE域的值为0时候,表示全局关闭所有中断。
  2. MPIE用于保存进入异常之前MIE域的值。
  3. XS作用于FS域类似,用于维护和反映用户自定义的扩展指令单元状态,标准riscv架构中,XS域是只读的,在e200中,将XS域设计为可读可写,用它来打开和关闭协处理器。
  4. SD域是一个只读域,其反映了XS域或者FS域处于脏(dirty)状态,其逻辑关系表达式为:SD=((FS==11) or (XS==11))
  5. MPP用于保存进入异常之前特权模式的值。处理器进入异常时候:MPIE域的值被更新为MIE的值。MIE的值被更新为0(意味着进入异常,中断被屏蔽)。MPP的值被更新为异常发生前的模式(如果只实现机器模式,则MPP的值永远为11)。
  6. FS域用于维护和反映浮点单元的状态,编码如下:
Status  FS Meaning XS  Meaning
0  Off All off
1  Initial  None dirty or clean,some on
2  Clean None dirty, some clean
3  Dirty Some dirty

      FS域的更新准则如下:FS上电后默认值为0,意味着浮点单元的状态为off。因此为了能够正常使用浮点单元,软件需要使用CSR写指令将FS的值改写为非0值,以打开浮点单元的功能。如果FS的值为1或2,当执行了任何的浮点指令之后,FS的值都会自动切换到3,表示浮点单元的状态为脏(dirty)(状态发生了改变 ) 。如果处理器不想使用浮点运算单元,可以使用csr写指令将mstatus寄存器的FS域设置为0,从而关闭浮点单元的功能。当浮点单元功能关闭后,任何访问浮点csr或者执行浮点指令的行为都会除法非法指令异常。

      Riscv架构规定,进入异常时候,硬件自动更新机器模式状态寄存器mstatus中的某些域。MPIE的值被更新为异常发生前MIE域的值。MPIE的作用是在异常结束后,能够使用MPIE的值恢复出异常发生之前的MIE值。MIE的值被更新为0,意味着进入异常服务程序后,中断被全局关闭,所有的中断不被响应。MPP的值被更新为异常发生前的模式(如果只实现机器模式,则MPP的值永远为11),MPP域的作用是在异常结束后,能够恢复到之前的工作模式。

     当异常程序处理完成后,最终要从异常服务程序中退出,并返回主程序。riscv中定义了一组退出指令mret,sret,和uret,对于机器模式,对应mret。

     在机器模式下退出异常时候,软件必须使用mret。riscv架构规定,处理器执行完mret指令后,硬件行为如下:

  • 停止执行当前程序流,转而从csr寄存器mepc定义的pc地址开始执行。
  • 执行mret指令不仅会让处理器跳转到上述的pc地址开始执行,还会让硬件同时更新csr寄存器机器模式状态寄存器mstatus。mstatus寄存器MIE域被更新为当前MPIE的值。MPIE 域的值则更新为1

mie/mip

Riscv架构中定义的中断类型分为4种。

  • 外部中断
  • 计时器中断
  • 软件中断
  • 调试中断

外部中断是指来自于处理器核外部的中断,比如uart,gpio等产生的中断。

Riscv架构上定义的异常是不可屏蔽的,但狭义上的中断是可以屏蔽的,通过设置mie寄存器来屏蔽中断。mip寄存器用于查询中断的等待状态,软件可以通过读mip寄存器达到查询中断状态的结果。

机器模式下外部中断的屏蔽由csr寄存器mie中MEIE域控制,等待标志(pending)则反映在csr寄存器mip的MEIP域。mip和mie寄存器的高20位可以用于扩展其它的自定义中断类型。

机器模式下定时器中断的屏蔽由mie中的MTIE域控制,等待标志(pending)则反映在csr寄存器mip的MTIP域。

机器模式下软件中断的屏蔽由mie中的MSIE域控制,等待标志(pending)则反映在csr寄存器mip的MSIP域。

mip xlen-1 11 10 9 8 7 6 5 4 3 2 1 0
WPRI MEIP WPRI SEIP UEIP MTIP WPRI STIP UTIP MSIP WPRI SSIP USIP
xlen-12 1 1 1 1 1 1 1 1 1 1 1 1
mie xlen-1 11 10 9 8 7 6 5 4 3 2 1 0
WPRI MEIE WPRI SEIE UEIE MTIE WPRI STIE UTIE MSIE WPRI SSIE USIE
xlen-12 1 1 1 1 1 1 1 1 1 1 1 1

机器模式外部中断可以作为处理器核的一个单比特输入信号,如果处理器要支持多个外部中断,可以采用平台级别的中断控制器(PLIC),可以用于多个外部中断源的优先级仲裁和派发。

mscratch

      mscratch寄存器用于机器模式下的程序临时保存某些数据。mscratch寄存器可以提供一种快速的保存、恢复机制。比如,在进入机器模式的异常处理程序后,将应用程序的某个通用寄存器的值临时存入mscratch寄存器中,然后在退出异常处理程序之前,将mscratch寄存器中的值读出恢复至通用寄存器。

mcycle和mcycleh

      riscv架构定义了一个64位的时钟周期计数器,用于反映处理器成功执行了多少个时钟周期。只要处理器处于执行状态,此计数器便会自增计数,其自增的频率由处理器硬件实现自定义。

      mcycle寄存器反映了该计数器低32位的值,mcycleh寄存器反映了该计数器高32位的值

minstret和minstreth

      riscv架构定义了一个64位的执行指令计数器,用于反映处理器成功执行了多少条指令。只要处理器每成功执行一条指令,此计数器便会自增计数。

      minstret寄存器反映了该计数器低32位的值,minstreth寄存器反映了该计数器高32位的值。

mtime/mtimecmp/msip

      Riscv架构定义了系统平台中必须有一个计时器,并给该计时器定义了两个64位宽的寄存器mtime和mtimecmp。mtime寄存器用于反应当前计数器的计数值,mtimecmp用于设置计数器的比较值。当mtime中的计数值大于或者等于mtimecmp中设置的比较值时,计时器便会产生计时器中断。计时器中断会一直拉高,直到软件重写mtimecmp寄存器的值,使得其大于mtime中的值,从而清除计时器中断。

      Riscv架构并没有定义mtime和mtimecmp寄存器为csr寄存器,而定义其为存储器地址映射的系统寄存器。具体的存储器映射,riscv并没有规定,而是交于soc系统集成者实现。

      riscv架构定义的mtime定时器为实时计时器,系统必须以一种恒定的频率作为计时器的时钟。该恒定的时钟频率必须为低速的电源常开的时钟。低速是为了省电,常开是为了提供准确的及时。

counterstop

counterstop是蜂鸟自定义csr寄存器。用于控制mtime,mcycle,minstreth,mtimeh,mcycleh,minstreth的运行和停止,以便节省功耗。

xlen-1 2 1 0
reserved reserved reserved reserved reserved reserved reserved reserved reserved reserved instret timer cycle
reserved reserved reserved reserved reserved reserved reserved reserved reserved reserved 1 1 1

0/1/2 三位如果为1,则相应计数器停止工作,如果为0,则开始工作,上电默认值为0.