1.概述由于RISCV的模塊化的指令集的定義,各家都有著自己的實現(xiàn)方式。從當(dāng)前看來,除了標(biāo)準(zhǔn)的CSR外,很多都實現(xiàn)了自己的CSR指令擴展。如何自定義CSR并且讓編譯器能夠識別,本文將進行一定的分析,同時從riscv gcc開發(fā)的角度出發(fā),來分析編譯器開發(fā)的流程。
2.不改變編譯工具鏈實現(xiàn)CSR添加如果想讀寫CSR,可以使用匯編指令進行操作。
void test_csr()
{
int a = 0x00200;
asm volatile(“csrw 0x307,%0”::“r”(a));
}
通過反匯編
riscv32-unknown-elf-objdump -D virt_test.elf 》 1.txt
得到該函數(shù)的匯編代碼
由于編號為0x307的CSR沒有標(biāo)準(zhǔn)定義,所以會直接會體現(xiàn)在匯編函數(shù)中。但是這樣并不會影響功能的使用。
對于這些非標(biāo)準(zhǔn)的CSR的讀寫操作,RISCV GCC并不會根據(jù)特定的編碼序號生成相應(yīng)的名稱。
比如芯來科技為其eclic定義的一條CSR。
如果用標(biāo)準(zhǔn)的GCC進行編譯,那么需要給定CSR地址(0x7ed)。
這樣的實現(xiàn),在寫匯編函數(shù)的時候,給定CSR的地址即可,不能寫名字。比如:
csrw 0x7ed,zero
通過上述的方式,可以完成不改變編譯器的情況下,實現(xiàn)非標(biāo)準(zhǔn)的CSR的操作。
3.在編譯器中集成CSR名稱往往通過匯編去查看時,若沒有CSR名稱,直接去查看CSR的地址,有時候還需要通過CSR的地址,查閱相關(guān)的寄存器手冊,才能明白讀寫哪個寄存器。為了簡化這種操作,可以將CSR的名稱添加到gcc中。這里借用玄鐵C906上的擴展指令進行實驗。
如果不想改變gcc,那么實現(xiàn)上直接可以通過內(nèi)聯(lián)匯編。
void test_csr()
{
int a = 0x00200;
asm volatile(“csrw 0x7c0,%0”::“r”(a));
}
那么最后反匯編得到結(jié)果如下:
這顯然還是不夠直觀。
為了讓其更加的直觀,可以修改RISCV工具鏈。
這里使用的是riscv-gnu-toolchain,目前做編譯器開發(fā)需要對該倉庫的使用非常熟悉。
https://github.com/riscv/riscv-gnu-toolchain.git
將代碼進行clone后,更新子模塊。
git submodule init
git submodule update
其中需要修改的是riscv-gnu-toolchain/riscv-binutils/include/opcode/riscv-opc.h
同時將MXSTATUS的地址添加進去。
這樣就能夠,編譯工具鏈,用生成的編譯工具鏈去編譯代碼,就能夠正常的看到反匯編的執(zhí)行效果了。
這樣,無論是傳遞地址csrw 0x7c0,zero,還是傳遞名稱csrw mxstatus,zero,匯編器都能夠正常的輸出CSR名稱。
通過對編譯器的修改,也是非常的簡單的實現(xiàn)了這個功能。
4.編譯開發(fā)riscv gcc相關(guān)如果要研究riscv gcc的開發(fā)工作,搭建環(huán)境,加快編譯效率很關(guān)鍵。由于編譯工具鏈很大,涉及到的模塊很多,而且編譯的過程很復(fù)雜,為了節(jié)省編譯的時間,可以通過編譯選項來進行約束。
通常情況下,編譯全功能的gcc,可以采用
。/configure --prefix=$PREFIX --enable-multilib --with-cmodel=medany
當(dāng)使能了--enable-multilib,就能夠編譯很多版本的lib庫。
。/riscv64-unknown-elf-gcc --print-multi-lib
。;
rv32i/ilp32;@march=rv32i@mabi=ilp32
rv32ic/ilp32;@march=rv32ic@mabi=ilp32
rv32im/ilp32;@march=rv32im@mabi=ilp32
rv32imc/ilp32;@march=rv32imc@mabi=ilp32
rv32iac/ilp32;@march=rv32iac@mabi=ilp32
rv32imac/ilp32;@march=rv32imac@mabi=ilp32
rv32imafc/ilp32f;@march=rv32imafc@mabi=ilp32f
rv32imafdc/ilp32d;@march=rv32imafdc@mabi=ilp32d
rv32e/ilp32e;@march=rv32e@mabi=ilp32e
rv32ec/ilp32e;@march=rv32ec@mabi=ilp32e
rv32emc/ilp32e;@march=rv32emc@mabi=ilp32e
rv32ema/ilp32e;@march=rv32ema@mabi=ilp32e
rv32emac/ilp32e;@march=rv32emac@mabi=ilp32e
rv32eac/ilp32e;@march=rv32eac@mabi=ilp32e
rv64i/lp64;@march=rv64i@mabi=lp64
rv64im/lp64;@march=rv64im@mabi=lp64
rv64imc/lp64;@march=rv64imc@mabi=lp64
rv64imac/lp64;@march=rv64imac@mabi=lp64
rv64imafc/lp64f;@march=rv64imafc@mabi=lp64f
這樣實際上也是消耗了很多時間,為了解決這個問題,可以指定特定的march和mabi進行編譯和測試,待開發(fā)完成后,發(fā)布時在進行整體編譯。這樣開發(fā)效率會高出很多。
make clean
。/configure --prefix=$RISCV/0727/rv32 --with-arch=rv32gc --with-abi=ilp32d --disable-gdb
make -j8
例如上面的命令,只編譯march為rv32gc,abi為ilp32d的gcc模型。省略掉很多庫的編譯,讓編譯的時間縮短了不少。
5.小結(jié)為自己的處理器添加特定的CSR支持,一種情況下可以使用CSR的地址進行,另外一種就是修改匯編器,前一種方法比較直觀,適合使用riscv通用編譯器的開發(fā)方式進行開發(fā),但是不夠直觀。后一種則需要修改匯編器,并且需要自己編譯工具鏈,比較復(fù)雜,但是使用起來直觀,簡單。
編輯:jq
-
CSR
+關(guān)注
關(guān)注
3文章
118瀏覽量
69968 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4361瀏覽量
63668 -
編譯器
+關(guān)注
關(guān)注
1文章
1649瀏覽量
49682
原文標(biāo)題:riscv gcc中添加自定義的csr支持
文章出處:【微信號:gh_390c588e521e,微信公眾號:嵌入式小作坊】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
HBird SDK設(shè)置構(gòu)建環(huán)境時找不到riscv-nuclei-elf-gcc,且編譯HelloWorld示例時出現(xiàn)error,怎么解決?
ubuntu24.04上安裝gcc工具鏈出現(xiàn)報錯怎么解決?
HBird SDK設(shè)置構(gòu)建環(huán)境時,顯示找不到riscv-nuclei-elf-gcc,為什么?
RISCV 操作常見問題集 - v4
riscv架構(gòu)和arm的區(qū)別是什么
RISCV的主流指令集有哪些?
在ubuntu 24.04下嘗試使用riscv64-linux-musleabi_for_x86_64-pc-linux-gnu工具鏈編譯cv1800大核出現(xiàn)報錯的原因?
https_server編譯報錯的原因?
ESP-IDF 4.4例程hello_world編譯失敗的原因?
Eclipse IDE+IDF- 藍牙例程“A2DP_Source\"編譯錯誤:undefined reference to...\"怎么解決?
使用ESP32 h2開發(fā)低功耗的過程中,無法調(diào)用低功耗接口的API如何解決?
RISCV Debug連接報錯問題

評論