Add MSR register corresponding to Pentium II Local APIC, because Windows Millenium Edition assumes it is there when cputype=pentium_ii (emulating a Pentium II)

This commit is contained in:
Jonathan Campbell
2021-11-18 23:48:03 -08:00
parent 9c00cd4ab1
commit bbf3131123
2 changed files with 22 additions and 0 deletions

View File

@@ -1,4 +1,10 @@
0.83.20
- Add MSR register 0x0000001B to Pentium II
emulation. DOSBox-X does not emulate a local
APIC but Windows Millenium Edition assumes that
MSR is present and reads/writes it on startup
if DOSBox-X reports itself as a Pentium II.
(joncampbell123)
- While CPU "debug spew" is silenced by default,
remove silencing for RDMSR/WRMSR and
SYSENTER/SYSEXIT debug messages (joncampbell123).

View File

@@ -4128,6 +4128,13 @@ bool CPU_RDMSR() {
if (!enable_msr) return false;
switch (reg_ecx) {
case 0x0000001b: /* Local APIC */
/* NTS: Windows ME assumes this MSR is present if we report ourself as a Pentium II,
* instead of, you know, using CPUID */
if (CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUMII) return false;
reg_edx = reg_eax = 0;
UNBLOCKED_LOG(LOG_CPU,LOG_NORMAL)("RDMSR: Faking Local APIC");
return true;
default:
UNBLOCKED_LOG(LOG_CPU,LOG_NORMAL)("RDMSR: Unknown register 0x%08lx",(unsigned long)reg_ecx);
break;
@@ -4146,6 +4153,15 @@ bool CPU_WRMSR() {
if (!enable_msr) return false;
switch (reg_ecx) {
case 0x0000001b: /* Local APIC */
/* NTS: Windows ME assumes this MSR is present if we report ourself as a Pentium II,
* instead of, you know, using CPUID. It will also set the enable bit, even if
* this register was 0x00000000 when it booted. Fortunately, Windows ME still
* runs properly if we silently ignore the write and leave it 0x00000000. */
if (CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUMII) return false;
UNBLOCKED_LOG(LOG_CPU,LOG_NORMAL)("WRMSR: Faking Local APIC");
if (reg_eax & 0x800) UNBLOCKED_LOG(LOG_CPU,LOG_WARN)("Guest OS is attempting to enable the Local APIC which we do not emulate yet");
return true;
default:
UNBLOCKED_LOG(LOG_CPU,LOG_NORMAL)("WRMSR: Unknown register 0x%08lx (write 0x%08lx:0x%08lx)",(unsigned long)reg_ecx,(unsigned long)reg_edx,(unsigned long)reg_eax);
break;