From 11389c9d5ada7c983aa0efb15141d5e3286c5ae1 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Fri, 18 Dec 2020 09:49:29 +0530 Subject: [PATCH 1/2] Check and use proc variable in MMU emulation We cannot blindly use proc variable in MMU emulation because external debug emulation instantiates MMU with proc=NULL. Signed-off-by: Anup Patel --- riscv/mmu.cc | 6 +++--- riscv/mmu.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/riscv/mmu.cc b/riscv/mmu.cc index 68d6839e..77d1cf13 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -54,7 +54,7 @@ reg_t mmu_t::translate(reg_t addr, reg_t len, access_type type, uint32_t xlate_f return addr; bool mxr = get_field(proc->state.mstatus, MSTATUS_MXR); - bool virt = proc->state.v; + bool virt = (proc) ? proc->state.v : false; reg_t mode = proc->state.prv; if (type != FETCH) { if (!proc->state.debug_mode && get_field(proc->state.mstatus, MSTATUS_MPRV)) { @@ -153,7 +153,7 @@ void mmu_t::load_slow_path(reg_t addr, reg_t len, uint8_t* bytes, uint32_t xlate else refill_tlb(addr, paddr, host_addr, LOAD); } else if (!mmio_load(paddr, len, bytes)) { - throw trap_load_access_fault(proc->state.v, addr, 0, 0); + throw trap_load_access_fault((proc) ? proc->state.v : false, addr, 0, 0); } if (!matched_trigger) { @@ -182,7 +182,7 @@ void mmu_t::store_slow_path(reg_t addr, reg_t len, const uint8_t* bytes, uint32_ else refill_tlb(addr, paddr, host_addr, STORE); } else if (!mmio_store(paddr, len, bytes)) { - throw trap_store_access_fault(proc->state.v, addr, 0, 0); + throw trap_store_access_fault((proc) ? proc->state.v : false, addr, 0, 0); } } diff --git a/riscv/mmu.h b/riscv/mmu.h index ada20fbd..f7b4a04f 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -253,7 +253,7 @@ public: if (auto host_addr = sim->addr_to_mem(paddr)) load_reservation_address = refill_tlb(vaddr, paddr, host_addr, LOAD).target_offset + vaddr; else - throw trap_load_access_fault(proc->state.v, vaddr, 0, 0); // disallow LR to I/O space + throw trap_load_access_fault((proc) ? proc->state.v : false, vaddr, 0, 0); // disallow LR to I/O space } inline bool check_load_reservation(reg_t vaddr, size_t size) @@ -265,7 +265,7 @@ public: if (auto host_addr = sim->addr_to_mem(paddr)) return load_reservation_address == refill_tlb(vaddr, paddr, host_addr, STORE).target_offset + vaddr; else - throw trap_store_access_fault(proc->state.v, vaddr, 0, 0); // disallow SC to I/O space + throw trap_store_access_fault((proc) ? proc->state.v : false, vaddr, 0, 0); // disallow SC to I/O space } static const reg_t ICACHE_ENTRIES = 1024; From 2aed3d24d987cbb7f63cc0e467814c8884bbf80f Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Fri, 18 Dec 2020 14:16:22 +0530 Subject: [PATCH 2/2] Fix processor_t:take_interrupt() for HS-mode interrupts When deciding HS-mode interrupts in processor_t:take_interrupt() we should use "~state.hideleg" instead of "~MIP_VS_MASK" because VS interrupt bits are writeable in HIDELEG CSR. Signed-off-by: Anup Patel --- riscv/processor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/riscv/processor.cc b/riscv/processor.cc index 76a54172..24131140 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -539,7 +539,7 @@ void processor_t::take_interrupt(reg_t pending_interrupts) enabled_interrupts = pending_interrupts & ~state.mideleg & -m_enabled; if (enabled_interrupts == 0) { // HS-ints have higher priority over VS-ints - deleg = state.mideleg & ~MIP_VS_MASK; + deleg = state.mideleg & ~state.hideleg; status = (state.v) ? state.vsstatus : state.mstatus; hsie = get_field(status, MSTATUS_SIE); hs_enabled = state.prv < PRV_S || (state.prv == PRV_S && hsie);