@@ -190,7 +190,8 @@ static inline void icache_invalidate_all(hart_t *vm)
190190
191191void mmu_invalidate (hart_t * vm )
192192{
193- vm -> cache_fetch .n_pages = 0xFFFFFFFF ;
193+ vm -> cache_fetch [0 ].n_pages = 0xFFFFFFFF ;
194+ vm -> cache_fetch [1 ].n_pages = 0xFFFFFFFF ;
194195 /* Invalidate all 8 sets × 2 ways for load cache */
195196 for (int set = 0 ; set < 8 ; set ++ ) {
196197 for (int way = 0 ; way < 2 ; way ++ )
@@ -234,9 +235,11 @@ void mmu_invalidate_range(hart_t *vm, uint32_t start_addr, uint32_t size)
234235 uint32_t end_vpn = (uint32_t ) end_addr >> RV_PAGE_SHIFT ;
235236
236237 /* Cache invalidation for fetch cache */
237- if (vm -> cache_fetch .n_pages >= start_vpn &&
238- vm -> cache_fetch .n_pages <= end_vpn )
239- vm -> cache_fetch .n_pages = 0xFFFFFFFF ;
238+ for (int i = 0 ; i < 2 ; i ++ ) {
239+ if (vm -> cache_fetch [i ].n_pages >= start_vpn &&
240+ vm -> cache_fetch [i ].n_pages <= end_vpn )
241+ vm -> cache_fetch [i ].n_pages = 0xFFFFFFFF ;
242+ }
240243
241244 /* Invalidate load cache: 8 sets × 2 ways */
242245 for (int set = 0 ; set < 8 ; set ++ ) {
@@ -372,23 +375,24 @@ static void mmu_fetch(hart_t *vm, uint32_t addr, uint32_t *value)
372375 uint32_t idx = (addr >> ICACHE_OFFSET_BITS ) & ICACHE_INDEX_MASK ;
373376 uint32_t tag = addr >> (ICACHE_OFFSET_BITS + ICACHE_INDEX_BITS );
374377 icache_block_t * blk = & vm -> icache .block [idx ];
378+ uint32_t vpn = addr >> RV_PAGE_SHIFT ;
379+ uint32_t index = __builtin_parity (vpn ) & 0x1 ;
375380
376381 if (likely (blk -> valid && blk -> tag == tag )) {
377382#ifdef MMU_CACHE_STATS
378- vm -> cache_fetch .hits ++ ;
383+ vm -> cache_fetch [ index ] .hits ++ ;
379384#endif
380385 uint32_t ofs = addr & ICACHE_BLOCK_MASK ;
381386 * value = * (const uint32_t * ) (blk -> base + ofs );
382387 return ;
383388 }
384389
385390#ifdef MMU_CACHE_STATS
386- vm -> cache_fetch .misses ++ ;
391+ vm -> cache_fetch [ index ] .misses ++ ;
387392#endif
388393
389394 /* cache miss, Continue using the original va->pa*/
390- uint32_t vpn = addr >> RV_PAGE_SHIFT ;
391- if (unlikely (vpn != vm -> cache_fetch .n_pages )) {
395+ if (unlikely (vpn != vm -> cache_fetch [index ].n_pages )) {
392396 mmu_translate (vm , & addr , (1 << 3 ), (1 << 6 ), false, RV_EXC_FETCH_FAULT ,
393397 RV_EXC_FETCH_PFAULT );
394398 if (vm -> error )
@@ -397,15 +401,16 @@ static void mmu_fetch(hart_t *vm, uint32_t addr, uint32_t *value)
397401 vm -> mem_fetch (vm , addr >> RV_PAGE_SHIFT , & page_addr );
398402 if (vm -> error )
399403 return ;
400- vm -> cache_fetch .n_pages = vpn ;
401- vm -> cache_fetch .page_addr = page_addr ;
404+ vm -> cache_fetch [ index ] .n_pages = vpn ;
405+ vm -> cache_fetch [ index ] .page_addr = page_addr ;
402406 }
403407
404- * value = vm -> cache_fetch .page_addr [(addr >> 2 ) & MASK (RV_PAGE_SHIFT - 2 )];
408+ * value =
409+ vm -> cache_fetch [index ].page_addr [(addr >> 2 ) & MASK (RV_PAGE_SHIFT - 2 )];
405410
406411 /* fill into the cache */
407412 uint32_t block_off = (addr & RV_PAGE_MASK ) & ~ICACHE_BLOCK_MASK ;
408- blk -> base = (const uint8_t * ) vm -> cache_fetch .page_addr + block_off ;
413+ blk -> base = (const uint8_t * ) vm -> cache_fetch [ index ] .page_addr + block_off ;
409414 blk -> tag = tag ;
410415 blk -> valid = true;
411416}
0 commit comments