summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-08-12 22:50:51 -0400
committerIan Moffett <ian@osmora.org>2025-08-12 22:50:51 -0400
commit39c2c3c8de8b2f3a18315e2001eac05fe52c0956 (patch)
tree57086542aacf3842509dd45f0c8b223c79dbc1f5 /sys
parent49e744c65c8e3d2f72357f865dbd1908796950cf (diff)
kernel/amd64: cpu: Report CPU vendor type
This commit introduces a vendor field within the 'cpu_info' structure. This allows kernel code to detect the CPU vendor by comparing it with the CPU_VENDOR_* defines that have also been added. Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/amd64/machdep.c63
-rw-r--r--sys/include/arch/amd64/cpu.h6
2 files changed, 69 insertions, 0 deletions
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index 3f8580a..8761fbe 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -238,11 +238,74 @@ init_ipis(void)
}
static void
+cpu_get_vendor(struct cpu_info *ci)
+{
+ uint32_t unused, ebx, ecx, edx;
+ char vendor_str[13];
+
+ /*
+ * This CPUID returns a 12 byte CPU vendor string
+ * that we'll put together and use to detect the vendor.
+ */
+ CPUID(0, unused, ebx, ecx, edx);
+
+ /* Dword 0 */
+ vendor_str[0] = ebx & 0xFF;
+ vendor_str[1] = (ebx >> 8) & 0xFF;
+ vendor_str[2] = (ebx >> 16) & 0xFF;
+ vendor_str[3] = (ebx >> 24) & 0xFF;
+
+ /* Dword 1 */
+ vendor_str[4] = edx & 0xFF;
+ vendor_str[5] = (edx >> 8) & 0xFF;
+ vendor_str[6] = (edx >> 16) & 0xFF;
+ vendor_str[7] = (edx >> 24) & 0xFF;
+
+ /* Dword 2 */
+ vendor_str[8] = ecx & 0xFF;
+ vendor_str[9] = (ecx >> 8) & 0xFF;
+ vendor_str[10] = (ecx >> 16) & 0xFF;
+ vendor_str[11] = (ecx >> 24) & 0xFF;
+ vendor_str[12] = '\0';
+
+ /* Is this an AMD CPU? */
+ if (strcmp(vendor_str, "AuthenticAMD") == 0) {
+ ci->vendor = CPU_VENDOR_AMD;
+ return;
+ }
+
+ /* Is this an Intel CPU? */
+ if (strcmp(vendor_str, "GenuineIntel") == 0) {
+ ci->vendor = CPU_VENDOR_INTEL;
+ return;
+ }
+
+ /*
+ * Some buggy Intel CPUs report the string "GenuineIotel"
+ * instead of "GenuineIntel". This is rare but we should
+ * still handle it as it can happen. Probably a good idea
+ * to log it so the user can know about their rare CPU
+ * quirk and brag to their friends :~)
+ */
+ if (strcmp(vendor_str, "GenuineIotel") == 0) {
+ pr_trace_bsp("vendor_str=%s\n", vendor_str);
+ pr_trace_bsp("detected vendor string quirk\n");
+ ci->vendor = CPU_VENDOR_INTEL;
+ return;
+ }
+
+ ci->vendor = CPU_VENDOR_OTHER;
+}
+
+static void
cpu_get_info(struct cpu_info *ci)
{
uint32_t eax, ebx, unused;
uint8_t ext_model, ext_family;
+ /* Get the vendor information */
+ cpu_get_vendor(ci);
+
/* Extended features */
CPUID(0x07, unused, ebx, unused, unused);
if (ISSET(ebx, BIT(7)))
diff --git a/sys/include/arch/amd64/cpu.h b/sys/include/arch/amd64/cpu.h
index 4586163..b02ed5f 100644
--- a/sys/include/arch/amd64/cpu.h
+++ b/sys/include/arch/amd64/cpu.h
@@ -45,11 +45,17 @@
#define CPU_FEAT_SMAP BIT(0)
#define CPU_FEAT_SMEP BIT(1)
+/* CPU vendors */
+#define CPU_VENDOR_OTHER 0x00000000
+#define CPU_VENDOR_INTEL 0x00000001
+#define CPU_VENDOR_AMD 0x00000002
+
typedef uint16_t ipi_pend_t;
struct cpu_info {
uint32_t apicid;
uint32_t feat;
+ uint32_t vendor; /* Vendor (see CPU_VENDOR_*) */
uint8_t ipi_dispatch : 1; /* 1: IPIs being dispatched */
uint8_t ipi_id;
ipi_pend_t ipi_pending[N_IPIVEC];