You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.9 KiB
129 lines
3.9 KiB
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <inttypes.h>
|
|
#include <string.h>
|
|
|
|
#include <x86/cpuid.h>
|
|
|
|
static void print_cpuid(struct cpuid_regs regs, uint32_t eax) {
|
|
printf("CPUID %08"PRIX32": %08"PRIX32"-%08"PRIX32"-%08"PRIX32"-%08"PRIX32"\n",
|
|
eax, regs.eax, regs.ebx, regs.ecx, regs.edx);
|
|
}
|
|
|
|
static void print_cpuidex(struct cpuid_regs regs, uint32_t eax, uint32_t ecx) {
|
|
printf("CPUID %08"PRIX32": %08"PRIX32"-%08"PRIX32"-%08"PRIX32"-%08"PRIX32" [SL %02"PRIX32"]\n",
|
|
eax, regs.eax, regs.ebx, regs.ecx, regs.edx, 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",
|
|
eax, regs.eax, regs.ebx, regs.ecx, regs.edx, vendor_id);
|
|
} 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;
|
|
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);
|
|
break;
|
|
case UINT32_C(0x00000004):
|
|
for (uint32_t ecx = 0; ; ecx++) {
|
|
const struct cpuid_regs regs = cpuidex(eax, ecx);
|
|
if ((regs.eax & UINT32_C(0x1F)) == 0) {
|
|
break;
|
|
}
|
|
print_cpuidex(regs, eax, ecx);
|
|
}
|
|
break;
|
|
case UINT32_C(0x00000007):
|
|
for (uint32_t ecx = 0; ecx <= max_structured_index; ecx++) {
|
|
const struct cpuid_regs regs = cpuidex(eax, ecx);
|
|
if (ecx == 0) {
|
|
max_structured_index = regs.eax;
|
|
has_sgx = !!(regs.ebx & UINT32_C(0x00000004));
|
|
}
|
|
print_cpuidex(regs, eax, ecx);
|
|
}
|
|
break;
|
|
case UINT32_C(0x0000000B):
|
|
for (uint32_t ecx = 0; ; ecx++) {
|
|
const struct cpuid_regs regs = cpuidex(eax, ecx);
|
|
if ((regs.ecx & UINT32_C(0x0000FF00)) == 0) {
|
|
break;
|
|
}
|
|
print_cpuidex(regs, eax, ecx);
|
|
}
|
|
break;
|
|
case UINT32_C(0x00000012):
|
|
if (has_sgx) {
|
|
for (uint32_t ecx = 0; ; ecx++) {
|
|
const struct cpuid_regs regs = cpuidex(eax, ecx);
|
|
if (ecx >= 2 && (regs.eax & UINT32_C(0x0000000F)) == 0) {
|
|
break;
|
|
}
|
|
print_cpuidex(regs, eax, ecx);
|
|
}
|
|
}
|
|
break;
|
|
case UINT32_C(0x00000014):
|
|
for (uint32_t ecx = 0; ecx <= max_trace_index; ecx++) {
|
|
const struct cpuid_regs regs = cpuidex(eax, ecx);
|
|
if (ecx == 0) {
|
|
max_trace_index = regs.eax;
|
|
}
|
|
print_cpuidex(regs, eax, ecx);
|
|
}
|
|
break;
|
|
case UINT32_C(0x00000017):
|
|
for (uint32_t ecx = 0; ecx <= max_socid_index; ecx++) {
|
|
const struct cpuid_regs regs = cpuidex(eax, ecx);
|
|
if (ecx == 0) {
|
|
max_socid_index = regs.eax;
|
|
}
|
|
print_cpuidex(regs, eax, ecx);
|
|
}
|
|
break;
|
|
default:
|
|
print_cpuid(cpuidex(eax, 0), eax);
|
|
break;
|
|
}
|
|
}
|
|
|
|
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);
|
|
break;
|
|
case UINT32_C(0x80000002):
|
|
case UINT32_C(0x80000003):
|
|
case UINT32_C(0x80000004):
|
|
print_cpuid_brand_string(cpuid(eax), eax);
|
|
break;
|
|
default:
|
|
print_cpuid(cpuidex(eax, 0), eax);
|
|
}
|
|
}
|
|
}
|