鐵人賽
昨日我們已經介紹 RISC-V 的特權架構了,建議先觀看第一天對後續的觀看體驗會更有幫助唷,相信大家對特權架構都有些許概念了,由於今天天氣不錯,筆者的鞋子也只溼了而已...,那就來介紹 CSR 吧,CSR 全名為 control and status register ,主要會以 machine level 為主,其他 level ( supervisor ) 概念基本與 machine level 類似只是權限的不同。
由於 CSR 挺多的,考慮到人體一天吸收有限,因此我們會分上下兩天介紹,絕對不是想蹭天數。
首先先列出目前現有的 machine level的 CSR 有什麼,我們在逐一介紹:
上圖為目前 RISC-V 所定義的 machine level CSR,以下讓我們開始介紹吧
簡單說明一下,通常首字母表示屬於哪種 level, 舉例來說: mxxx,就表示為 machine level 的 CSR ,xxx 表示其功能,以下舉例皆會以筆者公司所使用的 FPGA 及 AX45MP (64 bit) bitmap 當範例,還不快買一個板子來玩嗎 (́◉◞౪◟◉‵)
此 CSR 功能為表示其不同製造商所代表的ID,事實上筆者也很少用到此 CSR。
舉例來說:
根據下圖spec 描述,此 AX45MP 的 vendor ID 為 0x31e
我們來驗證一下我們這張板子~確實符合預期的!
此 CSR 功能為表示使用了什麼架構,根據不同製造商的定義而有所不同
舉例來說
在 SPEC 中,定義為 0x8a45
使用 FPGA 確認一下,果然沒錯
此 CSR 功能為提供該 CPU 版本號碼,筆者也鮮少使用該 CSR。
此 CSR 功能表示目前位於哪個 hart 上
舉例來說:
假設目前有4顆 hart ,當在 hart 3 時, 讀取 mhartid 則為 2。 ( hart 最低從1開始,mhartid則從0開始 )
此 CSR 表示目前的狀態,包含以下七種功能:
下圖為該 CSR 每位 bit 所代表的意義
欄位 | 全名 | 功能描述 |
---|---|---|
SIE |
Supervisor mode Interrupt Enable | S-mode 中斷啟用,SIE = 1 啟用 S-mode 全域中斷 |
MIE |
Machine mode Interrupt Enable | M-mode 中斷啟用,MIE = 1 啟用 M-mode 全域中斷 |
SPIE |
Supervisor mode Previous Interrupt Enable | 紀錄進入 S-mode 中斷與異常之前的 SIE |
UBE |
User mode Byte Endianness | U-mode 位元組順序 |
MPIE |
Machine mode Previous Interrupt Enable | 紀錄進入 M-mode 中斷與異常之前的 MIE |
SPP |
Supervisor mode Previous Privilege mode | 紀錄進入 S-mode 中斷與異常之前的特權模式,只有可能是來自 U-mode (SPP = 0) 或 S-mode (SPP = 1) |
VS |
Vector context Status | 向量擴展上下文狀態 |
MPP |
Machine mode Previous Privilege mode | 紀錄進入 M-mode 中斷與異常之前的特權模式,可能來自 U-mode (MPP = 0), S-mode (MPP = 1), M-mode (MPP = 3) |
FS |
FPU context Statue | 浮點數運算單元的上下文狀態 |
XS |
eXtension context Status | 擴展指令集上下文狀態 |
MPRV |
Modify PRiVilege | 是否將執行 load/store 指令的特權模式修改為 MPP |
SUM |
permit Supervisor User Memory access | 允許 S-mode 的 load/store 指令存取 U-mode 分頁, 即分頁表項 (page table entry) 的 U=1 |
MXR |
Make eXecutable Readable | 允許 load 指令讀取只能執行的分頁 |
TVM |
Trap Virtual Memory | 攔截虛擬記憶體操作,TVM = 1 則在存取 satp 或執行 sfence.vma 指令時觸發非法指令異常 |
TW |
Timeout Wait | 攔截 wfi (wait for interrupt) 指令,TW = 1 則在 S-mode 下執行 wfi 時觸發非法指令異常 |
TSR |
Trap SRet | 攔截 sret (supervisor exception return) 指令,TSR = 1 則在執行 sret 時觸發非法指令異常 |
UXL |
User mode XLEN | U-mode 的 XLEN 值 |
SXL |
Supervisor mode XLEN | S-mode 的 XLEN 值 |
SBE |
Supervisor mode Byte Endianness | S-mode 位元組順序 |
MBE |
Machine mode Byte Endianness | M-mode 位元組順序 |
SD |
summarize State Dirty | mstatus.XS 或 mstatus.FS 其中之一是否為 dirty |
SIE
, MIE
, SPIE
, MPIE
, SPP
, MPP
[M|S]IE
設為 1 表示啟用 global interrupt,0 表示關閉mstatus.SIE
= 0 而 sstatus.SIE
= 1 ,此時仍表示關閉 global interrupt[M|S]PIE
與 [M|S]PP
由硬體紀錄進入到 M-mode 之前的 [M|S]IE
與特權模式, 以支援巢狀 Trap, 假設目前在 M-mode 處理完 interrupt 或 exception 之後會根據 mstatus.MPP
用 mret
返回低權限執行環境, 並將 mstatus.MIE
恢復 mstatus.MPIE
[M|S]PP
屬於 WARL (Write Any Values, Reads Legal Values)的欄位,所以 M-mode 軟體可以透過寫入 MPP
再讀出來確認硬體是否支援某個特權模式。透過此 CSR 可以得知目前支援哪些 extension
每位 bit 表示不同的 extension 可根據其 bit 是否舉起來判斷。
相似就放在一起說明了。
預設情況下,所有特權模式的 trap 都由機器模式處理,機器模式也可以透過 mret
指令將其導向到更低的特權模式去做處理,但為了提昇效能,硬體實作可以提供 medeleg
與 mideleg
來指定某些 trap 直接交由更低一層的特權模式處理,假設 mcause 列出的 exception code 為 n, 則 m{i|e}deleg[n] == 1
表示該 trap 由低權限特權模式代理 。考慮 S-mode 代理的系統上,當 trap 被觸發時,mcause
, mepc
, mtval
, mstatus.MPP
, mstatus.MPIE
都將不變,且硬體會做以下事情
scause
暫存器sepc
暫存器stval
暫存器則根據 scause
紀錄不同的資料。mstatus.SPP
mstatus.SIE
於 mstatus.SPIE
,並且將 mstatus.SIE
清為 0 來關閉全域的 S-mode interrupt代理與否由硬體支援,由軟體決定,原則上硬體實作不應該寫死將某個 trap 對應的 m{i|e}deleg
bit 為 1, 因為一個可被代理的 trap 必須支援不代理的使用情境,但可以寫死為 0 代表硬體不支援這項代理,例如 QEMU virt machine 僅支援代理到 S-mode 軟體/計時器/external interrupt,又或者是 M-mode 的 ecall
(exception code = 11) 因為已經沒有比 M-mode 更高權限的特權模式了,所以 medeleg[11]
應該寫死為 0 。
軟體可以將
medeleg
與mideleg
各個 bit 寫入 1 再讀出來確認這個 trap 是可被代理的。
某特權模式下的 trap 不會由更低權限的模式代理,例如 S-mode 的 handler 無法處理 M-mode 的異常,假設 medeleg[2] == 1
的情況下 (mcause 為 2 表示非法指令異常),M-mode 軟體發生非法指令異常是由 M-mode 處理,而不是 S-mode; 同樣假設下,如果 S-mode 發生非法指令異常,則 S-mode 會自己處理該異常。
今天介紹了8種 CSR ,希望都懂啦~如果不懂就多看幾次吧XD
簡單歸納幾個重點,mstatus
每位 bit 都有表達不同的意義,需要多看幾次,才能理解其中的意義,而 medeleg/miedeleg
的目的是希望提高效能,讓一些 trap 可以直接在 S mode 處理,此外低權限的模式無法處理高權限模式。
在介紹這些 CSR 是不是有看到幾個尚未介紹的 CSR 呢(e.g. mtvec、mepc、mcause)? 明天將繼續介紹他們!! 後會有期~