mirror of
https://github.com/justinian/jsix.git
synced 2025-12-09 16:04:32 -08:00
[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:
@@ -79,7 +79,7 @@ check_cpu_supported()
|
|||||||
status_line status {L"Checking CPU features"};
|
status_line status {L"Checking CPU features"};
|
||||||
|
|
||||||
cpu::cpu_id cpu;
|
cpu::cpu_id cpu;
|
||||||
cpu::cpu_id::features features = cpu.validate();
|
cpu::features features = cpu.features();
|
||||||
bool supported = true;
|
bool supported = true;
|
||||||
|
|
||||||
#define CPU_FEATURE_OPT(...)
|
#define CPU_FEATURE_OPT(...)
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <util/bitset.h>
|
#include <util/bitset.h>
|
||||||
|
#include <util/no_construct.h>
|
||||||
|
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "cpu/cpu_id.h"
|
|
||||||
#include "device_manager.h"
|
#include "device_manager.h"
|
||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
@@ -20,38 +20,49 @@ unsigned g_num_cpus = 1;
|
|||||||
panic_data g_panic_data;
|
panic_data g_panic_data;
|
||||||
panic_data *g_panic_data_p = &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;
|
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
|
// Validate the required CPU features are present. Really, the bootloader already
|
||||||
// validated the required features, but still iterate the options and log about them.
|
// validated the required features, but still iterate the options and log about them.
|
||||||
void
|
static cpu::features
|
||||||
cpu_validate()
|
cpu_validate(cpu_data *c)
|
||||||
{
|
{
|
||||||
cpu::cpu_id cpu;
|
cpu::cpu_id cpuid;
|
||||||
|
|
||||||
char brand_name[50];
|
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, "CPU %2d: %s", c->index, brand_name);
|
||||||
log::info(logs::boot, " Vendor is %s", cpu.vendor_id());
|
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 basic CPUID: 0x%02x", cpuid.highest_basic());
|
||||||
log::spam(logs::boot, " Higest ext CPUID: 0x%02x", cpu.highest_ext() & ~cpu::cpu_id::cpuid_extended);
|
log::spam(logs::boot, " Higest ext CPUID: 0x%02x", cpuid.highest_ext() & ~cpu::cpu_id::cpuid_extended);
|
||||||
|
|
||||||
#define CPU_FEATURE_OPT(name, ...) \
|
#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) \
|
#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 );
|
kassert(features[cpu::feature::name], "Missing required CPU feature " #name );
|
||||||
|
|
||||||
#include "cpu/features.inc"
|
#include "cpu/features.inc"
|
||||||
#undef CPU_FEATURE_OPT
|
#undef CPU_FEATURE_OPT
|
||||||
#undef CPU_FEATURE_REQ
|
#undef CPU_FEATURE_REQ
|
||||||
|
|
||||||
|
return features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -70,13 +81,24 @@ cpu_early_init(cpu_data *cpu)
|
|||||||
.clear(cr0::CD);
|
.clear(cr0::CD);
|
||||||
asm volatile ( "mov %0, %%cr0" :: "r" (cr0_val) );
|
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;
|
util::bitset64 cr4_val = 0;
|
||||||
asm ("mov %%cr4, %0" : "=r"(cr4_val));
|
asm ("mov %%cr4, %0" : "=r"(cr4_val));
|
||||||
cr4_val
|
cr4_val
|
||||||
.set(cr4::OSXFSR)
|
.set(cr4::OSXFSR)
|
||||||
.set(cr4::OSXMMEXCPT)
|
.set(cr4::OSXMMEXCPT)
|
||||||
.set(cr4::PCIDE)
|
|
||||||
.set(cr4::OSXSAVE);
|
.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) );
|
asm volatile ( "mov %0, %%cr4" :: "r" (cr4_val) );
|
||||||
|
|
||||||
// Enable SYSCALL and NX bit
|
// Enable SYSCALL and NX bit
|
||||||
@@ -98,7 +120,6 @@ cpu_early_init(cpu_data *cpu)
|
|||||||
cpu_data *
|
cpu_data *
|
||||||
bsp_early_init()
|
bsp_early_init()
|
||||||
{
|
{
|
||||||
cpu_validate();
|
|
||||||
memset(&g_panic_data, 0, sizeof(g_panic_data));
|
memset(&g_panic_data, 0, sizeof(g_panic_data));
|
||||||
|
|
||||||
extern IDT &g_bsp_idt;
|
extern IDT &g_bsp_idt;
|
||||||
@@ -135,7 +156,12 @@ bsp_late_init()
|
|||||||
uint64_t xcr0v = get_xcr0();
|
uint64_t xcr0v = get_xcr0();
|
||||||
|
|
||||||
uint64_t efer = rdmsr(msr::ia32_efer);
|
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 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 *
|
cpu_data *
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <cpu/cpu_id.h>
|
||||||
|
|
||||||
class GDT;
|
class GDT;
|
||||||
class IDT;
|
class IDT;
|
||||||
@@ -128,6 +129,7 @@ struct cpu_data
|
|||||||
// the assembly version
|
// the assembly version
|
||||||
lapic *apic;
|
lapic *apic;
|
||||||
panic_data *panic;
|
panic_data *panic;
|
||||||
|
cpu::features features;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@@ -16,10 +16,11 @@ enum class feature {
|
|||||||
max
|
max
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using features = util::bitset<(unsigned)feature::max>;
|
||||||
|
|
||||||
class cpu_id
|
class cpu_id
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using features = util::bitset<(unsigned)feature::max>;
|
|
||||||
static constexpr uint32_t cpuid_extended = 0x80000000;
|
static constexpr uint32_t cpuid_extended = 0x80000000;
|
||||||
|
|
||||||
/// CPUID result register values
|
/// CPUID result register values
|
||||||
@@ -46,7 +47,7 @@ public:
|
|||||||
|
|
||||||
/// Check which of the cpu::feature flags this CPU supports.
|
/// Check which of the cpu::feature flags this CPU supports.
|
||||||
/// \returns A util::bitset mapping to cpu::feature values
|
/// \returns A util::bitset mapping to cpu::feature values
|
||||||
features validate() const;
|
features features() const;
|
||||||
|
|
||||||
/// The the result of a given CPUID leaf/subleaf
|
/// The the result of a given CPUID leaf/subleaf
|
||||||
/// \arg leaf The leaf selector (initial EAX)
|
/// \arg leaf The leaf selector (initial EAX)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
CPU_FEATURE_OPT(pcid, 0x00000001, 0, ecx, 17)
|
CPU_FEATURE_OPT(pcid, 0x00000001, 0, ecx, 17)
|
||||||
CPU_FEATURE_OPT(x2apic, 0x00000001, 0, ecx, 21)
|
CPU_FEATURE_OPT(x2apic, 0x00000001, 0, ecx, 21)
|
||||||
CPU_FEATURE_REQ(xsave, 0x00000001, 0, ecx, 26)
|
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(fpu, 0x00000001, 0, edx, 0)
|
||||||
CPU_FEATURE_REQ(pse, 0x00000001, 0, edx, 3)
|
CPU_FEATURE_REQ(pse, 0x00000001, 0, edx, 3)
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ cpu_id::cpu_id()
|
|||||||
__cpuid(cpuid_extended, 0, &m_high_ext);
|
__cpuid(cpuid_extended, 0, &m_high_ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu_id::features
|
features
|
||||||
cpu_id::validate() const
|
cpu_id::features() const
|
||||||
{
|
{
|
||||||
cpu_id::features feats;
|
::cpu::features feats;
|
||||||
uint32_t leaf = -1u;
|
uint32_t leaf = -1u;
|
||||||
uint32_t sub = -1u;
|
uint32_t sub = -1u;
|
||||||
regs r;
|
regs r;
|
||||||
|
|||||||
Reference in New Issue
Block a user