Add PSE-36 (36-bit page size extension) support

Code ported from PCBox
This commit is contained in:
Alexander Babikov
2024-12-21 20:37:26 +05:00
parent 5e2559452c
commit f1a60d8242
3 changed files with 16 additions and 4 deletions

View File

@@ -76,6 +76,7 @@ enum {
CPUID_MCA = (1 << 14), /* Machine Check Architecture */
CPUID_CMOV = (1 << 15), /* Conditional move instructions */
CPUID_PAT = (1 << 16), /* Page Attribute Table */
CPUID_PSE36 = (1 << 17), /* 36-bit Page Size Extension */
CPUID_MMX = (1 << 23), /* MMX technology */
CPUID_FXSR = (1 << 24) /* FXSAVE and FXRSTOR instructions */
};
@@ -1743,8 +1744,10 @@ cpu_set(void)
if (cpu_s->cpu_type >= CPU_PENTIUM2)
cpu_features |= CPU_FEATURE_MMX;
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PAE | CR4_PCE | CR4_PGE;
if (cpu_s->cpu_type == CPU_PENTIUM2D)
if (cpu_s->cpu_type == CPU_PENTIUM2D) {
cpu_CR4_mask |= CR4_OSFXSR;
cpu_features |= CPU_FEATURE_PSE36;
}
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_p6);
@@ -2489,7 +2492,7 @@ cpu_CPUID(void)
} else if (EAX == 1) {
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV;
EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV | CPUID_PSE36;
} else if (EAX == 2) {
EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries
Instruction TLB: 4 MB pages, fully associative, 2 entries

View File

@@ -530,6 +530,7 @@ extern int hasfpu;
#define CPU_FEATURE_3DNOW (1 << 6)
#define CPU_FEATURE_SYSCALL (1 << 7)
#define CPU_FEATURE_3DNOWE (1 << 8)
#define CPU_FEATURE_PSE36 (1 << 9)
extern uint32_t cpu_features;

View File

@@ -320,6 +320,7 @@ mmutranslatereal_normal(uint32_t addr, int rw)
if ((temp & 0x80) && (cr4 & CR4_PSE)) {
/*4MB page*/
uint64_t ret = temp & ~0x3fffff;
if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !cpl_override && !(temp & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) {
cr2 = addr;
temp &= 1;
@@ -336,7 +337,10 @@ mmutranslatereal_normal(uint32_t addr, int rw)
mmu_perm = temp & 4;
rammap(addr2) |= (rw ? 0x60 : 0x20);
return (temp & ~0x3fffff) + (addr & 0x3fffff);
if (cpu_features & CPU_FEATURE_PSE36)
ret |= (uint64_t) (temp & 0x1e000) << 32;
return ret + (addr & 0x3fffff);
}
temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc));
@@ -488,10 +492,14 @@ mmutranslate_noabrt_normal(uint32_t addr, int rw)
if ((temp & 0x80) && (cr4 & CR4_PSE)) {
/*4MB page*/
uint64_t ret = temp & ~0x3fffff;
if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !cpl_override && !(temp & 2) && ((CPL == 3) || (cr0 & WP_FLAG))))
return 0xffffffffffffffffULL;
return (temp & ~0x3fffff) + (addr & 0x3fffff);
if (cpu_features & CPU_FEATURE_PSE36)
ret |= (uint64_t) (temp & 0x1e000) << 32;
return ret + (addr & 0x3fffff);
}
temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc));