From dc511447dfe904ee17928e3e249b71cf90625c7c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 16 Jul 2017 21:24:09 +0100 Subject: [PATCH] Added Page Size Extension (4MB pages) to Pentium CPUs. --- src/cpu.c | 9 +++++---- src/ibm.h | 1 + src/mem.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index 9552c1d..2610ca3 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -52,6 +52,7 @@ enum { CPUID_FPU = (1 << 0), CPUID_VME = (1 << 1), + CPUID_PSE = (1 << 3), CPUID_TSC = (1 << 4), CPUID_MSR = (1 << 5), CPUID_CMPXCHG8B = (1 << 8), @@ -978,7 +979,7 @@ void cpu_set() cpu_hasMSR = 1; cpu_hasCR4 = 1; cpu_hasVME = 1; - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; codegen_timing_set(&codegen_timing_pentium); break; @@ -1019,7 +1020,7 @@ void cpu_set() cpu_hasMSR = 1; cpu_hasCR4 = 1; cpu_hasVME = 1; - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; codegen_timing_set(&codegen_timing_pentium); break; @@ -1299,7 +1300,7 @@ void cpu_CPUID() { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; } else EAX = 0; @@ -1317,7 +1318,7 @@ void cpu_CPUID() { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; } else EAX = 0; diff --git a/src/ibm.h b/src/ibm.h index df8dcfa..468dd1e 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -251,6 +251,7 @@ uint32_t dr[8]; #define CR4_VME (1 << 0) #define CR4_PVI (1 << 1) +#define CR4_PSE (1 << 4) #define IOPL ((flags>>12)&3) diff --git a/src/mem.c b/src/mem.c index 031d1f8..25fb4f7 100644 --- a/src/mem.c +++ b/src/mem.c @@ -873,6 +873,32 @@ uint32_t mmutranslatereal(uint32_t addr, int rw) }*/ return -1; } + + if ((temp & 0x80) && (cr4 & CR4_PSE)) + { + /*4MB page*/ + if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (CPL == 3 || cr0 & WP_FLAG))) + { +// if (!nopageerrors) pclog("Page not present! %08X %08X %02X %02X %i %08X %04X:%08X %04X:%08X %i %i %i\n",addr,temp,opcode,opcode2,frame,rmdat32, CS,pc,SS,ESP,ins,CPL,rw); + + cr2 = addr; + temp &= 1; + if (CPL == 3) + temp |= 4; + if (rw) + temp |= 2; + cpu_state.abrt = ABRT_PF; + abrt_error = temp; + + return -1; + } + + mmu_perm = temp & 4; + ((uint32_t *)ram)[addr2>>2] |= 0x20; + + return (temp & ~0x3fffff) + (addr & 0x3fffff); + } + temp=((uint32_t *)ram)[((temp&~0xFFF)+((addr>>10)&0xFFC))>>2]; temp3=temp&temp2; // if (output == 3) pclog("Do translate %08X %08X\n", temp, temp3); @@ -921,6 +947,15 @@ uint32_t mmutranslate_noabrt(uint32_t addr, int rw) if (!(temp&1)) return -1; + if ((temp & 0x80) && (cr4 & CR4_PSE)) + { + /*4MB page*/ + if ((CPL == 3 && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (CPL == 3 || cr0 & WP_FLAG))) + return -1; + + return (temp & ~0x3fffff) + (addr & 0x3fffff); + } + temp=((uint32_t *)ram)[((temp&~0xFFF)+((addr>>10)&0xFFC))>>2]; temp3=temp&temp2;