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 |
- MIE域表示全局中断使能。当该MIE域值为1时,表示所有中断的全局开关打开,当MIE域的值为0时候,表示全局关闭所有中断。
- MPIE用于保存进入异常之前MIE域的值。
- XS作用于FS域类似,用于维护和反映用户自定义的扩展指令单元状态,标准riscv架构中,XS域是只读的,在e200中,将XS域设计为可读可写,用它来打开和关闭协处理器。
- SD域是一个只读域,其反映了XS域或者FS域处于脏(dirty)状态,其逻辑关系表达式为:SD=((FS==11) or (XS==11))
- MPP用于保存进入异常之前特权模式的值。处理器进入异常时候:MPIE域的值被更新为MIE的值。MIE的值被更新为0(意味着进入异常,中断被屏蔽)。MPP的值被更新为异常发生前的模式(如果只实现机器模式,则MPP的值永远为11)。
- 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.