From 52a1ab757ae8d89f2395224740b76ca24db63f48 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 20 Aug 2021 17:25:27 +0200 Subject: [PATCH 1/4] CPL is now forced to 0 when switching from real to protected mode. --- src/cpu/x86_ops_mov_ctrl.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index 16e7aa7fa..17f51b971 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -125,6 +125,9 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat) case 0: if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) flushmmucache(); + /* 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; cr0 = cpu_state.regs[cpu_rm].l; if (cpu_16bitbus) cr0 |= 0x10; @@ -181,6 +184,9 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat) case 0: if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) flushmmucache(); + /* 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; cr0 = cpu_state.regs[cpu_rm].l; if (cpu_16bitbus) cr0 |= 0x10; From b384f58a8b659dd68691d3338c38799ec1f9b732 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 20 Aug 2021 17:27:56 +0200 Subject: [PATCH 2/4] The relocated SMBASE read from the SMM saved state now has bits 24-31 cleared. --- src/cpu/386_common.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index fbb67df1c..77b5ed373 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -592,7 +592,7 @@ smram_restore_state_p5(uint32_t *saved_state) smm_seg_load(&cpu_state.seg_gs); if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) - smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET]; + smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET] & 0x00ffffff; /* Am486/5x86 stuff */ if (!is_pentium) { @@ -1306,6 +1306,11 @@ leave_smm(void) x386_common_log("EAX = %08X, EBX = %08X, ECX = %08X, EDX = %08X, ESI = %08X, EDI = %08X, ESP = %08X, EBP = %08X\n", EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP); x386_common_log("leave_smm()\n"); + + if (cr0 & 1) + pclog("%s mode\n", (cpu_state.eflags & VM_FLAG) ? "V86" : "Protected"); + else + pclog("Real mode\n"); } From fed369c56f18e89c85ad35f108bf476727f96606 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 20 Aug 2021 17:29:12 +0200 Subject: [PATCH 3/4] AMD K6 CPU's are no longer treated as K6 for SMM purposes. --- src/cpu/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 5da0778ab..e29bca7d5 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -381,7 +381,7 @@ cpu_set(void) and the WinChip datasheet claims those are Pentium-compatible as well. AMD Am486DXL/DXL2 also has compatible SMM, or would if not for it's different SMBase*/ is_pentium = (cpu_isintel && (cpu_s->cpu_type >= CPU_i486SX_SLENH) && (cpu_s->cpu_type < CPU_PENTIUMPRO)) || !strcmp(cpu_f->manufacturer, "IDT") || (cpu_s->cpu_type == CPU_Am486DXL); - is_k5 = !strcmp(cpu_f->manufacturer, "AMD") && (cpu_s->cpu_type > CPU_ENH_Am486DX); + is_k5 = !strcmp(cpu_f->manufacturer, "AMD") && (cpu_s->cpu_type > CPU_ENH_Am486DX) && (cpu_s->cpu_type < CPU_K6); is_k6 = (cpu_s->cpu_type >= CPU_K6) && !strcmp(cpu_f->manufacturer, "AMD"); /* The Samuel 2 datasheet claims it's Celeron-compatible. */ is_p6 = (cpu_isintel && (cpu_s->cpu_type >= CPU_PENTIUMPRO)) || !strcmp(cpu_f->manufacturer, "VIA"); From fe5955e4775c3115f695369e79aa53320f4ffd81 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 20 Aug 2021 17:31:18 +0200 Subject: [PATCH 4/4] Removed excess logging from 386_common.c. --- src/cpu/386_common.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 77b5ed373..1c5fa8b3e 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1306,11 +1306,6 @@ leave_smm(void) x386_common_log("EAX = %08X, EBX = %08X, ECX = %08X, EDX = %08X, ESI = %08X, EDI = %08X, ESP = %08X, EBP = %08X\n", EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP); x386_common_log("leave_smm()\n"); - - if (cr0 & 1) - pclog("%s mode\n", (cpu_state.eflags & VM_FLAG) ? "V86" : "Protected"); - else - pclog("Real mode\n"); }