Implement missing IBM, AMD and Cyrix MSRs

This commit is contained in:
Alexander Babikov
2024-02-04 21:39:07 +05:00
parent 65f40ca71d
commit e54b57641c
2 changed files with 127 additions and 22 deletions

View File

@@ -2590,7 +2590,8 @@ cpu_RDMSR(void)
/* Cache Region Control Register */
case 0x1001:
EAX = msr.ibm_crcr & 0xffffffffff;
EAX = msr.ibm_crcr & 0xffffffff;
EDX = (msr.ibm_crcr >> 32) & 0x0000ffff;
break;
/* Processor Operation Register */
@@ -2598,6 +2599,12 @@ cpu_RDMSR(void)
if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi)
EAX = msr.ibm_por2 & 0x3f000000;
break;
/* Processor Control Register */
case 0x1004:
if (cpu_s->cpu_type > CPU_IBM486SLC)
EAX = msr.ibm_pcr & 0x00d6001a;
break;
}
break;
@@ -2780,12 +2787,20 @@ cpu_RDMSR(void)
case CPU_K6_3:
case CPU_K6_2P:
case CPU_K6_3P:
EAX = EDX = 0;
EAX = 0;
/* EDX is left unchanged when reading this MSR! */
if (ECX != 0x82)
EDX = 0;
switch (ECX) {
/* Machine Check Address Register */
case 0x00000000:
EAX = msr.mcar & 0xffffffff;
EDX = msr.mcar >> 32;
break;
/* Machine Check Type Register */
case 0x00000001:
EAX = msr.mctr & 0xffffffff;
EDX = msr.mctr >> 32;
break;
/* Test Register 12 */
case 0x0000000e:
@@ -2796,11 +2811,32 @@ cpu_RDMSR(void)
EAX = tsc & 0xffffffff;
EDX = tsc >> 32;
break;
/* Array Access Register */
case 0x00000082:
if (cpu_s->cpu_type > CPU_5K86)
goto amd_k_invalid_rdmsr;
EAX = msr.amd_aar & 0xffffffff;
/* EDX is left unchanged! */
break;
/* Hardware Configuration Register */
case 0x00000083:
EAX = msr.amd_hwcr & 0xffffffff;
EDX = msr.amd_hwcr >> 32;
break;
/* Write Allocate Top-of-Memory and Control Register */
case 0x00000085:
if (cpu_s->cpu_type != CPU_5K86)
goto amd_k_invalid_rdmsr;
EAX = msr.amd_watmcr & 0xffffffff;
EDX = msr.amd_watmcr >> 32;
break;
/* Write Allocate Programmable Memory Range Register */
case 0x00000086:
if (cpu_s->cpu_type != CPU_5K86)
goto amd_k_invalid_rdmsr;
EAX = msr.amd_wapmrr & 0xffffffff;
EDX = msr.amd_wapmrr >> 32;
break;
/* Extended Feature Enable Register */
case 0xc0000080:
EAX = msr.amd_efer & 0xffffffff;
@@ -3033,16 +3069,37 @@ pentium_invalid_rdmsr:
case CPU_CxGX1:
case CPU_Cx6x86MX:
switch (ECX) {
/* Machine Check Exception Address */
case 0x00:
/* Machine Check Exception Type */
case 0x01:
/* Test Data */
case 0x03:
EAX = msr.tr3;
break;
/* Test Address */
case 0x04:
EAX = msr.tr4;
break;
/* Test Command/Status */
case 0x05:
EAX = msr.tr5;
break;
/* Time Stamp Counter */
case 0x10:
EAX = tsc & 0xffffffff;
EDX = tsc >> 32;
break;
/* Performance Monitor - Control and Event Select */
case 0x11:
EAX = msr.cesr;
break;
/* Performance Monitor - Event Counter 0 */
case 0x12:
EAX = msr.pmc[0] & 0xffffffff;
EDX = msr.pmc[0] >> 32;
break;
/* Performance Monitor - Event Counter 1 */
case 0x13:
EAX = msr.pmc[1] & 0xffffffff;
EDX = msr.pmc[1] >> 32;
break;
}
cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX);
break;
@@ -3331,8 +3388,8 @@ cpu_WRMSR(void)
switch (cpu_s->cpu_type) {
case CPU_IBM386SLC:
case CPU_IBM486BL:
case CPU_IBM486SLC:
case CPU_IBM486BL:
switch (ECX) {
/* Processor Operation Register */
case 0x1000:
@@ -3341,13 +3398,18 @@ cpu_WRMSR(void)
break;
/* Cache Region Control Register */
case 0x1001:
msr.ibm_crcr = EAX & 0xffffffffff;
msr.ibm_crcr = EAX | ((uint64_t) (EDX & 0x0000ffff) << 32);
break;
/* Processor Operation Register */
case 0x1002:
if ((cpu_s->cpu_type > CPU_IBM386SLC) && cpu_s->multi)
msr.ibm_por2 = EAX & 0x3f000000;
break;
/* Processor Control Register */
case 0x1004:
if (cpu_s->cpu_type > CPU_IBM486SLC)
msr.ibm_pcr = EAX & 0x00d6001a;
break;
}
break;
@@ -3521,22 +3583,45 @@ cpu_WRMSR(void)
case CPU_K6_3P:
switch (ECX) {
/* Machine Check Address Register */
case 0x00:
case 0x00000000:
if (cpu_s->cpu_type > CPU_5K86)
msr.mcar = EAX | ((uint64_t) EDX << 32);
break;
/* Machine Check Type Register */
case 0x01:
case 0x00000001:
if (cpu_s->cpu_type > CPU_5K86)
msr.mctr = EAX | ((uint64_t) EDX << 32);
break;
/* Test Register 12 */
case 0x0e:
msr.tr12 = EAX & 0x228;
case 0x0000000e:
msr.tr12 = EAX & 0x8;
break;
/* Time Stamp Counter */
case 0x10:
case 0x00000010:
tsc = EAX | ((uint64_t) EDX << 32);
break;
/* Array Access Register */
case 0x00000082:
if (cpu_s->cpu_type > CPU_5K86)
goto amd_k_invalid_wrmsr;
msr.amd_aar = EAX | ((uint64_t) EDX << 32);
break;
/* Hardware Configuration Register */
case 0x83:
case 0x00000083:
msr.amd_hwcr = EAX | ((uint64_t) EDX << 32);
break;
/* Write Allocate Top-of-Memory and Control Register */
case 0x00000085:
if (cpu_s->cpu_type != CPU_5K86)
goto amd_k_invalid_wrmsr;
msr.amd_watmcr = EAX | ((uint64_t) EDX << 32);
break;
/* Write Allocate Programmable Memory Range Register */
case 0x00000086:
if (cpu_s->cpu_type != CPU_5K86)
goto amd_k_invalid_wrmsr;
msr.amd_wapmrr = EAX | ((uint64_t) EDX << 32);
break;
/* Extended Feature Enable Register */
case 0xc0000080:
temp = EAX | ((uint64_t) EDX << 32);
@@ -3757,15 +3842,31 @@ pentium_invalid_wrmsr:
case CPU_Cx6x86MX:
cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX);
switch (ECX) {
/* Machine Check Exception Address */
case 0x00:
/* Machine Check Exception Type */
case 0x01:
break;
/* Test Data */
case 0x03:
msr.tr3 = EAX;
/* Test Address */
case 0x04:
msr.tr4 = EAX;
/* Test Command/Status */
case 0x05:
msr.tr5 = EAX & 0x008f0f3b;
/* Time Stamp Counter */
case 0x10:
tsc = EAX | ((uint64_t) EDX << 32);
break;
/* Performance Monitor - Control and Event Select */
case 0x11:
msr.cesr = EAX & 0x7ff07ff;
break;
/* Performance Monitor - Event Counter 0 */
case 0x12:
msr.pmc[0] = EAX | ((uint64_t) EDX << 32);
break;
/* Performance Monitor - Event Counter 1 */
case 0x13:
msr.pmc[1] = EAX | ((uint64_t) EDX << 32);
break;
}
break;
#endif

View File

@@ -230,6 +230,7 @@ typedef struct {
uint64_t ibm_por; /* 0x00001000 - 386SLC and later */
uint64_t ibm_crcr; /* 0x00001001 - 386SLC and later */
uint64_t ibm_por2; /* 0x00001002 - 486SLC and later */
uint64_t ibm_pcr; /* 0x00001004 - 486BL3 */
/* IDT WinChip C6/2/VIA Cyrix III MSRs */
uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */
@@ -239,11 +240,14 @@ typedef struct {
uint32_t mcr_ctrl; /* 0x00000120 (IDT) */
/* AMD K5/K6 MSRs */
uint64_t amd_hwcr; /* 0x00000083 - all K5 and K6 */
uint64_t amd_aar; /* 0x00000082 - all K5 */
uint64_t amd_hwcr; /* 0x00000083 - all K5 and all K6 */
uint64_t amd_watmcr; /* 0x00000085 - K5 Model 1 and later */
uint64_t amd_wapmrr; /* 0x00000086 - K5 Model 1 and later */
uint64_t amd_efer; /* 0xc0000080 - all K5 and K6 */
uint64_t amd_efer; /* 0xc0000080 - all K5 and all K6 */
uint64_t amd_star; /* 0xc0000081 - K6-2 and later */
uint64_t amd_whcr; /* 0xc0000082 - all K5 and K6 */
uint64_t amd_whcr; /* 0xc0000082 - all K5 and all K6 */
uint64_t amd_uwccr; /* 0xc0000085 - K6-2C and later */
uint64_t amd_epmr; /* 0xc0000086 - K6-III+/2+ only */
uint64_t amd_psor; /* 0xc0000087 - K6-2C and later */