四畳半テクノポリス

コロナのストレスで気が狂い、D進した院生

Rocket chipのCPUログを逆アセンブルする

研究でRocketChipというRISC-Vの割とデファクトスタンダードな実装のCPUをいじっているのですが、エラーがよくわからなくて苦しんでいます。

https://github.com/chipsalliance/rocket-chip

このRocketChipは実行するとvcdの他にCPUの実行した命令や、その時のALUのRS1、RS2、プログラムカウンタを含むXX.outというファイルを出力してくれます。このログファイルは次のような感じです

using random seed 1658059470
This emulator compiled with JTAG Remote Bitbang client. To enable, use +jtag_rbb_enable=1.
Listening on port 34039
C0:         27 [1] pc=[00010040] W[r 0=00000208][1] R[r 0=00000000] R[r 0=00000000] inst=[7c105073] DASM(7c105073)
C0:         32 [1] pc=[00010044] W[r10=00000000][1] R[r 0=00000000] R[r 0=00000000] inst=[f1402573] DASM(f1402573)
C0:         33 [1] pc=[00010048] W[r11=00010048][1] R[r 0=00000000] R[r 0=00000000] inst=[00000597] DASM(00000597)
C0:         34 [1] pc=[0001004c] W[r11=00010080][1] R[r11=00010048] R[r 0=00000000] inst=[03858593] DASM(03858593)
C0:         35 [1] pc=[00010050] W[r 0=00000000][1] R[r 0=00000000] R[r 0=00000000] inst=[30405073] DASM(30405073)
C0:         40 [1] pc=[00010054] W[r 0=00000000][0] R[r 0=00000000] R[r 0=00000000] inst=[10500073] DASM(10500073)
C0:         43 [0] pc=[00010058] W[r 0=00000000][0] R[r 0=00000000] R[r 0=00000000] inst=[0000bff5] DASM(0000bff5)
C0:         70 [1] pc=[00000800] W[r 0=00000804][1] R[r 0=00000000] R[r 0=00000000] inst=[00c0006f] DASM(00c0006f)
C0:         72 [1] pc=[0000080c] W[r 0=00000000][0] R[r 0=00000000] R[r 0=00000000] inst=[0ff0000f] DASM(0ff0000f)

この中のDASMという項目がアセンブラなのでどんなプログラムが走っているか知りたいですよね。なのでこの項目に逆アセンブラを適応していきましょう。今回はRISCVのtoolchainに含まれているspike-dasmを使います。このコマンドは行内に含まれるDASM(0x????????)という16進数の記述を見つけると逆アセンブルして置き換えてくれるみたいです。便利ですね。

catにパイプ付けてそのまま実行出来るかと思ったら、なんかうまく行かなかったので次のように実行してます。以下の内容でshellで実行してください。僕の環境だとspike-dasmは/opt/riscv/bin/spike-dasm にありました。

cat <span style="color: #d32f2f">XXX.out</span>| while read line      
do       
/path/to/spike-dasm ${line}
done;

この結果が次のようになります。

This emulator compiled with JTAG Remote Bitbang client. To enable, use +jtag_rbb_enable=1.
Listening on port 34039
C0:         27 [1] pc=[00010040] W[r 0=00000208][1] R[r 0=00000000] R[r 0=00000000] inst=[7c105073] csrwi   unknown_7c1, 0
C0:         32 [1] pc=[00010044] W[r10=00000000][1] R[r 0=00000000] R[r 0=00000000] inst=[f1402573] csrr    a0, mhartid
C0:         33 [1] pc=[00010048] W[r11=00010048][1] R[r 0=00000000] R[r 0=00000000] inst=[00000597] auipc   a1, 0x0
C0:         34 [1] pc=[0001004c] W[r11=00010080][1] R[r11=00010048] R[r 0=00000000] inst=[03858593] addi    a1, a1, 56
C0:         35 [1] pc=[00010050] W[r 0=00000000][1] R[r 0=00000000] R[r 0=00000000] inst=[30405073] csrwi   mie, 0
C0:         40 [1] pc=[00010054] W[r 0=00000000][0] R[r 0=00000000] R[r 0=00000000] inst=[10500073] wfi
C0:         43 [0] pc=[00010058] W[r 0=00000000][0] R[r 0=00000000] R[r 0=00000000] inst=[0000bff5] c.j     pc - 4
C0:         70 [1] pc=[00000800] W[r 0=00000804][1] R[r 0=00000000] R[r 0=00000000] inst=[00c0006f] j       pc + 0xc
C0:         72 [1] pc=[0000080c] W[r 0=00000000][0] R[r 0=00000000] R[r 0=00000000] inst=[0ff0000f] fence

はい、とりあえず何の命令が実行されているか確認出来ますね。これでデバッグがかなり楽になります。 いままで大体1024番地のデバッグ用のレジスタの挙動が意味不明で動かないことが多かったのでそのへんも分かったらまとめていきます。 じゃあさよなら