RV32/64 特權架構 - CSR寄存器
- 1 CSR地址空間
- 2 CSR定義
- 2.1 用戶級
- 2.2 監管級
- 2.3 超級監管級
- 2.4 機器級
- 3 CSR訪問
- 3.1 CSRRW
- 3.2 CSRRS
- 3.3 CSRRC
- 3.4 CSRRWI
- 3.5 CSRRSI
- 3.6 CSRRCI
本文屬于《 RISC-V指令集基礎系列教程》之一,歡迎查看其它文章。
1 CSR地址空間
RISC-V架構中定義了一些控制和狀態寄存器(control and status register),簡稱CSR,與32個物理寄存器不同(物理寄存器可以認為是5位地址尋址的),這些CSR是用12位地址進行尋址的,因此理論上最多可以有4096個CSR寄存器,并且地址空間是私有獨立的,不同于全局地址空間。
CSR地址空間,定義如下:
CSR地址的高4bits,用于編碼CSR在各個權級上的可讀寫性:
- [11:10],表示該寄存器是可讀寫(00,01或10),還是只讀(11)。
- [9:8],表示允許訪問該寄存器的最低權級。
00:用戶級,用戶模式及以上權級(用戶、監管、機器)可訪問。
01:監管級,監管模式及以上權級(監管、機器)可訪問。
10:超級監管級(擴展模式),僅在虛擬化時使用,用于訪問虛擬化專用的CSR。
11:機器級,僅機器模式可訪問。
從上圖也可以看到,根據[9:8]的值,整個CSR地址空間被分為了4個部分。
除此之外,上圖還指定了哪些CSR地址是標準用途,而哪些是自定義用途。
用于自定義的CSR地址,不會在未來標準擴展中被重新定義。
2 CSR定義
我們知道,CSR寄存器被劃分為4個級別:用戶級、監管級、超級監管級、機器級。
接下來,我們看看各個權級,具體定義了哪些寄存器。
2.1 用戶級
用戶級CSR,定義了兩個部分的寄存器:
- Unprivileged Floating-Point CSRs
- Unprivileged Counter/Timers
以上Number列,給出了該寄存器的12位地址。
具體寄存器含義見規范手冊。
2.2 監管級
監管級CSR,定義了五個部分的寄存器:
- Supervisor Trap Setup
- Supervisor Configuration
- Supervisor Trap Handling
- Supervisor Protection and Translation
- Debug/Trace Registers
具體寄存器含義見規范手冊。
2.3 超級監管級
超級監管級CSR,定義了七個部分的寄存器:
- Hypervisor Trap Setup
- Hypervisor Trap Handling
- Hypervisor Configuration
- Hypervisor Protection and Translation
- Debug/Trace Registers
- Hypervisor Counter/Timer Virtualization Registers
- Virtual Supervisor Registers
具體寄存器含義見規范手冊。
2.4 機器級
機器級CSR,定義了九個部分的寄存器:
- Machine Information Registers
- Machine Trap Setup
- Machine Trap Handling
- Machine Configuration
- Machine Memory Protection
- Machine Counter/Timers
- Machine Counter Setup
- Debug/Trace Registers (shared with Debug Mode)
- Debug Mode Registers
具體寄存器含義見規范手冊。
3 CSR訪問
針對CSR寄存器的讀寫,有相應的特殊指令,這些特殊指令都被定義在RV32I中,如下所示:
真正的指令只有CSRRW、CSRRS、CSRRC、CSRRWI、CSRRSI、CSRRCI這6條,其他資料中的CSR指令,均為偽指令。
CSR指令機器碼中共有12位(第20-31位)用來指示,被“讀改寫”的是哪一個CSR寄存器,這里通常填寫的就是前面講過的CSR地址,比如:mtvec寄存器那就是0x305。
注意事項:
- 試圖訪問一個不存在的CSR將造成一個非法指令異常(illegal instruction exception);
- 試圖在不當的權級下訪問CSR,或者嘗試寫入一個只讀寄存器也都將造成非法指令異常;
- 可讀寫寄存器中也可能包含一些只讀位,此時忽略對只讀位的寫入。
3.1 CSRRW
指令形式:csrrw rd, csr, rs1
指令功能:CSR寄存器讀后寫。記csr值為t,將rs1寫入csr,再將t寫入rd。
t = csr
csr = rs1
rd = t
例如:csrrw t0, mstatus, t0
將 mstatus 的值與 t0 的值交換。
3.2 CSRRS
指令形式:csrrs rd, csr, rs1
指令功能:CSR寄存器讀后置位。記csr值為t,將t和rs1的按位或結果寫入csr,再將t 寫入rd。
t = csr
csr = t | rs1
rd = t
3.3 CSRRC
指令形式:csrrc rd, csr, rs1
指令功能:CSR寄存器讀后清位。記csr值為t,將rs1的反碼和t按位與,結果寫入csr,再將t寫入rd。
t = csr
csr = t & ~rs1
rd = t
3.4 CSRRWI
指令形式:csrrwi rd, csr, zimm[4:0]
指令功能:CSR寄存器讀后寫立即數。將csr 的值復制到rd 中,再將5 位立即數zimm 的零擴展結果寫入csr。
rd = csr
csr = zimm
3.5 CSRRSI
指令形式:csrrsi rd, csr, zimm[4:0]
指令功能:CSR寄存器讀后置位立即數。記csr 的值為t,將5 位立即數zimm 零擴展后,和t 按位或,結果寫入csr,再將t 寫入rd(csr 中的第5 及更高的位不變)。
t = csr
csr = t | zimm
rd = t
3.6 CSRRCI
指令形式:csrrci rd, csr, zimm[4:0]
指令功能:CSR寄存器讀后清位立即數。記csr 的值為t,將5 位立即數zimm 零擴展后的反碼和t 按位與,結果寫入csr,再將t 寫入rd(csr 中的第5 及更高的位不變)。
t = csr
csr = t & ~zimm
rd = t
此外,需要注意:
- 若目的通用寄存器為x0,則不會執行讀取操作;
- 若源通用寄存器為x0或立即數0,也不會進行寫入CSR操作。
基于以上6條指令和x0這樣的特性,衍生出若干CSR偽指令,比如:csrr、csrc、csrci、csrs、csrw等。
參考文檔:
- 《riscv-spec-20191213》
- 《riscv-privileged-20211203》