Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 50 additions & 26 deletions tools/cpuid-dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,47 +24,53 @@ static void print_cpuidex(struct cpuid_regs regs, uint32_t eax, uint32_t ecx) {
ecx);
}

static void print_cpuid_vendor(struct cpuid_regs regs, uint32_t eax) {
if (regs.ebx | regs.ecx | regs.edx) {
char vendor_id[12];
memcpy(&vendor_id[0], &regs.ebx, sizeof(regs.ebx));
memcpy(&vendor_id[4], &regs.edx, sizeof(regs.edx));
memcpy(&vendor_id[8], &regs.ecx, sizeof(regs.ecx));
printf("CPUID %08" PRIX32 ": %08" PRIX32 "-%08" PRIX32 "-%08" PRIX32 "-%08" PRIX32 " [%.12s]\n",
enum cpuid_string_format { REG_ABCD = 1, REG_BDC = 2, REG_BCD = 3, REG_A = 4 };

static void print_cpuid_string(struct cpuid_regs regs, uint32_t eax, enum cpuid_string_format fmt) {
char buf[16];
memset(buf, 0, sizeof(buf));
switch (fmt) {
case REG_ABCD:
memcpy(&buf[0], &regs.eax, sizeof(regs.eax));
memcpy(&buf[4], &regs.ebx, sizeof(regs.ebx));
memcpy(&buf[8], &regs.ecx, sizeof(regs.ecx));
memcpy(&buf[12], &regs.edx, sizeof(regs.edx));
break;
case REG_BCD:
memcpy(&buf[0], &regs.ebx, sizeof(regs.ebx));
memcpy(&buf[4], &regs.ecx, sizeof(regs.ecx));
memcpy(&buf[8], &regs.edx, sizeof(regs.edx));
break;
case REG_BDC:
memcpy(&buf[0], &regs.ebx, sizeof(regs.ebx));
memcpy(&buf[4], &regs.edx, sizeof(regs.ecx));
memcpy(&buf[8], &regs.ecx, sizeof(regs.edx));
break;
case REG_A:
memcpy(&buf[0], &regs.eax, sizeof(regs.eax));
break;
}
if (buf[0]) {
printf("CPUID %08" PRIX32 ": %08" PRIX32 "-%08" PRIX32 "-%08" PRIX32 "-%08" PRIX32 " [%.16s]\n",
eax,
regs.eax,
regs.ebx,
regs.ecx,
regs.edx,
vendor_id);
buf);
} else {
print_cpuid(regs, eax);
}
}

static void print_cpuid_brand_string(struct cpuid_regs regs, uint32_t eax) {
char brand_string[16];
memcpy(&brand_string[0], &regs.eax, sizeof(regs.eax));
memcpy(&brand_string[4], &regs.ebx, sizeof(regs.ebx));
memcpy(&brand_string[8], &regs.ecx, sizeof(regs.ecx));
memcpy(&brand_string[12], &regs.edx, sizeof(regs.edx));
printf("CPUID %08" PRIX32 ": %08" PRIX32 "-%08" PRIX32 "-%08" PRIX32 "-%08" PRIX32 " [%.16s]\n",
eax,
regs.eax,
regs.ebx,
regs.ecx,
regs.edx,
brand_string);
}

int main(int argc, char** argv) {
const uint32_t max_base_index = cpuid(0).eax;
uint32_t max_structured_index = 0, max_trace_index = 0, max_socid_index = 0;
bool has_sgx = false;
for (uint32_t eax = 0; eax <= max_base_index; eax++) {
switch (eax) {
case UINT32_C(0x00000000):
print_cpuid_vendor(cpuid(eax), eax);
print_cpuid_string(cpuid(eax), eax, REG_BDC);
break;
case UINT32_C(0x00000004):
for (uint32_t ecx = 0;; ecx++) {
Expand Down Expand Up @@ -138,16 +144,34 @@ int main(int argc, char** argv) {
}
}

/**
* CPUID[1].ECX bit 31 is supposed to indicate whether or not
* a hypervisor is running, but not all hypervisors set it.
*/
const uint32_t max_hypervisor_index = cpuid(UINT32_C(0x40000000)).eax;
for (uint32_t eax = UINT32_C(0x40000000); eax <= max_hypervisor_index; eax++) {
switch (eax) {
case UINT32_C(0x40000000):
print_cpuid_string(cpuid(eax), eax, REG_BCD);
break;
case UINT32_C(0x40000001):
print_cpuid_string(cpuid(eax), eax, REG_A);
break;
default:
print_cpuid(cpuidex(eax, 0), eax);
}
}

const uint32_t max_extended_index = cpuid(UINT32_C(0x80000000)).eax;
for (uint32_t eax = UINT32_C(0x80000000); eax <= max_extended_index; eax++) {
switch (eax) {
case UINT32_C(0x80000000):
print_cpuid_vendor(cpuid(eax), eax);
print_cpuid_string(cpuid(eax), eax, REG_BDC);
break;
case UINT32_C(0x80000002):
case UINT32_C(0x80000003):
case UINT32_C(0x80000004):
print_cpuid_brand_string(cpuid(eax), eax);
print_cpuid_string(cpuid(eax), eax, REG_ABCD);
break;
default:
print_cpuid(cpuidex(eax, 0), eax);
Expand Down