From 532953da4d3bb2fb2e8bbd3ccbd2dc5eb5956351 Mon Sep 17 00:00:00 2001 From: xamidev Date: Thu, 26 Mar 2026 16:53:39 +0100 Subject: [PATCH] CPU Name identification --- include/arch/x86.h | 4 ++++ src/arch/x86/cpuid.c | 27 +++++++++++++++++++++++++ src/arch/x86/init.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/include/arch/x86.h b/include/arch/x86.h index 2c04dcf..0e6ad58 100644 --- a/include/arch/x86.h +++ b/include/arch/x86.h @@ -10,6 +10,10 @@ void wrmsr(uint32_t msr, uint64_t value); bool x86_has_msr(); void x86_arch_init(); + +void x86_cpu_identification(); +int cpuid_get_vendor_string(char* str); + /* Interrupt Descriptor Table */ void idt_init(void); diff --git a/src/arch/x86/cpuid.c b/src/arch/x86/cpuid.c index b4a9a55..bbe31a4 100644 --- a/src/arch/x86/cpuid.c +++ b/src/arch/x86/cpuid.c @@ -6,6 +6,8 @@ #include #include +#include +#include /* * cpuid - Wrapper for CPUID instruction @@ -18,4 +20,29 @@ void cpuid(uint32_t leaf, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) { __asm__ volatile("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "a"(leaf)); +} + +/* + * cpuid_get_vendor_string - Get the CPU vendor string + * @str: String at least 13 bytes long (for output) + * + * Return: + * %0 - on success + */ +int cpuid_get_vendor_string(char* str) +{ + uint32_t eax, ebx, ecx, edx; + + cpuid(0, &eax, &ebx, &ecx, &edx); + char output[13] = {0}; + + uint32_t regs[3] = {ebx, edx, ecx}; + for (unsigned int j=0; j<3; j++) { + for (unsigned int i=0; i<4; i++) { + output[4*j+i] = (char)((regs[j] >> 8*i) & 0xff); + } + } + + strncpy(str, output, 13); + return 0; } \ No newline at end of file diff --git a/src/arch/x86/init.c b/src/arch/x86/init.c index 9d74333..bc4b461 100644 --- a/src/arch/x86/init.c +++ b/src/arch/x86/init.c @@ -8,6 +8,7 @@ #include #include #include +#include /* * x86_overwrite_pat - Set PAT to WC @@ -41,6 +42,52 @@ static void x86_overwrite_pat() void x86_arch_init() { x86_overwrite_pat(); + x86_cpu_identification(); idt_init(); gdt_init(); +} + +/* + * cpu_supports_brandstring - Does the CPU support brand strings? + * + * Return: + * true - if it does + * false - if it doesn't +*/ +bool cpu_supports_brandstring() { + uint32_t eax, ebx, ecx, edx; + cpuid(0x80000000, &eax, &ebx, &ecx, &edx); + + if (eax < 0x80000004) { + return false; + } else { + return true; + } +} + +/* + * x86_cpu_idenfitication - get info about the CPU + * + * This function displays the CPU vendor name or the + * extended "brand string" if it's supported, on + * debug output. +*/ +void x86_cpu_identification() +{ + if (cpu_supports_brandstring()) { + uint32_t regs[12]; + // Some CPUs don't return null-terminated values so we do it as a failsafe default + char str[sizeof(regs)+1] = {0}; + cpuid(0x80000002, ®s[0], ®s[1], ®s[2], ®s[3]); + cpuid(0x80000003, ®s[4], ®s[5], ®s[6], ®s[7]); + cpuid(0x80000004, ®s[8], ®s[9], ®s[10], ®s[11]); + + memcpy(str, regs, sizeof(regs)); + str[sizeof(regs)] = '\0'; + DEBUG("CPU: %s", str); + } else { + char vendor_string[13] = {0}; + cpuid_get_vendor_string(vendor_string); + DEBUG("CPU vendor is: %s", vendor_string); + } } \ No newline at end of file