@@ -167,11 +167,19 @@ static inline uint32_t read_rs2(const vm_t *vm, uint32_t insn)
167167
168168/* virtual addressing */
169169
170+ static void mmu_invalidate_caches (vm_t * vm ) {
171+ mmu_cache_reset_ctx (& vm -> mmu_cache_fetch_ctx );
172+ mmu_cache_reset_ctx (& vm -> mmu_cache_load_ctx );
173+ mmu_cache_reset_ctx (& vm -> mmu_cache_store_ctx );
174+ }
175+
176+
170177/* Pre-verify the root page table to minimize page table access during
171178 * translation time.
172179 */
173180static void mmu_set (vm_t * vm , uint32_t satp )
174181{
182+ mmu_invalidate_caches (vm );
175183 if (satp >> 31 ) {
176184 uint32_t * page_table = vm -> mem_page_table (vm , satp & MASK (22 ));
177185 if (!page_table )
@@ -228,16 +236,25 @@ static bool mmu_lookup(const vm_t *vm,
228236 return true;
229237}
230238
231- static void mmu_translate (vm_t * vm ,
232- uint32_t * addr ,
233- const uint32_t access_bits ,
234- const uint32_t set_bits ,
235- const bool skip_privilege_test ,
236- const uint8_t fault ,
237- const uint8_t pfault )
239+ static inline void mmu_translate (vm_t * vm ,
240+ struct _mmu_cache_ctx * cctx ,
241+ uint32_t * addr ,
242+ const uint32_t access_bits ,
243+ const uint32_t set_bits ,
244+ const bool skip_privilege_test ,
245+ const uint8_t fault ,
246+ const uint8_t pfault )
238247{
248+ const uint32_t high_part = * addr & ~MASK (RV_PAGE_SHIFT );
249+ uint32_t caddr = mmu_cache_lookup (cctx , high_part );
250+
239251 /* NOTE: save virtual address, for physical accesses, to set exception. */
240252 vm -> exc_val = * addr ;
253+
254+ if (caddr ) {
255+ * addr = caddr | (* addr & MASK (RV_PAGE_SHIFT ));
256+ return ;
257+ }
241258 if (!vm -> page_table )
242259 return ;
243260
@@ -265,16 +282,18 @@ static void mmu_translate(vm_t *vm,
265282 * pte_ref = new_pte ;
266283
267284 * addr = ((* addr ) & MASK (RV_PAGE_SHIFT )) | (ppn << RV_PAGE_SHIFT );
285+ mmu_cache_insert (cctx , high_part , ppn << RV_PAGE_SHIFT );
268286}
269287
270288static void mmu_fence (vm_t * vm UNUSED , uint32_t insn UNUSED )
271289{
272- /* no-op for now */
290+ mmu_invalidate_caches ( vm );
273291}
274292
275293static void mmu_fetch (vm_t * vm , uint32_t addr , uint32_t * value )
276294{
277- mmu_translate (vm , & addr , (1 << 3 ), (1 << 6 ), false, RV_EXC_FETCH_FAULT ,
295+ mmu_translate (vm , & vm -> mmu_cache_fetch_ctx ,
296+ & addr , (1 << 3 ), (1 << 6 ), false, RV_EXC_FETCH_FAULT ,
278297 RV_EXC_FETCH_PFAULT );
279298 if (vm -> error )
280299 return ;
@@ -287,7 +306,8 @@ static void mmu_load(vm_t *vm,
287306 uint32_t * value ,
288307 bool reserved )
289308{
290- mmu_translate (vm , & addr , (1 << 1 ) | (vm -> sstatus_mxr ? (1 << 3 ) : 0 ),
309+ mmu_translate (vm , & vm -> mmu_cache_load_ctx ,
310+ & addr , (1 << 1 ) | (vm -> sstatus_mxr ? (1 << 3 ) : 0 ),
291311 (1 << 6 ), vm -> sstatus_sum && vm -> s_mode , RV_EXC_LOAD_FAULT ,
292312 RV_EXC_LOAD_PFAULT );
293313 if (vm -> error )
@@ -306,7 +326,8 @@ static bool mmu_store(vm_t *vm,
306326 uint32_t value ,
307327 bool cond )
308328{
309- mmu_translate (vm , & addr , (1 << 2 ), (1 << 6 ) | (1 << 7 ),
329+ mmu_translate (vm , & vm -> mmu_cache_store_ctx ,
330+ & addr , (1 << 2 ), (1 << 6 ) | (1 << 7 ),
310331 vm -> sstatus_sum && vm -> s_mode , RV_EXC_STORE_FAULT ,
311332 RV_EXC_STORE_PFAULT );
312333 if (vm -> error )
@@ -336,6 +357,8 @@ void vm_set_exception(vm_t *vm, uint32_t cause, uint32_t val)
336357
337358void vm_trap (vm_t * vm )
338359{
360+ mmu_invalidate_caches (vm );
361+
339362 /* Fill exception fields */
340363 vm -> scause = vm -> exc_cause ;
341364 vm -> stval = vm -> exc_val ;
@@ -357,6 +380,8 @@ void vm_trap(vm_t *vm)
357380
358381static void op_sret (vm_t * vm )
359382{
383+ mmu_invalidate_caches (vm );
384+
360385 /* Restore from stack */
361386 vm -> pc = vm -> sepc ;
362387 vm -> s_mode = vm -> sstatus_spp ;
0 commit comments