#include "payload_common.h"
#include "payload_utils.h"
#include "test_defs.h"
#define MSR_APICBASE 0x1b
#define MSR_X2APIC_BASE 0x800
#define MSR_X2APIC_MAX 0x8ff
#define APICBASE_X2APIC (1 << 10)
static bool
reg_readable(uint32_t reg)
{
switch (reg) {
case 0x802:
case 0x803:
case 0x808:
case 0x809:
case 0x80a:
case 0x80c:
case 0x80d:
case 0x80e:
case 0x80f:
case 0x810 ... 0x817:
case 0x818 ... 0x81f:
case 0x820 ... 0x827:
case 0x828:
case 0x82f:
case 0x830:
case 0x832:
case 0x833:
case 0x834:
case 0x835:
case 0x836:
case 0x837:
case 0x838:
case 0x839:
case 0x83e:
return (true);
default:
return (false);
}
}
static bool
reg_writable(uint32_t reg)
{
switch (reg) {
case 0x802:
case 0x808:
case 0x80b:
case 0x80d:
case 0x80e:
case 0x80f:
case 0x828:
case 0x82f:
case 0x830:
case 0x832:
case 0x833:
case 0x834:
case 0x835:
case 0x836:
case 0x837:
case 0x838:
case 0x83e:
case 0x83f:
return (true);
default:
return (false);
}
}
void
start(void)
{
uint64_t base = rdmsr(MSR_APICBASE);
if ((base & APICBASE_X2APIC) == 0) {
outb(IOP_TEST_RESULT, TEST_RESULT_FAIL);
}
for (uint32_t msr = MSR_X2APIC_BASE; msr <= MSR_X2APIC_MAX; msr++) {
uint64_t val = 0;
if (reg_readable(msr)) {
val = rdmsr(msr);
}
if (reg_writable(msr)) {
if (msr == 0x828) {
val = 0;
}
wrmsr(msr, val);
}
}
outb(IOP_TEST_RESULT, TEST_RESULT_PASS);
}