diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 3b04efe56..2004d7336 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -56,10 +56,12 @@ enum { CPUID_TSC = (1 << 4), CPUID_MSR = (1 << 5), CPUID_PAE = (1 << 6), + CPUID_MCE = (1 << 7), CPUID_CMPXCHG8B = (1 << 8), CPUID_AMDSEP = (1 << 10), CPUID_SEP = (1 << 11), CPUID_MTRR = (1 << 12), + CPUID_MCA = (1 << 14), CPUID_CMOV = (1 << 15), CPUID_MMX = (1 << 23), CPUID_FXSR = (1 << 24) @@ -1616,7 +1618,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; } else EAX = EBX = ECX = EDX = 0; break; @@ -1631,7 +1633,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; } else EAX = EBX = ECX = EDX = 0; break; @@ -1645,14 +1647,14 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; } else if (EAX == 0x80000000) { EAX = 0x80000005; EBX = ECX = EDX = 0; } else if (EAX == 0x80000001) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; } else if (EAX == 0x80000002) { EAX = 0x2D444D41; EBX = 0x7428354B; @@ -1682,14 +1684,14 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; } else if (EAX == 0x80000000) { EAX = 0x80000005; EBX = ECX = EDX = 0; } else if (EAX == 0x80000001) { EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; } else if (EAX == 0x80000002) { EAX = 0x2D444D41; EBX = 0x6D74364B; @@ -1729,14 +1731,14 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; break; case 0x80000000: EAX = 0x80000005; break; case 0x80000001: EAX = CPUID + 0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm) 3D pr */ @@ -1772,14 +1774,14 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; break; case 0x80000000: EAX = 0x80000006; break; case 0x80000001: EAX = CPUID + 0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm) 3D+ P */ @@ -1819,14 +1821,14 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; break; case 0x80000000: EAX = 0x80000007; break; case 0x80000001: EAX = CPUID + 0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm)-III P */ @@ -1869,7 +1871,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; } else EAX = EBX = ECX = EDX = 0; break; @@ -1941,7 +1943,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_SEP | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { EAX = 0x00000001; EBX = ECX = 0; @@ -1959,7 +1961,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_SEP | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { EAX = 0x00000001; EBX = ECX = 0; @@ -1977,7 +1979,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; } else if (EAX == 2) { EAX = 0x00000001; EBX = ECX = 0; @@ -2003,7 +2005,7 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR; if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; break; @@ -2012,7 +2014,7 @@ cpu_CPUID(void) break; case 0x80000001: EAX = CPUID; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; break; @@ -2124,6 +2126,8 @@ cpu_RDMSR(void) case CPU_CYRIX3S: EAX = EDX = 0; switch (ECX) { + case 0x00: case 0x01: + break; case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; @@ -2209,6 +2213,9 @@ cpu_RDMSR(void) case CPU_K6_3P: EAX = EDX = 0; switch (ECX) { + case 0x00000000: + case 0x00000001: + break; case 0x0000000e: EAX = msr.tr12; break; @@ -2289,6 +2296,8 @@ amd_k_invalid_rdmsr: #endif EAX = EDX = 0; switch (ECX) { + case 0x00: case 0x01: + break; case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; @@ -2302,6 +2311,8 @@ amd_k_invalid_rdmsr: case CPU_PENTIUM2D: EAX = EDX = 0; switch (ECX) { + case 0x00: case 0x01: + break; case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; @@ -2406,7 +2417,14 @@ amd_k_invalid_rdmsr: EDX = 0x00000000; break; case 0x179: - EAX = EDX = 0x00000000; + EAX = 0x00000105; + EDX = 0x00000000; + break; + case 0x17a: + break; + case 0x17b: + EAX = msr.mcg_ctl & 0xffffffff; + EDX = msr.mcg_ctl >> 32; break; case 0x186: EAX = msr.ecx186 & 0xffffffff; @@ -2457,21 +2475,14 @@ amd_k_invalid_rdmsr: EAX = msr.mtrr_deftype & 0xffffffff; EDX = msr.mtrr_deftype >> 32; break; - case 0x404: - EAX = msr.ecx404 & 0xffffffff; - EDX = msr.ecx404 >> 32; - break; - case 0x408: - EAX = msr.ecx408 & 0xffffffff; - EDX = msr.ecx408 >> 32; - break; - case 0x40c: - EAX = msr.ecx40c & 0xffffffff; - EDX = msr.ecx40c >> 32; - break; + case 0x400: case 0x404: case 0x408: case 0x40c: case 0x410: - EAX = msr.ecx410 & 0xffffffff; - EDX = msr.ecx410 >> 32; + EAX = msr.mca_ctl[(ECX - 0x400) >> 2] & 0xffffffff; + EDX = msr.mca_ctl[(ECX - 0x400) >> 2] >> 32; + break; + case 0x401: case 0x402: case 0x405: case 0x406: + case 0x407: case 0x409: case 0x40d: case 0x40e: + case 0x411: case 0x412: break; case 0x570: EAX = msr.ecx570 & 0xffffffff; @@ -2577,6 +2588,8 @@ cpu_WRMSR(void) case CPU_CYRIX3S: switch (ECX) { + case 0x00: case 0x01: + break; case 0x10: tsc = EAX | ((uint64_t)EDX << 32); break; @@ -2631,6 +2644,8 @@ cpu_WRMSR(void) case CPU_K6_2P: case CPU_K6_3P: switch (ECX) { + case 0x00: case 0x01: + break; case 0x0e: msr.tr12 = EAX & 0x228; break; @@ -2704,6 +2719,8 @@ amd_k_invalid_wrmsr: #endif cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); switch (ECX) { + case 0x00: case 0x01: + break; case 0x10: tsc = EAX | ((uint64_t)EDX << 32); break; @@ -2724,6 +2741,10 @@ amd_k_invalid_wrmsr: case CPU_PENTIUM2: case CPU_PENTIUM2D: switch (ECX) { + case 0x00: case 0x01: + if (EAX || EDX) + x86gpf(NULL, 0); + break; case 0x10: tsc = EAX | ((uint64_t)EDX << 32); break; @@ -2775,6 +2796,13 @@ amd_k_invalid_wrmsr: break; case 0x179: break; + case 0x17a: + if (EAX || EDX) + x86gpf(NULL, 0); + break; + case 0x17b: + msr.mcg_ctl = EAX | ((uint64_t)EDX << 32); + break; case 0x186: msr.ecx186 = EAX | ((uint64_t)EDX << 32); break; @@ -2812,17 +2840,15 @@ amd_k_invalid_wrmsr: case 0x2ff: msr.mtrr_deftype = EAX | ((uint64_t)EDX << 32); break; - case 0x404: - msr.ecx404 = EAX | ((uint64_t)EDX << 32); - break; - case 0x408: - msr.ecx408 = EAX | ((uint64_t)EDX << 32); - break; - case 0x40c: - msr.ecx40c = EAX | ((uint64_t)EDX << 32); - break; + case 0x400: case 0x404: case 0x408: case 0x40c: case 0x410: - msr.ecx410 = EAX | ((uint64_t)EDX << 32); + msr.mca_ctl[(ECX - 0x400) >> 2] = EAX | ((uint64_t)EDX << 32); + break; + case 0x401: case 0x402: case 0x405: case 0x406: + case 0x407: case 0x409: case 0x40d: case 0x40e: + case 0x411: case 0x412: + if (EAX || EDX) + x86gpf(NULL, 0); break; case 0x570: msr.ecx570 = EAX | ((uint64_t)EDX << 32); diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index c9773ad67..18962bab0 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -261,6 +261,9 @@ typedef struct { uint32_t sysenter_esp; /* 0x00000175 - SYSENTER/SYSEXIT MSR's */ uint32_t sysenter_eip; /* 0x00000176 - SYSENTER/SYSEXIT MSR's */ + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */ + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ uint64_t ecx186, ecx187; /* 0x00000186, 0x00000187 */ uint64_t ecx1e0; /* 0x000001e0 */ @@ -282,10 +285,7 @@ typedef struct { uint64_t mtrr_deftype; /* 0x000002ff */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx404; /* 0x00000404 - Model Identification MSR's used by some Acer BIOSes */ - uint64_t ecx408; /* 0x00000408 */ - uint64_t ecx40c; /* 0x0000040c */ - uint64_t ecx410; /* 0x00000410 */ + uint64_t mca_ctl[5]; /* 0x00000400, 0x00000404, 0x00000408, 0x0000040c, 0x00000410 - Machine Check Architecture */ uint64_t ecx570; /* 0x00000570 */ /* IBM 386SLC, 486SLC, and 486BL MSR's */