11#include <stdio.h>
2+ #include <string.h>
23
34#include "common.h"
45#include "device.h"
@@ -180,6 +181,11 @@ static inline uint32_t read_rs2(const hart_t *vm, uint32_t insn)
180181 return vm -> x_regs [decode_rs2 (insn )];
181182}
182183
184+ static inline void ic_invalidate_all (hart_t * vm )
185+ {
186+ memset (& vm -> ic , 0 , sizeof (vm -> ic ));
187+ }
188+
183189/* virtual addressing */
184190
185191void mmu_invalidate (hart_t * vm )
@@ -197,6 +203,7 @@ void mmu_invalidate(hart_t *vm)
197203 vm -> cache_store [set ].ways [way ].n_pages = 0xFFFFFFFF ;
198204 vm -> cache_store [set ].lru = 0 ; /* Reset LRU to way 0 */
199205 }
206+ ic_invalidate_all (vm );
200207}
201208
202209/* Pre-verify the root page table to minimize page table access during
@@ -310,11 +317,27 @@ static void mmu_fence(hart_t *vm, uint32_t insn UNUSED)
310317
311318static void mmu_fetch (hart_t * vm , uint32_t addr , uint32_t * value )
312319{
313- uint32_t vpn = addr >> RV_PAGE_SHIFT ;
314- if (unlikely (vpn != vm -> cache_fetch .n_pages )) {
320+ /* cache hit */
321+ uint32_t idx = (addr >> IC_SHIFT ) & IC_INDEX_MASK ;
322+ uint32_t tag = addr >> (IC_SHIFT + IC_INDEX_BITS );
323+ ic_block_t * blk = & vm -> ic .block [idx ];
324+
325+ if (likely (blk -> valid && blk -> tag == tag )) {
315326#ifdef MMU_CACHE_STATS
316- vm -> cache_fetch .misses ++ ;
327+ vm -> cache_fetch .hits ++ ;
317328#endif
329+ uint32_t ofs = addr & IC_BLOCK_MASK ;
330+ * value = * (const uint32_t * ) (blk -> base + ofs );
331+ return ;
332+ }
333+
334+ #ifdef MMU_CACHE_STATS
335+ vm -> cache_fetch .misses ++ ;
336+ #endif
337+
338+ /* cache miss, Continue using the original va->pa*/
339+ uint32_t vpn = addr >> RV_PAGE_SHIFT ;
340+ if (unlikely (vpn != vm -> cache_fetch .n_pages )) {
318341 mmu_translate (vm , & addr , (1 << 3 ), (1 << 6 ), false, RV_EXC_FETCH_FAULT ,
319342 RV_EXC_FETCH_PFAULT );
320343 if (vm -> error )
@@ -326,12 +349,14 @@ static void mmu_fetch(hart_t *vm, uint32_t addr, uint32_t *value)
326349 vm -> cache_fetch .n_pages = vpn ;
327350 vm -> cache_fetch .page_addr = page_addr ;
328351 }
329- #ifdef MMU_CACHE_STATS
330- else {
331- vm -> cache_fetch .hits ++ ;
332- }
333- #endif
352+
334353 * value = vm -> cache_fetch .page_addr [(addr >> 2 ) & MASK (RV_PAGE_SHIFT - 2 )];
354+
355+ /* fill into the cache */
356+ uint32_t block_off = (addr & RV_PAGE_MASK ) & ~IC_BLOCK_MASK ;
357+ blk -> base = (const uint8_t * ) vm -> cache_fetch .page_addr + block_off ;
358+ blk -> tag = addr >> (IC_SHIFT + IC_INDEX_BITS );
359+ blk -> valid = true;
335360}
336361
337362static void mmu_load (hart_t * vm ,
0 commit comments