RISC-V入门笔记(新手必看!)
目錄
- 什么是RISC-V
- RISC-V 發展
- RISC-V指令集
- RISC-V特權架構
- RISC-V通用寄存器
- RISC-V CSR寄存器
- M模式CSR寄存器
- S模式CSR寄存器
- 總結
筆者學習RISC-V架構有一段時間了,總結了一下入門RISC-V的一些必備知識點。
什么是RISC-V
大家聽過最多的處理器架構可能就是x86和ARM,x86架構主要用在PC端,ARM主要用在移動終端。學習嵌入式的小伙伴肯定都知道ARM,但是ARM是國外的,設計一款ARM架構的芯片,需要經過ARM公司的授權,同時會產生一些費用,這也帶來了一個問題:假如有一天ARM公司不授權怎么辦?
RISC-V架構就是為了解決這個問題的!RISC-V最早在2010年起源于加州大學伯克利分校,由于受夠了現有處理器架構的復雜性和相關知識產權的限制,伯克利大學決定發明一種全新的、簡單且開放免費的指令集架構。
從名字可以看出,RISC-V就是RISC的第五代指令集架構。而RISC-V目標就是“成為一種完全開放的指令集架構,可被任何學術機構或商業組織自由使用”。
RISC-V 發展
2015年成立了RISC-V基金會,這是個非營利性組織,主要為了維護和發展RISC-V。
目前RISC-V的IP供應商大部分是國內的廠商,例如sifive、阿里平頭哥、Andes等等。而基于RISC-V架構設計的芯片廠商也基本是國內的。
可見,基于RISC-V架構設計的芯片,沒有了像ARM需要授權等多方面的限制,可以做到自主可控。但由于RISC-V還處于發展的階段,還有許多不完善的地方,有傳言未來可能會形成x86、ARM、RISC-V三足鼎立的天下,但能夠形成這個局面,還需要大家的共同努力。
RISC-V指令集
RISC-V指令集由“基本指令集 + 擴展指令集”組成。基本指令集是必選的,擴展指令集是可選的。意思就是可以根據你的實際需求,選擇需要使用的指令。例如在一個項目中,如果不需要用到壓縮指令,那么就不需要把壓縮指令添加進來,從而做到定制化,這也是RISC-V的一大特點。
RISC-V指令集有RV32I、RV32E、RV64I、RV64E、RV64I等等,RV代表RISC-V,32/64代表32位或64位,I和E都是基本指令集,在I和E的基礎上,可以添加D(雙精度浮點擴展)、M(整數乘除法)、A(原子擴展)、C(壓縮擴展)等擴展指令。例如,在RV64I基礎上,添加原子、整數乘除法、雙精度浮點、壓縮指令,則該指令集稱為RV64IMADC。
基本指令集和擴展指令集描述如下:
RISC-V特權架構
ARM有7種工作模式,而RISC-V也有不同的模式,這些模式在RISC-V中也被稱為特權架構。
RISC-V總共有四種模式,分別是U、S、H和M模式: U模式被編碼為00,S模式編碼為01,H模式編碼為10,M模式編碼為11。Level越高,等級越高。等級越高,擁有的訪問權限也更高。按照特權等級,有高到低依次為M、H、S、U。
上圖中編碼為10的模式是保留的,這個模式實際上就是H模式,H模式是用作虛擬化,但是目前RISC-V對虛擬化還不太完善,基本不支持。因此上圖并沒有將H模式標出來,而是作為保留。也正是因此,有人經常將RISC-V的模式說成三種U、S和M。
- U模式:User,用戶模式
- S模式:Supervisor,監管者模式
- M模式:Machine,機器模式
以RISC-V Linux為例,Linux應用程序處于U模式,Linux內核/uboot處于S模式,M模式則是OpenSBI。M模式擁有最高訪問權限,Linux內核如果要訪問CSR寄存器,則必須由S模式切換到M模式,由OpenSBI讀取CSR寄存器,然后將數據返回給內核。
M模式是必須要選擇的,RISC-V的裸機代碼都運行在M模式下。
RISC-V通用寄存器
| x0 | zero | 0值寄存器,硬編碼為0,寫入數據忽略,讀取數據為0 |
| x1 | ra | 用于返回地址(return address) |
| x2 | sp | 用于棧指針(stack pointer) |
| x3 | gp | 用于通用指針(global pointer) |
| x4 | tp | 用于線程指針 |
| x5 | t0 | 用于存放臨時數據或者備用鏈接寄存器 |
| x6~x7 | t1~t2 | 用于存放臨時數據寄存器 |
| x8 | s0/fp | 需要保存的寄存器或者幀指針寄存器 |
| x9 | s1 | 需要保存寄存器 |
| x10~x11 | a0~a1 | 函數參數或者返回值寄存器 |
| x12~x17 | a2-a7 | 函數傳遞參數寄存器 |
| x18~x27 | s2-s11 | 需要保存的寄存器 |
| x28~x31 | t3~t6 | 用于存放臨時數據寄存器 |
RISC-V有x0x31共32個通用寄存器,每個通用寄存器都有各自的用途,例如x2是作為sp棧指針、a0a1用來保存函數參數或返回值。x0寄存器被硬編碼為了0,就是個0值寄存器。
ABI名稱相當于這些通用寄存器的別名,在RISC-V匯編當中,都使用ABI名稱來代表這些寄存器。
RISC-V CSR寄存器
CSR是控制狀態寄存器,RISC-V中CSR寄存器,需要使用csrr、csrw、csrrw等特定指令進行訪問。
RISC-V的CSR寄存器,M模式和S模式都有自己的寄存器,但是大體上相同。下面列舉一些常用的CSR
M模式CSR寄存器
mstatus
狀態寄存器,保存了全局中斷使能狀態和其他狀態,例如切換模式前,保存當前模式。
mtvec
異常入口基地址寄存器。保存發生異常時需要跳轉的地址。
medeleg和mideleg
? medeleg是異常委托,mideleg是中斷委托。例如,在M模式下發生異常或中斷時,可以通過這兩個寄存器,將中斷/異常交給S模式或者其他模式處理。
mip和mie
mie是中斷使能寄存器,對需要使能的中斷,在對應位使能。
mip是中斷等待寄存器,表示目前正準備處理的中斷。
hpm
全稱Hardware Performance Monitor,硬件性能單元,用于性能計數。包括了兩類寄存器:mhpmcounter和mhpmevent
- ? mhpmcounter:性能計數器
- ? mhpmevent:用于配置性能事件
mcounteren和mcountinhibit
這兩個也是是hpm相關的寄存器,主要用于控制hpm的使能、計數禁止。
- ? mcounteren:計數器使能
- ? mcountinhibit:禁止計數
mscratch
用于保存M模式指向hart上下文的指針,并在進入M模式的處理程序時,和用戶寄存器交換。
mepc
發生中斷時,當前程序的PC值,保存在mepc中,中斷返回時,會從mepc讀取PC值。
mcause
? 用于保存發生中斷或異常的情況,中斷和異常描述如下:
1代表中斷,0代表異常,每個異常/中斷都有對應的編碼值,通過mcause的值,可以很清楚的知道發生了什么中斷或異常,特別在調試過程,mcause發揮了很大作用。
mvtal
異常值寄存器,例如發生異常時,保存出錯的地址。
S模式CSR寄存器
S模式的CSR和M模式基本上是一樣的,只不過將第一個字母m改為了s,例如mcause改為了scause,mvtal改為了svtal。它們的功能基本相同,這里就不再贅述了。
需要注意的是,S模式除了擁有M模式相同功能的CSR外,另外還增加了一個stap寄存器。
stap寄存器主要是給MMU使用,stap寄存器保存了頁表的基地址,MMU通過stap可以找到第一級頁表,進而找到物理地址。stap寄存器涉及到的內容比較多,關于stap相關內容,以后會詳細展開講講。
總結
以上就是入門RISC-V需要掌握的基本知識,主要還是一些寄存器的作用和特權架構。內容不多,比較基礎,但是要真正掌握RISC-V,還需要多看一下匯編代碼和裸機代碼,才能深刻理解每個寄存器的作用以及不同特權架構下的區別,本文主要是RISC-V入門知識的總結。
原文鏈接: RISC-V 入門筆記(新手必看)
總結
以上是生活随笔為你收集整理的RISC-V入门笔记(新手必看!)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python脚本使用hive正则表达式斜
- 下一篇: C语言笔记含源码(变量、输入输出、分支、