[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.
This commit is contained in:
Justin C. Miller
2023-03-16 19:41:07 -07:00
parent 201e7191ef
commit bfab4f085e
6 changed files with 51 additions and 22 deletions

View File

@@ -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(...)

View File

@@ -2,10 +2,10 @@
#include <stdint.h>
#include <string.h>
#include <util/bitset.h>
#include <util/no_construct.h>
#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<cpu_data> __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 *

View File

@@ -1,6 +1,7 @@
#pragma once
#include <stdint.h>
#include <cpu/cpu_id.h>
class GDT;
class IDT;
@@ -128,6 +129,7 @@ struct cpu_data
// the assembly version
lapic *apic;
panic_data *panic;
cpu::features features;
};
extern "C" {

View File

@@ -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)

View File

@@ -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)

View File

@@ -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;