From c73d357a1a72caf8c905230990e8aec7f55d5ed6 Mon Sep 17 00:00:00 2001 From: Anatoly Parshintsev Date: Tue, 14 Jul 2026 12:19:54 +0300 Subject: [PATCH] get rid of mmio_ok checks before this patch, hart access to debug module region was controlled in two places: 1. pmp_ok performed the normal architectural PMP checks, but **bypassed** them for debug module region accesses while the hart was in debug mode. 2. mmio_ok **rejected** debug module region accesses from harts outside debug mode. Processor-less debug_mmu accesses remained allowed. This patch moves the control decision entirely to pmp_ok routine: **allow** debug module regoin accesses in debug mode and **deny** them otherwise. This check is run before the no-PMP fast path, making mmio_ok redundant. Additionally, we flush the TLB on processor reset because it may contain stale entries from the time while hart was in debug mode. --- riscv/mmu.cc | 27 ++++++--------------------- riscv/mmu.h | 1 - riscv/processor.cc | 1 + 3 files changed, 7 insertions(+), 22 deletions(-) diff --git a/riscv/mmu.cc b/riscv/mmu.cc index 0db3f456..815e75a1 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -158,20 +158,8 @@ static reg_t reg_from_bytes(size_t len, const uint8_t* bytes) return res; } -bool mmu_t::mmio_ok(reg_t paddr, size_t len, access_type UNUSED type) -{ - // Disallow access to debug region when not in debug mode - if (proc && sim && sim->is_debug_module_access(paddr, len) && !proc->state.debug_mode) - return false; - - return true; -} - bool mmu_t::mmio_fetch(reg_t paddr, size_t len, uint8_t* bytes) { - if (!mmio_ok(paddr, len, FETCH)) - return false; - return sim->mmio_fetch(paddr, len, bytes); } @@ -191,9 +179,6 @@ bool mmu_t::mmio(reg_t paddr, size_t len, uint8_t* bytes, access_type type) bool naturally_aligned = (paddr & (len - 1)) == 0; if (power_of_2 && naturally_aligned) { - if (!mmio_ok(paddr, len, type)) - return false; - if (type == STORE) return sim->mmio_store(paddr, len, bytes); else @@ -533,13 +518,13 @@ std::optional mmu_t::pmp_lookup(reg_t addr, reg_t len, size bool mmu_t::pmp_ok(reg_t addr, reg_t len, access_type type, reg_t mode, bool hlvx) { - if (!proc || proc->n_pmp == 0) - return true; - // The debug module implementation relies on firmware (ROM) owned by spike. - // When executing code from this firmware we keep target PMP rules from - // blocking the simulator-owned debug firmware. - if (proc->state.debug_mode && sim && sim->is_debug_module_access(addr, len)) + // The Debug Module address region is hidden from normal software. + // A hart can access it only in debug mode. + if (proc && sim && sim->is_debug_module_access(addr, len)) + return proc->state.debug_mode; + + if (!proc || proc->n_pmp == 0) return true; if (auto pmp = pmp_lookup(addr, len, 0, proc->n_pmp); pmp.has_value()) diff --git a/riscv/mmu.h b/riscv/mmu.h index 90a67e6e..06c2574d 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -444,7 +444,6 @@ private: bool mmio_load(reg_t paddr, size_t len, uint8_t* bytes); bool mmio_store(reg_t paddr, size_t len, const uint8_t* bytes); bool mmio(reg_t paddr, size_t len, uint8_t* bytes, access_type type); - bool mmio_ok(reg_t paddr, size_t len, access_type type); void check_triggers(triggers::operation_t operation, reg_t addr, bool virt, std::size_t data_size, const std::uint8_t* bytes); diff --git a/riscv/processor.cc b/riscv/processor.cc index 08e24da3..ceaab3e9 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -150,6 +150,7 @@ void processor_t::reset() { xlen = isa.get_max_xlen(); state.reset(this, isa.get_max_isa()); + mmu->flush_tlb(); if (any_vector_extensions()) VU.reset(); in_wfi = false;