From bfab4f085e7325731c6f877ad5946209bbcd8dac Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Thu, 16 Mar 2023 19:41:07 -0700 Subject: [PATCH] [cpu] Rename cpu_id::validate() to cpu_id::features() Validate wasn't a correct name anymore. Also move the features enum out of the cpu_id class scope and into the `cpu` namespace directly. --- src/boot/hardware.cpp | 2 +- src/kernel/cpu.cpp | 56 ++++++++++++++++++++++-------- src/kernel/cpu.h | 2 ++ src/libraries/cpu/cpu/cpu_id.h | 5 +-- src/libraries/cpu/cpu/features.inc | 2 +- src/libraries/cpu/cpu_id.cpp | 6 ++-- 6 files changed, 51 insertions(+), 22 deletions(-) diff --git a/src/boot/hardware.cpp b/src/boot/hardware.cpp index 3ba9664..f20a06d 100644 --- a/src/boot/hardware.cpp +++ b/src/boot/hardware.cpp @@ -79,7 +79,7 @@ check_cpu_supported() status_line status {L"Checking CPU features"}; cpu::cpu_id cpu; - cpu::cpu_id::features features = cpu.validate(); + cpu::features features = cpu.features(); bool supported = true; #define CPU_FEATURE_OPT(...) diff --git a/src/kernel/cpu.cpp b/src/kernel/cpu.cpp index c957435..83ef638 100644 --- a/src/kernel/cpu.cpp +++ b/src/kernel/cpu.cpp @@ -2,10 +2,10 @@ #include #include #include +#include #include "assert.h" #include "cpu.h" -#include "cpu/cpu_id.h" #include "device_manager.h" #include "gdt.h" #include "idt.h" @@ -20,38 +20,49 @@ unsigned g_num_cpus = 1; panic_data g_panic_data; panic_data *g_panic_data_p = &g_panic_data; -cpu_data g_bsp_cpu_data; +static util::no_construct __g_bsp_cpu_storage; +cpu_data &g_bsp_cpu_data = __g_bsp_cpu_storage.value; + cpu_data **g_cpu_data = nullptr; +static cpu::features +get_features() +{ + cpu::cpu_id cpuid; + return cpuid.features(); +} + // Validate the required CPU features are present. Really, the bootloader already // validated the required features, but still iterate the options and log about them. -void -cpu_validate() +static cpu::features +cpu_validate(cpu_data *c) { - cpu::cpu_id cpu; + cpu::cpu_id cpuid; char brand_name[50]; - cpu.brand_name(brand_name); + cpuid.brand_name(brand_name); - cpu::cpu_id::features features = cpu.validate(); + cpu::features &features = c->features; - log::info(logs::boot, "CPU: %s", brand_name); - log::info(logs::boot, " Vendor is %s", cpu.vendor_id()); + log::info(logs::boot, "CPU %2d: %s", c->index, brand_name); + log::info(logs::boot, " Vendor is %s", cpuid.vendor_id()); - log::spam(logs::boot, " Higest basic CPUID: 0x%02x", cpu.highest_basic()); - log::spam(logs::boot, " Higest ext CPUID: 0x%02x", cpu.highest_ext() & ~cpu::cpu_id::cpuid_extended); + log::spam(logs::boot, " Higest basic CPUID: 0x%02x", cpuid.highest_basic()); + log::spam(logs::boot, " Higest ext CPUID: 0x%02x", cpuid.highest_ext() & ~cpu::cpu_id::cpuid_extended); #define CPU_FEATURE_OPT(name, ...) \ - log::verbose(logs::boot, " Supports %9s: %s", #name, features[cpu::feature::name] ? "yes" : "no"); + log::verbose(logs::boot, " Flag %11s: %s", #name, features[cpu::feature::name] ? "yes" : "no"); #define CPU_FEATURE_REQ(name, feat_leaf, feat_sub, regname, bit) \ - log::verbose(logs::boot, " Supports %9s: %s", #name, features[cpu::feature::name] ? "yes" : "no"); \ + log::verbose(logs::boot, " Flag %11s: %s", #name, features[cpu::feature::name] ? "yes" : "no"); \ kassert(features[cpu::feature::name], "Missing required CPU feature " #name ); #include "cpu/features.inc" #undef CPU_FEATURE_OPT #undef CPU_FEATURE_REQ + + return features; } @@ -70,13 +81,24 @@ cpu_early_init(cpu_data *cpu) .clear(cr0::CD); asm volatile ( "mov %0, %%cr0" :: "r" (cr0_val) ); + cpu->features = get_features(); + + uintptr_t cr3_val; + asm ("mov %%cr3, %0" : "=r"(cr3_val)); + util::bitset64 cr4_val = 0; asm ("mov %%cr4, %0" : "=r"(cr4_val)); cr4_val .set(cr4::OSXFSR) .set(cr4::OSXMMEXCPT) - .set(cr4::PCIDE) .set(cr4::OSXSAVE); + + // TODO: On KVM setting PCIDE generates a #GP even though + // the feature is listed as available in CPUID. + /* + if (cpu->features[cpu::feature::pcid]) + cr4_val.set(cr4::PCIDE); + */ asm volatile ( "mov %0, %%cr4" :: "r" (cr4_val) ); // Enable SYSCALL and NX bit @@ -98,7 +120,6 @@ cpu_early_init(cpu_data *cpu) cpu_data * bsp_early_init() { - cpu_validate(); memset(&g_panic_data, 0, sizeof(g_panic_data)); extern IDT &g_bsp_idt; @@ -135,7 +156,12 @@ bsp_late_init() uint64_t xcr0v = get_xcr0(); uint64_t efer = rdmsr(msr::ia32_efer); +<<<<<<< HEAD log::spam(logs::boot, "Control regs: cr0:%lx cr4:%lx efer:%lx mxcsr:%x xcr0:%x", cr0v, cr4v, efer, mxcsrv, xcr0v); +======= + log::spam(logs::boot, "Control regs: cr0:%lx cr4:%lx efer:%lx", cr0v, cr4v, efer); + cpu_validate(&g_bsp_cpu_data); +>>>>>>> 66a5273 ([cpu] Rename cpu_id::validate() to cpu_id::features()) } cpu_data * diff --git a/src/kernel/cpu.h b/src/kernel/cpu.h index 7e70051..5d4e996 100644 --- a/src/kernel/cpu.h +++ b/src/kernel/cpu.h @@ -1,6 +1,7 @@ #pragma once #include +#include class GDT; class IDT; @@ -128,6 +129,7 @@ struct cpu_data // the assembly version lapic *apic; panic_data *panic; + cpu::features features; }; extern "C" { diff --git a/src/libraries/cpu/cpu/cpu_id.h b/src/libraries/cpu/cpu/cpu_id.h index e264977..00deeeb 100644 --- a/src/libraries/cpu/cpu/cpu_id.h +++ b/src/libraries/cpu/cpu/cpu_id.h @@ -16,10 +16,11 @@ enum class feature { max }; +using features = util::bitset<(unsigned)feature::max>; + class cpu_id { public: - using features = util::bitset<(unsigned)feature::max>; static constexpr uint32_t cpuid_extended = 0x80000000; /// CPUID result register values @@ -46,7 +47,7 @@ public: /// Check which of the cpu::feature flags this CPU supports. /// \returns A util::bitset mapping to cpu::feature values - features validate() const; + features features() const; /// The the result of a given CPUID leaf/subleaf /// \arg leaf The leaf selector (initial EAX) diff --git a/src/libraries/cpu/cpu/features.inc b/src/libraries/cpu/cpu/features.inc index 476605a..dc6b542 100644 --- a/src/libraries/cpu/cpu/features.inc +++ b/src/libraries/cpu/cpu/features.inc @@ -2,7 +2,7 @@ CPU_FEATURE_OPT(pcid, 0x00000001, 0, ecx, 17) CPU_FEATURE_OPT(x2apic, 0x00000001, 0, ecx, 21) CPU_FEATURE_REQ(xsave, 0x00000001, 0, ecx, 26) -CPU_FEATURE_OPT(in_hv, 0x00000001, 0, ecx, 31) +CPU_FEATURE_OPT(hypervisor, 0x00000001, 0, ecx, 31) CPU_FEATURE_REQ(fpu, 0x00000001, 0, edx, 0) CPU_FEATURE_REQ(pse, 0x00000001, 0, edx, 3) diff --git a/src/libraries/cpu/cpu_id.cpp b/src/libraries/cpu/cpu_id.cpp index 4bdc3b0..a4d765a 100644 --- a/src/libraries/cpu/cpu_id.cpp +++ b/src/libraries/cpu/cpu_id.cpp @@ -34,10 +34,10 @@ cpu_id::cpu_id() __cpuid(cpuid_extended, 0, &m_high_ext); } -cpu_id::features -cpu_id::validate() const +features +cpu_id::features() const { - cpu_id::features feats; + ::cpu::features feats; uint32_t leaf = -1u; uint32_t sub = -1u; regs r;