RISC-VのISSを引き続き修正している。 MMUの実装と、ベクタの部分が間違っていたので修正した。RISC-Vでは、ECALLという命令を使って一つ上の権限に移ることができる。
RISC-Vには4つの権限があり、上から
- Machine Mode
- Hypervisor Mode
- Superviros Mode
- User Mode
ECALL命令は、どのモードから遷移するかで飛ぶベクタアドレスが異なっている。Privileged Manualには以下のように記述されていた。
ECALL命令の動作を以下のように修正した。
void InstEnv::RISCV_INST_ECALL (Word_t inst_hex) { Addr_t current_pc = m_env->GetPC (); m_env->CSRWrite (SYSREG_ADDR_MEPC, current_pc); PrivMode curr_priv = m_env->GetPrivMode (); Addr_t jmp_addr; switch (curr_priv) { case PrivUser : { m_env->DebugPrint ("ECALL from PrivUser\n"); m_env->CSRWrite (SYSREG_ADDR_SCAUSE, Except_EcallFromUMode); m_env->SetPrivMode (PrivSupervisor); jmp_addr = 0x100; break; } case PrivSupervisor : { m_env->DebugPrint ("ECALL from SuperUser\n"); m_env->CSRWrite (SYSREG_ADDR_MCAUSE, Except_EcallFromSMode); m_env->SetPrivMode (PrivMachine); jmp_addr = 0x140; break; } case PrivHypervisor : { m_env->DebugPrint ("ECALL from Hypervisor\n"); m_env->CSRWrite (SYSREG_ADDR_MCAUSE, Except_EcallFromHMode); m_env->SetPrivMode (PrivMachine); jmp_addr = 0x180; break; } case PrivMachine : { m_env->DebugPrint ("ECALL from Machine\n"); m_env->CSRWrite (SYSREG_ADDR_MCAUSE, Except_EcallFromMMode); m_env->SetPrivMode (PrivMachine); jmp_addr = 0x1c0; break; } } m_env->SetPC (jmp_addr); m_env->SetJumped (true); }
jmp_addrを元のモードによって修正している。
現在のパタンの通過率は、以下のようになった。
$ ctest Test project /home/vagrant/swimmer_iss/build_riscv Start 1: rv32mi-p-csr 1/434 Test #1: rv32mi-p-csr .....................***Failed 0.29 sec Start 2: rv32mi-p-illegal 2/434 Test #2: rv32mi-p-illegal ................. Passed 0.00 sec Start 3: rv32mi-p-ma_addr 3/434 Test #3: rv32mi-p-ma_addr .................***Failed 0.00 sec Start 4: rv32mi-p-ma_fetch ... Start 434: rv64ui-v-xori 434/434 Test #434: rv64ui-v-xori .................... Passed 0.02 sec 73% tests passed, 118 tests failed out of 434 Total Test time (real) = 7.52 sec
とりあえず73%まで通過するようになった。