From 6b3cdad8770f10b70b0e393a6c9ab0e21211b3d6 Mon Sep 17 00:00:00 2001 From: joevt Date: Thu, 24 Aug 2023 23:53:03 -0700 Subject: [PATCH] ppcmmu: Fix BAT update. Need to schedule flush of both BAT and PAT type TLBs because BAT takes precedence over PAT which means updating a BAT can invalidate a PAT. --- cpu/ppc/ppcmmu.cpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/cpu/ppc/ppcmmu.cpp b/cpu/ppc/ppcmmu.cpp index 29dd717..be9323a 100644 --- a/cpu/ppc/ppcmmu.cpp +++ b/cpu/ppc/ppcmmu.cpp @@ -857,6 +857,18 @@ void tlb_flush_pat_entries() gTLBFlushPatEntries = false; } +template +void tlb_flush_all_entries() +{ + if (!gTLBFlushBatEntries && !gTLBFlushPatEntries) + return; + + tlb_flush_entries((TLBFlags)(TLBE_FROM_BAT | TLBE_FROM_PAT)); + + gTLBFlushBatEntries = false; + gTLBFlushPatEntries = false; +} + static void mpc601_bat_update(uint32_t bat_reg) { PPC_BAT_entry *ibat_entry, *dbat_entry; @@ -888,10 +900,11 @@ static void mpc601_bat_update(uint32_t bat_reg) } // MPC601 has unified BATs so we're going to flush both ITLB and DTLB - if (!gTLBFlushBatEntries) { + if (!gTLBFlushBatEntries || !gTLBFlushPatEntries) { gTLBFlushBatEntries = true; - add_ctx_sync_action(&tlb_flush_bat_entries); - add_ctx_sync_action(&tlb_flush_bat_entries); + gTLBFlushPatEntries = true; + add_ctx_sync_action(&tlb_flush_all_entries); + add_ctx_sync_action(&tlb_flush_all_entries); } } @@ -913,9 +926,10 @@ static void ppc_ibat_update(uint32_t bat_reg) bat_entry->phys_hi = ppc_state.spr[upper_reg_num + 1] & hi_mask; bat_entry->bepi = ppc_state.spr[upper_reg_num] & hi_mask; - if (!gTLBFlushBatEntries) { + if (!gTLBFlushBatEntries || !gTLBFlushPatEntries) { gTLBFlushBatEntries = true; - add_ctx_sync_action(&tlb_flush_bat_entries); + gTLBFlushPatEntries = true; + add_ctx_sync_action(&tlb_flush_all_entries); } } @@ -937,9 +951,10 @@ static void ppc_dbat_update(uint32_t bat_reg) bat_entry->phys_hi = ppc_state.spr[upper_reg_num + 1] & hi_mask; bat_entry->bepi = ppc_state.spr[upper_reg_num] & hi_mask; - if (!gTLBFlushBatEntries) { + if (!gTLBFlushBatEntries || !gTLBFlushPatEntries) { gTLBFlushBatEntries = true; - add_ctx_sync_action(&tlb_flush_bat_entries); + gTLBFlushPatEntries = true; + add_ctx_sync_action(&tlb_flush_all_entries); } }