标准RISC-V的分页机制需要在S模式及U模式下才能开启, 而在M模式下的访存并不会进行MMU的地址转换. 但我们在NEMU中进行了简化, 允许M模式的访存也进行地址转换, 这样可以避免引入S模式相关的细节……
然而在 nemu/tools/spike-diff/repo/riscv/mmu.h 的 decode_vm_info() 函数中,如果目前模式是 M 模式,那么会直接返回全零的 vm_info:
https://github.com/NJU-ProjectN/riscv-isa-sim/blob/4740dedcfd58f1b881d570cca0f8b697e17b8a5f/riscv/mmu.h#L496-L499
inline vm_info decode_vm_info(int xlen, bool stage2, reg_t prv, reg_t satp)
{
if (prv == PRV_M) {
return {0, 0, 0, 0, 0};
这导致了 M 模式下作为对照的 Spike 不会去做地址转换:
https://github.com/NJU-ProjectN/riscv-isa-sim/blob/4740dedcfd58f1b881d570cca0f8b697e17b8a5f/riscv/mmu.cc#L384-L390
reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode, bool virt, bool hlvx)
{
reg_t page_mask = (reg_t(1) << PGSHIFT) - 1;
reg_t satp = (virt) ? proc->get_state()->vsatp : proc->get_state()->satp;
vm_info vm = decode_vm_info(proc->max_xlen, false, mode, satp);
if (vm.levels == 0)
return s2xlate(addr, addr & ((reg_t(2) << (proc->xlen-1))-1), type, type, virt, hlvx) & ~page_mask; // zero-extend from xlen
从而导致 difftest 出错,但是 gitbook 中似乎没有提到这一点。如果 PA 的 NEMU 不打算去实现 S 模式的话,这里的修改恐怕是必须的,可能可以加一个 macro 来弄。
然而在 nemu/tools/spike-diff/repo/riscv/mmu.h 的
decode_vm_info()函数中,如果目前模式是 M 模式,那么会直接返回全零的vm_info:https://github.com/NJU-ProjectN/riscv-isa-sim/blob/4740dedcfd58f1b881d570cca0f8b697e17b8a5f/riscv/mmu.h#L496-L499
这导致了 M 模式下作为对照的 Spike 不会去做地址转换:
https://github.com/NJU-ProjectN/riscv-isa-sim/blob/4740dedcfd58f1b881d570cca0f8b697e17b8a5f/riscv/mmu.cc#L384-L390
从而导致 difftest 出错,但是 gitbook 中似乎没有提到这一点。如果 PA 的 NEMU 不打算去实现 S 模式的话,这里的修改恐怕是必须的,可能可以加一个 macro 来弄。