#include "payload_common.h"
#include "payload_utils.h"
int
leaf_cmp(const uint32_t *a, const uint32_t *b)
{
return (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3]);
}
const uint32_t expected_base[] = { 5, 0x74737552, 0x65646978, 0x4f206465 };
struct test_case {
uint32_t func;
uint32_t idx;
uint32_t val_eax;
int fallback;
};
const struct test_case cases[] = {
{
.func = 1,
.val_eax = 0x100,
},
{
.func = 3,
.idx = 0,
.val_eax = 0x300,
},
{
.func = 3,
.idx = 1,
.val_eax = 0x301,
},
{
.func = 4,
.idx = 0,
.val_eax = 0x400,
},
{
.func = 4,
.idx = 2,
.val_eax = 0x402,
},
{
.func = 5,
.val_eax = 0x5,
},
{
.func = 2,
.val_eax = 0,
},
{
.func = 3,
.idx = 2,
.val_eax = 0,
},
{
.func = 4,
.idx = 1,
.val_eax = 0x0,
},
{
.func = 4,
.idx = 0xffff,
.val_eax = 0x0,
},
{
.func = 0x80000000,
.val_eax = 0x80000001,
},
{
.func = 0x80000001,
.idx = 0,
.val_eax = 0x8000,
},
{
.func = 0x80000001,
.idx = 1,
.val_eax = 0x8001,
},
{
.func = 0x80000001,
.idx = 5,
.val_eax = 0,
},
{
.func = 6,
.fallback = 1,
},
{
.func = 0x80000002,
.fallback = 1,
},
};
#define NCASES (sizeof (cases) / sizeof (cases[0]))
void
do_test(int intel_fallback)
{
uint32_t regs[4];
uint32_t expected_fallback[4] = { 0 };
cpuid(0, 0, regs);
if (!leaf_cmp(regs, expected_base)) {
outb(IOP_TEST_RESULT, TEST_RESULT_FAIL);
}
if (intel_fallback) {
cpuid(regs[0], 0, expected_fallback);
}
for (uint_t i = 0; i < NCASES; i++) {
cpuid(cases[i].func, cases[i].idx, regs);
if (cases[i].fallback != 0) {
if (!leaf_cmp(regs, expected_fallback)) {
outb(IOP_TEST_RESULT, TEST_RESULT_FAIL);
}
} else {
if (regs[0] != cases[i].val_eax) {
outb(IOP_TEST_RESULT, TEST_RESULT_FAIL);
}
}
}
}
void
start(void)
{
do_test(1);
outl(IOP_TEST_VALUE, 0);
do_test(0);
outb(IOP_TEST_RESULT, TEST_RESULT_PASS);
}