From 609f34cc492ad670bcba59f11c3092a156b3d628 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 23 Mar 2025 15:36:05 +0100 Subject: [PATCH] Only flush write MMU cache on WP flag toggle as read and execute MMU cache is not affected by the flag. --- src/cpu/x86_ops_mov_ctrl.h | 10 ++++++---- src/cpu/x86_ops_mov_ctrl_2386.h | 10 ++++++---- src/include/86box/mem.h | 1 + src/mem/mem.c | 15 +++++++++++++++ 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index b4f0c498a..253dc059e 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -184,7 +184,7 @@ opMOV_CRx_r_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); switch (cpu_reg) { case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & (0x00000001 | WP_FLAG)) + if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x00000001) flushmmucache(); else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) { if (is_p6 || cpu_use_dynarec) @@ -193,7 +193,8 @@ opMOV_CRx_r_a16(uint32_t fetchdat) flushmmucache_nopc(); cpu_flush_pending = 1; } - } + } else if ((cpu_state.regs[cpu_rm].l ^ cr0) & WP_FLAG) + flushmmucache_write(); /* Make sure CPL = 0 when switching from real mode to protected mode. */ if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; @@ -249,7 +250,7 @@ opMOV_CRx_r_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); switch (cpu_reg) { case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & (0x00000001 | WP_FLAG)) + if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x00000001) flushmmucache(); else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) { if (is_p6 || cpu_use_dynarec) @@ -258,7 +259,8 @@ opMOV_CRx_r_a32(uint32_t fetchdat) flushmmucache_nopc(); cpu_flush_pending = 1; } - } + } else if ((cpu_state.regs[cpu_rm].l ^ cr0) & WP_FLAG) + flushmmucache_write(); /* Make sure CPL = 0 when switching from real mode to protected mode. */ if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; diff --git a/src/cpu/x86_ops_mov_ctrl_2386.h b/src/cpu/x86_ops_mov_ctrl_2386.h index 13e08a145..8827d29b2 100644 --- a/src/cpu/x86_ops_mov_ctrl_2386.h +++ b/src/cpu/x86_ops_mov_ctrl_2386.h @@ -180,12 +180,13 @@ opMOV_CRx_r_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); switch (cpu_reg) { case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & (0x00000001 | WP_FLAG)) + if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x00000001) flushmmucache(); else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) { flushmmucache_nopc(); cpu_flush_pending = 1; - } + } else if ((cpu_state.regs[cpu_rm].l ^ cr0) & WP_FLAG) + flushmmucache_write(); /* Make sure CPL = 0 when switching from real mode to protected mode. */ if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; @@ -241,12 +242,13 @@ opMOV_CRx_r_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); switch (cpu_reg) { case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & (0x00000001 | WP_FLAG)) + if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x00000001) flushmmucache(); else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) { flushmmucache_nopc(); cpu_flush_pending = 1; - } + } else if ((cpu_state.regs[cpu_rm].l ^ cr0) & WP_FLAG) + flushmmucache_write(); /* Make sure CPL = 0 when switching from real mode to protected mode. */ if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 19a331925..81b46b2fa 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -448,6 +448,7 @@ extern void mem_flush_write_page(uint32_t addr, uint32_t virt); extern void mem_reset_page_blocks(void); extern void flushmmucache(void); +extern void flushmmucache_write(void); extern void flushmmucache_pc(void); extern void flushmmucache_nopc(void); diff --git a/src/mem/mem.c b/src/mem/mem.c index d85b20581..94c4ab788 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -225,6 +225,21 @@ flushmmucache(void) #endif } +void +flushmmucache_write(void) +{ + for (uint16_t c = 0; c < 256; c++) { + if (writelookup[c] != (int) 0xffffffff) { + page_lookup[writelookup[c]] = NULL; + page_lookupp[writelookup[c]] = 4; + writelookup2[writelookup[c]] = LOOKUP_INV; + writelookupp[writelookup[c]] = 4; + writelookup[c] = 0xffffffff; + } + } + mmuflush++; +} + void flushmmucache_pc(void) {