diff --git a/tools/cpuid-dump.c b/tools/cpuid-dump.c index 1a65510f..febdc682 100644 --- a/tools/cpuid-dump.c +++ b/tools/cpuid-dump.c @@ -24,39 +24,45 @@ 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], ®s.ebx, sizeof(regs.ebx)); - memcpy(&vendor_id[4], ®s.edx, sizeof(regs.edx)); - memcpy(&vendor_id[8], ®s.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], ®s.eax, sizeof(regs.eax)); + memcpy(&buf[4], ®s.ebx, sizeof(regs.ebx)); + memcpy(&buf[8], ®s.ecx, sizeof(regs.ecx)); + memcpy(&buf[12], ®s.edx, sizeof(regs.edx)); + break; + case REG_BCD: + memcpy(&buf[0], ®s.ebx, sizeof(regs.ebx)); + memcpy(&buf[4], ®s.ecx, sizeof(regs.ecx)); + memcpy(&buf[8], ®s.edx, sizeof(regs.edx)); + break; + case REG_BDC: + memcpy(&buf[0], ®s.ebx, sizeof(regs.ebx)); + memcpy(&buf[4], ®s.edx, sizeof(regs.ecx)); + memcpy(&buf[8], ®s.ecx, sizeof(regs.edx)); + break; + case REG_A: + memcpy(&buf[0], ®s.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], ®s.eax, sizeof(regs.eax)); - memcpy(&brand_string[4], ®s.ebx, sizeof(regs.ebx)); - memcpy(&brand_string[8], ®s.ecx, sizeof(regs.ecx)); - memcpy(&brand_string[12], ®s.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; @@ -64,7 +70,7 @@ int main(int argc, char** argv) { 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++) { @@ -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);