diff --git a/src/CPU/cpu.c b/src/CPU/cpu.c index 6e4b1eb93..2c07c438e 100644 --- a/src/CPU/cpu.c +++ b/src/CPU/cpu.c @@ -72,6 +72,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), @@ -1211,7 +1212,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; @@ -1252,7 +1253,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; @@ -1452,7 +1453,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; @@ -1486,7 +1487,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_686); break; @@ -1521,7 +1522,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_686); break; #endif @@ -1556,7 +1557,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 | CR4_OSFXSR; + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE | CR4_OSFXSR; codegen_timing_set(&codegen_timing_686); break; @@ -1681,7 +1682,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; @@ -1769,7 +1770,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 if (EAX == 0x80000000) { @@ -1780,7 +1781,7 @@ void cpu_CPUID() { EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP; } else if (EAX == 0x80000002) { @@ -1831,7 +1832,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; @@ -1926,7 +1927,7 @@ void cpu_CPUID() { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { @@ -1947,7 +1948,7 @@ void cpu_CPUID() { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_SEP | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { @@ -1971,7 +1972,7 @@ void cpu_CPUID() { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; } else if (EAX == 2) { diff --git a/src/ibm.h b/src/ibm.h index ed4eb561d..38cf6e857 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -263,6 +263,7 @@ extern 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 ab8f50fac..548376a56 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1061,9 +1061,30 @@ uint32_t mmutranslate(uint32_t addr, int rw, int is_abrt) /* First check the flags of the page directory entry. */ table_flags = ((uint32_t *)ram)[table_addr >> 2]; - if (mmu_page_fault_check(addr, rw, table_flags & 7, 1, is_abrt) == -1) + if ((table_flags & 0x80) && (cr4 & CR4_PSE)) { - return -1; + /* Do a PDE-style page fault check. */ + if (mmu_page_fault_check(addr, rw, table_flags & 7, 0, is_abrt) == -1) + { + return -1; + } + + /* Since PSE is not enabled, there is no page table, so we do a slightly modified skip to the end. */ + if (is_abrt) + { + mmu_perm = table_flags & 4; + ((uint32_t *)ram)[table_addr >> 2] |= (rw ? PAGE_DIRTY_AND_ACCESSED : PAGE_ACCESSED); + } + + return (table_flags & ~0x3FFFFF) + (addr & 0x3FFFFF); + } + else + { + /* Do a non-PDE-style page fault check. */ + if (mmu_page_fault_check(addr, rw, table_flags & 7, 1, is_abrt) == -1) + { + return -1; + } } page_addr = table_flags & ~0xfff;