前回の続き。Rocket Chipがどのようにしてプログラムをロードするのかを引き続き解析している。riscv-fesvrのdtm.cc
を見てその動作を解析している。
write_chunk (uint64_t taddr, size_t len, const void* src)
ターゲットのアドレスtaddr
からlen
バイト分、src
データを書き込む。
情報として処理しなければならないのはこの3つだが、これをどのようにして処理するのか。
まずはターゲットアドレスtaddr
をレジスタs0に転送する。転送するためには転送コマンドを送信する必要があるが、これをどのようにして作っているのかというと、
- riscv-fesvr/fesvr/dtm.cc
uint32_t command = AC_ACCESS_REGISTER_TRANSFER | AC_ACCESS_REGISTER_WRITE | AC_AR_SIZE(xlen) | AC_AR_REGNO(S0); RUN_AC_OR_DIE(command, prog, 3, data, xlen/(4*8));
RUN_AC_OR_DIE
というのはrun_abstract_command()
という関数のためのWrapperである。
Abstract Commandというのは何かというとDebug仕様書に書いてあるのだが、Abstract Commandのフォーマットに従って制御される。
Abstract Commandのフォーマットは以下。
- Access Register : Rocket Coreのレジスタにアクセスする。
Write=0, Transfer=1
でデータをコアから取得し、Write=1, Transfer=1
でデータをコアに転送する。 - Postexecが設定されている場合、プログラムバッファを実行する。
プログラムバッファ
このPostExecで設定されるプログラムバッファに書き込まれたプログラムを、Rocket Chipは実行することが出来るのだが、この実行できるプログラムはRISC-Vのプログラムそのままに他ならない。
dtm.cc
にはdefineデスクリプションにより簡単なプログラムが定義されているが、
- riscv-fesvr/fesvr/dtm.cc
#define LOAD(xlen, dst, base, imm) \ (((xlen) == 64 ? 0x00003003 : 0x00002003) \ | ((dst) << 7) | ((base) << 15) | (uint32_t)ENCODE_ITYPE_IMM(imm)) #define STORE(xlen, src, base, imm) \ (((xlen) == 64 ? 0x00003023 : 0x00002023) \ | ((src) << 20) | ((base) << 15) | (uint32_t)ENCODE_STYPE_IMM(imm)) #define JUMP(there, here) (0x6f | (uint32_t)ENCODE_UJTYPE_IMM((there) - (here))) #define BNE(r1, r2, there, here) (0x1063 | ((r1) << 15) | ((r2) << 20) | (uint32_t)ENCODE_SBTYPE_IMM((there) - (here))) #define ADDI(dst, src, imm) (0x13 | ((dst) << 7) | ((src) << 15) | (uint32_t)ENCODE_ITYPE_IMM(imm)) #define SRL(dst, src, sh) (0x5033 | ((dst) << 7) | ((src) << 15) | ((sh) << 20)) #define FENCE_I 0x100f #define EBREAK 0x00100073
このプログラムは、Abstract Commandのプログラムサイズ設定フィールドが1以上に設定されている場合、EBREAKで停止する。
read_chunk()
prog[0] = LOAD(xlen, S1, S0, 0); prog[1] = ADDI(S0, S0, xlen/8); prog[2] = EBREAK;
write_chunk()
prog[0] = STORE(xlen, S1, S0, 0); prog[1] = ADDI(S0, S0, xlen/8); prog[2] = EBREAK;
プログラムをデバッグレジスタにロードしては、Rocket Chipを動かしてプログラムをストアするという方式でメモリに書き込みを行っていることが分かる。