From ebe49d915577c1136bead41a09360d63dd5d7c26 Mon Sep 17 00:00:00 2001 From: Jim Huang Date: Sun, 2 Nov 2025 23:59:40 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20mmu=5Finvalidate=5Frange=20for=208=C3=972?= =?UTF-8?q?=20set-associative?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function was attempting to access n_pages directly on mmu_cache_set_t structures, which don't have this member. The correct access path is cache_load[set].ways[way].n_pages for the 8-set × 2-way architecture. The fix ensures all 16 load cache entries and 16 store cache entries are properly checked during range invalidation operations (e.g., SFENCE.VMA). --- riscv.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/riscv.c b/riscv.c index 6fbf449..3e00751 100644 --- a/riscv.c +++ b/riscv.c @@ -226,25 +226,28 @@ void mmu_invalidate_range(hart_t *vm, uint32_t start_addr, uint32_t size) end_addr = UINT32_MAX; uint32_t end_vpn = (uint32_t) end_addr >> RV_PAGE_SHIFT; - /* Check each cache entry and invalidate if in range. - * Since we only have 4 cache entries total (fetch: 1, load: 2, store: 1), - * simple sequential checks are sufficient. - */ + /* Cache invalidation for fetch cache */ if (vm->cache_fetch.n_pages >= start_vpn && vm->cache_fetch.n_pages <= end_vpn) vm->cache_fetch.n_pages = 0xFFFFFFFF; - if (vm->cache_load[0].n_pages >= start_vpn && - vm->cache_load[0].n_pages <= end_vpn) - vm->cache_load[0].n_pages = 0xFFFFFFFF; - - if (vm->cache_load[1].n_pages >= start_vpn && - vm->cache_load[1].n_pages <= end_vpn) - vm->cache_load[1].n_pages = 0xFFFFFFFF; + /* Invalidate load cache: 8 sets × 2 ways */ + for (int set = 0; set < 8; set++) { + for (int way = 0; way < 2; way++) { + if (vm->cache_load[set].ways[way].n_pages >= start_vpn && + vm->cache_load[set].ways[way].n_pages <= end_vpn) + vm->cache_load[set].ways[way].n_pages = 0xFFFFFFFF; + } + } - if (vm->cache_store.n_pages >= start_vpn && - vm->cache_store.n_pages <= end_vpn) - vm->cache_store.n_pages = 0xFFFFFFFF; + /* Invalidate store cache: 8 sets × 2 ways */ + for (int set = 0; set < 8; set++) { + for (int way = 0; way < 2; way++) { + if (vm->cache_store[set].ways[way].n_pages >= start_vpn && + vm->cache_store[set].ways[way].n_pages <= end_vpn) + vm->cache_store[set].ways[way].n_pages = 0xFFFFFFFF; + } + } } /* Pre-verify the root page table to minimize page table access during