Implement machine check exception/architecture MSRs and CPUID flags
This commit is contained in:
112
src/cpu/cpu.c
112
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);
|
||||
|
@@ -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 */
|
||||
|
Reference in New Issue
Block a user