Implement machine check exception/architecture MSRs and CPUID flags

This commit is contained in:
Alexander Babikov
2021-10-17 02:57:13 +05:00
parent 1a04b93165
commit ee79348885
2 changed files with 73 additions and 47 deletions

View File

@@ -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);

View File

@@ -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 */