RISC-Vにおける割り込みの挿入方法を、テストパタンを動かしながら確認している。 以下のテストパタンで、MIP(Machine Interrupt Pending)とMIE(Machine Interrupt Enable)を制御して割り込みを挿入するテストが行われている。
動作確認には、ChipyardのRocketChip環境を使用している。
$ chipyard/sims/verilator $ make CONFIG=RocketConfig debug $ ./simulator-chipyard-RocketConfig-debug +verbose -v rv64mi-p-illegal.vcd ${RISCV}/riscv64-unknown-elf/share/riscv-tests/isa/rv64mi-p-illegal 2>&1 | spike-dasm | tee rv64mi-p-illegal.rocket.log
C0: 564 [1] pc=[00000000800001b0] W[r 7=0000000a00000880][1] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[300023f3] csrr t2, mstatus C0: 567 [1] pc=[00000000800001b4] W[r 7=0000000000000800][1] R[r 7=0000000a00000880] R[r 5=0000000000001800] inst=[0053f3b3] and t2, t2, t0 C0: 568 [1] pc=[00000000800001b8] W[r 0=0000000000000000][0] R[r 6=0000000000000800] R[r 7=0000000000000800] inst=[0c731e63] bne t1, t2, pc + 220 C0: 569 [1] pc=[00000000800001bc] W[r 0=0000000000000080][1] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[34415073] csrwi mip, 2 C0: 590 [1] pc=[00000000800001c0] W[r 0=0000000000000000][1] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[30415073] csrwi mie, 2 C0: 595 [1] pc=[00000000800001c4] W[r 5=00000000800001c4][1] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[00000297] auipc t0, 0x0 C0: 596 [1] pc=[00000000800001c8] W[r 5=0000000080000301][1] R[r 5=00000000800001c4] R[r 0=0000000000000000] inst=[13d28293] addi t0, t0, 317 C0: 597 [1] pc=[00000000800001cc] W[r 8=0000000080000004][1] R[r 5=0000000080000301] R[r 0=0000000000000000] inst=[30529473] csrrw s0, mtvec, t0 C0: 602 [1] pc=[00000000800001d0] W[r 5=0000000080000301][1] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[305022f3] csrr t0, mtvec C0: 605 [1] pc=[00000000800001d4] W[r 5=0000000000000001][1] R[r 5=0000000080000301] R[r 0=0000000000000000] inst=[0012f293] andi t0, t0, 1 C0: 606 [1] pc=[00000000800001d8] W[r 0=0000000000000000][0] R[r 5=0000000000000001] R[r 0=0000000000000000] inst=[00028663] beqz t0, pc + 12 C0: 607 [1] pc=[00000000800001dc] W[r 0=0000000a00000880][1] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[30046073] csrsi mstatus, 8 C0: 612 [0] pc=[00000000800001e0] W[r 0=0000000000000000][0] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[0000006f] j pc + 0x0 C0: 617 [1] pc=[0000000080000304] W[r 0=0000000080000308][1] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[ee1ff06f] j pc - 0x120 C0: 619 [1] pc=[00000000800001e4] W[r 0=0000000080000301][1] R[r 8=0000000080000004] R[r 0=0000000000000000] inst=[30541073] csrw mtvec, s0 C0: 624 [1] pc=[00000000800001e8] W[r 0=0000000000000000][1] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[30315073] csrwi mideleg, 2 C0: 629 [1] pc=[00000000800001ec] W[r 5=00000000800001ec][1] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[00000297] auipc t0, 0x0 C0: 630 [1] pc=[00000000800001f0] W[r 5=0000000080000214][1] R[r 5=00000000800001ec] R[r 0=0000000000000000] inst=[02828293] addi t0, t0, 40 C0: 631 [1] pc=[00000000800001f4] W[r 0=00000000800001e0][1] R[r 5=0000000080000214] R[r 0=0000000000000000] inst=[34129073] csrw mepc, t0 C0: 632 [1] pc=[00000000800001f8] W[r 5=0000000000002000][1] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[000022b7] lui t0, 0x2 C0: 633 [1] pc=[00000000800001fc] W[r 5=0000000000001800][1] R[r 5=0000000000002000] R[r 0=0000000000000000] inst=[8002829b] addiw t0, t0, -2048
MIP=2, MIE=2 を設定しているので、SSIP(Supervisor Software Interrupt Pending)とSSIE(Supervisor software Interrupt Enable)を設定し、mstatus
の3ビット目を1に設定する、つまりmstatus.MIE=1
とすることで割込みが挿入される。
mtvec
は0x80000301
が設定されているため、割り込みが発生するとそのあたりにジャンプするはずだが、Rocketのログでは0x80000304
にジャンプしている。なんでだ?
もう一つ、MIPは自動的にOFFされるのかと思ったが、これは違うようだ。一度割り込みが入った後に自動的にどのように抑え込むかは、Rocket-Chipの実装を確認してみる必要がありそうだ。