mirror of
https://github.com/RGBCube/serenity
synced 2025-05-20 13:45:06 +00:00
Kernel: Consolidate features into CPUFeature enum
This allows us to consolidate printing out all the CPU features into one log statement. Also expose them in /proc/cpuinfo
This commit is contained in:
parent
e373e5f007
commit
9b4e6f6a23
9 changed files with 197 additions and 145 deletions
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include <AK/Assertions.h>
|
#include <AK/Assertions.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
|
#include <AK/StringBuilder.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <Kernel/Arch/i386/CPU.h>
|
#include <Kernel/Arch/i386/CPU.h>
|
||||||
#include <Kernel/Arch/i386/ProcessorInfo.h>
|
#include <Kernel/Arch/i386/ProcessorInfo.h>
|
||||||
|
@ -633,7 +634,7 @@ void exit_trap(TrapFrame* trap)
|
||||||
return Processor::current().exit_trap(*trap);
|
return Processor::current().exit_trap(*trap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sse_init()
|
static void sse_init()
|
||||||
{
|
{
|
||||||
asm volatile(
|
asm volatile(
|
||||||
"mov %cr0, %eax\n"
|
"mov %cr0, %eax\n"
|
||||||
|
@ -645,122 +646,6 @@ void sse_init()
|
||||||
"mov %eax, %cr4\n");
|
"mov %eax, %cr4\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool g_cpu_supports_nx;
|
|
||||||
bool g_cpu_supports_pae;
|
|
||||||
bool g_cpu_supports_pge;
|
|
||||||
bool g_cpu_supports_rdrand;
|
|
||||||
bool g_cpu_supports_rdseed;
|
|
||||||
bool g_cpu_supports_smap;
|
|
||||||
bool g_cpu_supports_smep;
|
|
||||||
bool g_cpu_supports_sse;
|
|
||||||
bool g_cpu_supports_tsc;
|
|
||||||
bool g_cpu_supports_umip;
|
|
||||||
|
|
||||||
void cpu_detect()
|
|
||||||
{
|
|
||||||
CPUID processor_info(0x1);
|
|
||||||
g_cpu_supports_pae = (processor_info.edx() & (1 << 6));
|
|
||||||
g_cpu_supports_pge = (processor_info.edx() & (1 << 13));
|
|
||||||
g_cpu_supports_sse = (processor_info.edx() & (1 << 25));
|
|
||||||
g_cpu_supports_tsc = (processor_info.edx() & (1 << 4));
|
|
||||||
g_cpu_supports_rdrand = (processor_info.ecx() & (1 << 30));
|
|
||||||
|
|
||||||
CPUID extended_processor_info(0x80000001);
|
|
||||||
g_cpu_supports_nx = (extended_processor_info.edx() & (1 << 20));
|
|
||||||
|
|
||||||
CPUID extended_features(0x7);
|
|
||||||
g_cpu_supports_smap = (extended_features.ebx() & (1 << 20));
|
|
||||||
g_cpu_supports_smep = (extended_features.ebx() & (1 << 7));
|
|
||||||
g_cpu_supports_umip = (extended_features.ecx() & (1 << 2));
|
|
||||||
g_cpu_supports_rdseed = (extended_features.ebx() & (1 << 18));
|
|
||||||
}
|
|
||||||
|
|
||||||
void cpu_setup(u32 cpu)
|
|
||||||
{
|
|
||||||
if (cpu == 0)
|
|
||||||
cpu_detect();
|
|
||||||
|
|
||||||
if (g_cpu_supports_sse) {
|
|
||||||
sse_init();
|
|
||||||
klog() << "x86: SSE support enabled";
|
|
||||||
}
|
|
||||||
|
|
||||||
asm volatile(
|
|
||||||
"movl %%cr0, %%eax\n"
|
|
||||||
"orl $0x00010000, %%eax\n"
|
|
||||||
"movl %%eax, %%cr0\n" ::
|
|
||||||
: "%eax", "memory");
|
|
||||||
klog() << "x86: WP support enabled";
|
|
||||||
|
|
||||||
if (g_cpu_supports_pge) {
|
|
||||||
// Turn on CR4.PGE so the CPU will respect the G bit in page tables.
|
|
||||||
asm volatile(
|
|
||||||
"mov %cr4, %eax\n"
|
|
||||||
"orl $0x80, %eax\n"
|
|
||||||
"mov %eax, %cr4\n");
|
|
||||||
klog() << "x86: PGE support enabled";
|
|
||||||
} else {
|
|
||||||
klog() << "x86: PGE support not detected";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_cpu_supports_nx) {
|
|
||||||
// Turn on IA32_EFER.NXE
|
|
||||||
asm volatile(
|
|
||||||
"movl $0xc0000080, %ecx\n"
|
|
||||||
"rdmsr\n"
|
|
||||||
"orl $0x800, %eax\n"
|
|
||||||
"wrmsr\n");
|
|
||||||
klog() << "x86: NX support enabled";
|
|
||||||
} else {
|
|
||||||
klog() << "x86: NX support not detected";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_cpu_supports_smep) {
|
|
||||||
// Turn on CR4.SMEP
|
|
||||||
asm volatile(
|
|
||||||
"mov %cr4, %eax\n"
|
|
||||||
"orl $0x100000, %eax\n"
|
|
||||||
"mov %eax, %cr4\n");
|
|
||||||
klog() << "x86: SMEP support enabled";
|
|
||||||
} else {
|
|
||||||
klog() << "x86: SMEP support not detected";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_cpu_supports_smap) {
|
|
||||||
// Turn on CR4.SMAP
|
|
||||||
klog() << "x86: Enabling SMAP";
|
|
||||||
asm volatile(
|
|
||||||
"mov %cr4, %eax\n"
|
|
||||||
"orl $0x200000, %eax\n"
|
|
||||||
"mov %eax, %cr4\n");
|
|
||||||
klog() << "x86: SMAP support enabled";
|
|
||||||
} else {
|
|
||||||
klog() << "x86: SMAP support not detected";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_cpu_supports_umip) {
|
|
||||||
asm volatile(
|
|
||||||
"mov %cr4, %eax\n"
|
|
||||||
"orl $0x800, %eax\n"
|
|
||||||
"mov %eax, %cr4\n");
|
|
||||||
klog() << "x86: UMIP support enabled";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_cpu_supports_tsc) {
|
|
||||||
asm volatile(
|
|
||||||
"mov %cr4, %eax\n"
|
|
||||||
"orl $0x4, %eax\n"
|
|
||||||
"mov %eax, %cr4\n");
|
|
||||||
klog() << "x86: RDTSC support restricted";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_cpu_supports_rdrand) {
|
|
||||||
klog() << "x86: Using RDRAND for good randomness";
|
|
||||||
} else {
|
|
||||||
klog() << "x86: No RDRAND support detected, randomness will be poor";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 read_cr0()
|
u32 read_cr0()
|
||||||
{
|
{
|
||||||
u32 cr0;
|
u32 cr0;
|
||||||
|
@ -822,6 +707,156 @@ Processor& Processor::by_id(u32 cpu)
|
||||||
return *procs[cpu];
|
return *procs[cpu];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Processor::cpu_detect()
|
||||||
|
{
|
||||||
|
// NOTE: This is called during Processor::early_initialize, we cannot
|
||||||
|
// safely log at this point because we don't have kmalloc
|
||||||
|
// initialized yet!
|
||||||
|
auto set_feature =
|
||||||
|
[&](CPUFeature f) {
|
||||||
|
m_features = static_cast<CPUFeature>(static_cast<u32>(m_features) | static_cast<u32>(f));
|
||||||
|
};
|
||||||
|
m_features = static_cast<CPUFeature>(0);
|
||||||
|
|
||||||
|
CPUID processor_info(0x1);
|
||||||
|
if (processor_info.edx() & (1 << 6))
|
||||||
|
set_feature(CPUFeature::PAE);
|
||||||
|
if (processor_info.edx() & (1 << 13))
|
||||||
|
set_feature(CPUFeature::PGE);
|
||||||
|
if (processor_info.edx() & (1 << 25))
|
||||||
|
set_feature(CPUFeature::SSE);
|
||||||
|
if (processor_info.edx() & (1 << 4))
|
||||||
|
set_feature(CPUFeature::TSC);
|
||||||
|
if (processor_info.ecx() & (1 << 30))
|
||||||
|
set_feature(CPUFeature::RDRAND);
|
||||||
|
|
||||||
|
CPUID extended_processor_info(0x80000001);
|
||||||
|
if (extended_processor_info.edx() & (1 << 20))
|
||||||
|
set_feature(CPUFeature::NX);
|
||||||
|
|
||||||
|
CPUID extended_features(0x7);
|
||||||
|
if (extended_features.ebx() & (1 << 20))
|
||||||
|
set_feature(CPUFeature::SMAP);
|
||||||
|
if (extended_features.ebx() & (1 << 7))
|
||||||
|
set_feature(CPUFeature::SMEP);
|
||||||
|
if (extended_features.ecx() & (1 << 2))
|
||||||
|
set_feature(CPUFeature::UMIP);
|
||||||
|
if (extended_features.ebx() & (1 << 18))
|
||||||
|
set_feature(CPUFeature::RDSEED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Processor::cpu_setup()
|
||||||
|
{
|
||||||
|
// NOTE: This is called during Processor::early_initialize, we cannot
|
||||||
|
// safely log at this point because we don't have kmalloc
|
||||||
|
// initialized yet!
|
||||||
|
cpu_detect();
|
||||||
|
|
||||||
|
if (has_feature(CPUFeature::SSE))
|
||||||
|
sse_init();
|
||||||
|
|
||||||
|
asm volatile(
|
||||||
|
"movl %%cr0, %%eax\n"
|
||||||
|
"orl $0x00010000, %%eax\n"
|
||||||
|
"movl %%eax, %%cr0\n" ::
|
||||||
|
: "%eax", "memory");
|
||||||
|
|
||||||
|
if (has_feature(CPUFeature::PGE)) {
|
||||||
|
// Turn on CR4.PGE so the CPU will respect the G bit in page tables.
|
||||||
|
asm volatile(
|
||||||
|
"mov %cr4, %eax\n"
|
||||||
|
"orl $0x80, %eax\n"
|
||||||
|
"mov %eax, %cr4\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_feature(CPUFeature::NX)) {
|
||||||
|
// Turn on IA32_EFER.NXE
|
||||||
|
asm volatile(
|
||||||
|
"movl $0xc0000080, %ecx\n"
|
||||||
|
"rdmsr\n"
|
||||||
|
"orl $0x800, %eax\n"
|
||||||
|
"wrmsr\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_feature(CPUFeature::SMEP)) {
|
||||||
|
// Turn on CR4.SMEP
|
||||||
|
asm volatile(
|
||||||
|
"mov %cr4, %eax\n"
|
||||||
|
"orl $0x100000, %eax\n"
|
||||||
|
"mov %eax, %cr4\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_feature(CPUFeature::SMAP)) {
|
||||||
|
// Turn on CR4.SMAP
|
||||||
|
asm volatile(
|
||||||
|
"mov %cr4, %eax\n"
|
||||||
|
"orl $0x200000, %eax\n"
|
||||||
|
"mov %eax, %cr4\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_feature(CPUFeature::UMIP)) {
|
||||||
|
asm volatile(
|
||||||
|
"mov %cr4, %eax\n"
|
||||||
|
"orl $0x800, %eax\n"
|
||||||
|
"mov %eax, %cr4\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_feature(CPUFeature::TSC)) {
|
||||||
|
asm volatile(
|
||||||
|
"mov %cr4, %eax\n"
|
||||||
|
"orl $0x4, %eax\n"
|
||||||
|
"mov %eax, %cr4\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String Processor::features_string() const
|
||||||
|
{
|
||||||
|
StringBuilder builder;
|
||||||
|
auto feature_to_str =
|
||||||
|
[](CPUFeature f) -> const char*
|
||||||
|
{
|
||||||
|
switch (f) {
|
||||||
|
case CPUFeature::NX:
|
||||||
|
return "nx";
|
||||||
|
case CPUFeature::PAE:
|
||||||
|
return "pae";
|
||||||
|
case CPUFeature::PGE:
|
||||||
|
return "pge";
|
||||||
|
case CPUFeature::RDRAND:
|
||||||
|
return "rdrand";
|
||||||
|
case CPUFeature::RDSEED:
|
||||||
|
return "rdseed";
|
||||||
|
case CPUFeature::SMAP:
|
||||||
|
return "smap";
|
||||||
|
case CPUFeature::SMEP:
|
||||||
|
return "smep";
|
||||||
|
case CPUFeature::SSE:
|
||||||
|
return "sse";
|
||||||
|
case CPUFeature::TSC:
|
||||||
|
return "tsc";
|
||||||
|
case CPUFeature::UMIP:
|
||||||
|
return "umip";
|
||||||
|
// no default statement here intentionally so that we get
|
||||||
|
// a warning if a new feature is forgotten to be added here
|
||||||
|
}
|
||||||
|
// Shouldn't ever happen
|
||||||
|
return "???";
|
||||||
|
};
|
||||||
|
bool first = true;
|
||||||
|
for (u32 flag = 1; flag < sizeof(m_features) * 8; flag <<= 1) {
|
||||||
|
if ((static_cast<u32>(m_features) & flag) != 0) {
|
||||||
|
if (first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
builder.append(' ');
|
||||||
|
auto str = feature_to_str(static_cast<CPUFeature>(flag));
|
||||||
|
builder.append(str, strlen(str));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
void Processor::early_initialize(u32 cpu)
|
void Processor::early_initialize(u32 cpu)
|
||||||
{
|
{
|
||||||
m_self = this;
|
m_self = this;
|
||||||
|
@ -838,6 +873,8 @@ void Processor::early_initialize(u32 cpu)
|
||||||
m_mm_data = nullptr;
|
m_mm_data = nullptr;
|
||||||
m_info = nullptr;
|
m_info = nullptr;
|
||||||
|
|
||||||
|
cpu_setup();
|
||||||
|
|
||||||
gdt_init();
|
gdt_init();
|
||||||
ASSERT(¤t() == this); // sanity check
|
ASSERT(¤t() == this); // sanity check
|
||||||
}
|
}
|
||||||
|
@ -847,12 +884,9 @@ void Processor::initialize(u32 cpu)
|
||||||
ASSERT(m_self == this);
|
ASSERT(m_self == this);
|
||||||
ASSERT(¤t() == this); // sanity check
|
ASSERT(¤t() == this); // sanity check
|
||||||
|
|
||||||
m_cpu = cpu;
|
klog() << "CPU[" << id() << "]: Supported features: " << features_string();
|
||||||
m_in_irq = 0;
|
if (!has_feature(CPUFeature::RDRAND))
|
||||||
|
klog() << "CPU[" << id() << "]: No RDRAND support detected, randomness will be poor";
|
||||||
m_idle_thread = nullptr;
|
|
||||||
m_current_thread = nullptr;
|
|
||||||
m_mm_data = nullptr;
|
|
||||||
|
|
||||||
if (cpu == 0)
|
if (cpu == 0)
|
||||||
idt_init();
|
idt_init();
|
||||||
|
|
|
@ -265,7 +265,6 @@ struct RegisterState;
|
||||||
|
|
||||||
const DescriptorTablePointer& get_gdtr();
|
const DescriptorTablePointer& get_gdtr();
|
||||||
const DescriptorTablePointer& get_idtr();
|
const DescriptorTablePointer& get_idtr();
|
||||||
void sse_init();
|
|
||||||
void register_interrupt_handler(u8 number, void (*f)());
|
void register_interrupt_handler(u8 number, void (*f)());
|
||||||
void register_user_callable_interrupt_handler(u8 number, void (*f)());
|
void register_user_callable_interrupt_handler(u8 number, void (*f)());
|
||||||
GenericInterruptHandler& get_interrupt_handler(u8 interrupt_number);
|
GenericInterruptHandler& get_interrupt_handler(u8 interrupt_number);
|
||||||
|
@ -599,6 +598,19 @@ private:
|
||||||
SplitQword m_start;
|
SplitQword m_start;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class CPUFeature : u32 {
|
||||||
|
NX = (1 << 0),
|
||||||
|
PAE = (1 << 1),
|
||||||
|
PGE = (1 << 2),
|
||||||
|
RDRAND = (1 << 3),
|
||||||
|
RDSEED = (1 << 4),
|
||||||
|
SMAP = (1 << 5),
|
||||||
|
SMEP = (1 << 6),
|
||||||
|
SSE = (1 << 7),
|
||||||
|
TSC = (1 << 8),
|
||||||
|
UMIP = (1 << 9)
|
||||||
|
};
|
||||||
|
|
||||||
class Thread;
|
class Thread;
|
||||||
struct TrapFrame;
|
struct TrapFrame;
|
||||||
|
|
||||||
|
@ -614,6 +626,8 @@ class ProcessorInfo;
|
||||||
struct MemoryManagerData;
|
struct MemoryManagerData;
|
||||||
|
|
||||||
class Processor {
|
class Processor {
|
||||||
|
friend class ProcessorInfo;
|
||||||
|
|
||||||
Processor* m_self; // must be first field (%fs offset 0x0)
|
Processor* m_self; // must be first field (%fs offset 0x0)
|
||||||
|
|
||||||
DescriptorTablePointer m_gdtr;
|
DescriptorTablePointer m_gdtr;
|
||||||
|
@ -626,6 +640,7 @@ class Processor {
|
||||||
|
|
||||||
TSS32 m_tss;
|
TSS32 m_tss;
|
||||||
static FPUState s_clean_fpu_state;
|
static FPUState s_clean_fpu_state;
|
||||||
|
CPUFeature m_features;
|
||||||
|
|
||||||
ProcessorInfo* m_info;
|
ProcessorInfo* m_info;
|
||||||
MemoryManagerData* m_mm_data;
|
MemoryManagerData* m_mm_data;
|
||||||
|
@ -640,6 +655,11 @@ class Processor {
|
||||||
void write_gdt_entry(u16 selector, Descriptor& descriptor);
|
void write_gdt_entry(u16 selector, Descriptor& descriptor);
|
||||||
static Vector<Processor*>& processors();
|
static Vector<Processor*>& processors();
|
||||||
|
|
||||||
|
void cpu_detect();
|
||||||
|
void cpu_setup();
|
||||||
|
|
||||||
|
String features_string() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void early_initialize(u32 cpu);
|
void early_initialize(u32 cpu);
|
||||||
void initialize(u32 cpu);
|
void initialize(u32 cpu);
|
||||||
|
@ -740,6 +760,11 @@ public:
|
||||||
return s_clean_fpu_state;
|
return s_clean_fpu_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE bool has_feature(CPUFeature f) const
|
||||||
|
{
|
||||||
|
return (static_cast<u32>(m_features) & static_cast<u32>(f)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
void check_invoke_scheduler();
|
void check_invoke_scheduler();
|
||||||
void invoke_scheduler_async() { m_invoke_scheduler_async = true; }
|
void invoke_scheduler_async() { m_invoke_scheduler_async = true; }
|
||||||
|
|
||||||
|
@ -846,22 +871,9 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void cpu_setup(u32 cpu);
|
|
||||||
|
|
||||||
extern bool g_cpu_supports_nx;
|
|
||||||
extern bool g_cpu_supports_pae;
|
|
||||||
extern bool g_cpu_supports_pge;
|
|
||||||
extern bool g_cpu_supports_rdrand;
|
|
||||||
extern bool g_cpu_supports_rdseed;
|
|
||||||
extern bool g_cpu_supports_smap;
|
|
||||||
extern bool g_cpu_supports_smep;
|
|
||||||
extern bool g_cpu_supports_sse;
|
|
||||||
extern bool g_cpu_supports_tsc;
|
|
||||||
extern bool g_cpu_supports_umip;
|
|
||||||
|
|
||||||
ALWAYS_INLINE void stac()
|
ALWAYS_INLINE void stac()
|
||||||
{
|
{
|
||||||
if (!g_cpu_supports_smap)
|
if (!Processor::current().has_feature(CPUFeature::SMAP))
|
||||||
return;
|
return;
|
||||||
asm volatile("stac" ::
|
asm volatile("stac" ::
|
||||||
: "cc");
|
: "cc");
|
||||||
|
@ -869,7 +881,7 @@ ALWAYS_INLINE void stac()
|
||||||
|
|
||||||
ALWAYS_INLINE void clac()
|
ALWAYS_INLINE void clac()
|
||||||
{
|
{
|
||||||
if (!g_cpu_supports_smap)
|
if (!Processor::current().has_feature(CPUFeature::SMAP))
|
||||||
return;
|
return;
|
||||||
asm volatile("clac" ::
|
asm volatile("clac" ::
|
||||||
: "cc");
|
: "cc");
|
||||||
|
|
|
@ -88,6 +88,9 @@ ProcessorInfo::ProcessorInfo(Processor& processor):
|
||||||
copy_brand_string_part_to_buffer(2);
|
copy_brand_string_part_to_buffer(2);
|
||||||
m_brandstr = buffer;
|
m_brandstr = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cache the CPU feature string
|
||||||
|
m_features = m_processor.features_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ class ProcessorInfo
|
||||||
Processor& m_processor;
|
Processor& m_processor;
|
||||||
String m_cpuid;
|
String m_cpuid;
|
||||||
String m_brandstr;
|
String m_brandstr;
|
||||||
|
String m_features;
|
||||||
u32 m_display_model;
|
u32 m_display_model;
|
||||||
u32 m_display_family;
|
u32 m_display_family;
|
||||||
u32 m_stepping;
|
u32 m_stepping;
|
||||||
|
@ -47,6 +48,7 @@ public:
|
||||||
|
|
||||||
const String& cpuid() const { return m_cpuid; }
|
const String& cpuid() const { return m_cpuid; }
|
||||||
const String& brandstr() const { return m_brandstr; }
|
const String& brandstr() const { return m_brandstr; }
|
||||||
|
const String& features() const { return m_features; }
|
||||||
u32 display_model() const { return m_display_model; }
|
u32 display_model() const { return m_display_model; }
|
||||||
u32 display_family() const { return m_display_family; }
|
u32 display_family() const { return m_display_family; }
|
||||||
u32 stepping() const { return m_stepping; }
|
u32 stepping() const { return m_stepping; }
|
||||||
|
|
|
@ -773,6 +773,7 @@ Optional<KBuffer> procfs$cpuinfo(InodeIdentifier)
|
||||||
builder.appendf("processor: %u\n", proc.id());
|
builder.appendf("processor: %u\n", proc.id());
|
||||||
builder.appendf("cpuid: %s\n", info.cpuid().characters());
|
builder.appendf("cpuid: %s\n", info.cpuid().characters());
|
||||||
builder.appendf("family: %u\n", info.display_family());
|
builder.appendf("family: %u\n", info.display_family());
|
||||||
|
builder.appendf("features: %s\n", info.features().characters());
|
||||||
builder.appendf("model: %u\n", info.display_model());
|
builder.appendf("model: %u\n", info.display_model());
|
||||||
builder.appendf("stepping: %u\n", info.stepping());
|
builder.appendf("stepping: %u\n", info.stepping());
|
||||||
builder.appendf("type: %u\n", info.type());
|
builder.appendf("type: %u\n", info.type());
|
||||||
|
|
|
@ -44,10 +44,12 @@ KernelRng& KernelRng::the()
|
||||||
|
|
||||||
KernelRng::KernelRng()
|
KernelRng::KernelRng()
|
||||||
{
|
{
|
||||||
if (g_cpu_supports_rdseed || g_cpu_supports_rdrand) {
|
bool supports_rdseed = Processor::current().has_feature(CPUFeature::RDSEED);
|
||||||
|
bool supports_rdrand = Processor::current().has_feature(CPUFeature::RDRAND);
|
||||||
|
if (supports_rdseed || supports_rdrand) {
|
||||||
for (size_t i = 0; i < resource().pool_count * resource().reseed_threshold; ++i) {
|
for (size_t i = 0; i < resource().pool_count * resource().reseed_threshold; ++i) {
|
||||||
u32 value = 0;
|
u32 value = 0;
|
||||||
if (g_cpu_supports_rdseed) {
|
if (supports_rdseed) {
|
||||||
asm volatile(
|
asm volatile(
|
||||||
"1:\n"
|
"1:\n"
|
||||||
"rdseed %0\n"
|
"rdseed %0\n"
|
||||||
|
|
|
@ -80,7 +80,7 @@ void MemoryManager::protect_kernel_image()
|
||||||
pte.set_writable(false);
|
pte.set_writable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_cpu_supports_nx) {
|
if (Processor::current().has_feature(CPUFeature::NX)) {
|
||||||
// Disable execution of the kernel data and bss segments.
|
// Disable execution of the kernel data and bss segments.
|
||||||
for (size_t i = (FlatPtr)&start_of_kernel_data; i < (FlatPtr)&end_of_kernel_bss; i += PAGE_SIZE) {
|
for (size_t i = (FlatPtr)&start_of_kernel_data; i < (FlatPtr)&end_of_kernel_bss; i += PAGE_SIZE) {
|
||||||
auto& pte = ensure_pte(kernel_page_directory(), VirtualAddress(i));
|
auto& pte = ensure_pte(kernel_page_directory(), VirtualAddress(i));
|
||||||
|
|
|
@ -237,7 +237,7 @@ void Region::map_individual_page_impl(size_t page_index)
|
||||||
pte.set_writable(false);
|
pte.set_writable(false);
|
||||||
else
|
else
|
||||||
pte.set_writable(is_writable());
|
pte.set_writable(is_writable());
|
||||||
if (g_cpu_supports_nx)
|
if (Processor::current().has_feature(CPUFeature::NX))
|
||||||
pte.set_execute_disabled(!is_executable());
|
pte.set_execute_disabled(!is_executable());
|
||||||
pte.set_user_allowed(is_user_accessible());
|
pte.set_user_allowed(is_user_accessible());
|
||||||
#ifdef MM_DEBUG
|
#ifdef MM_DEBUG
|
||||||
|
|
|
@ -106,7 +106,6 @@ extern "C" [[noreturn]] void init()
|
||||||
setup_serial_debug();
|
setup_serial_debug();
|
||||||
|
|
||||||
s_bsp_processor.early_initialize(0);
|
s_bsp_processor.early_initialize(0);
|
||||||
cpu_setup(0);
|
|
||||||
|
|
||||||
kmalloc_init();
|
kmalloc_init();
|
||||||
slab_alloc_init();
|
slab_alloc_init();
|
||||||
|
@ -169,7 +168,6 @@ extern "C" [[noreturn]] void init_ap(u32 cpu, Processor* processor_info)
|
||||||
|
|
||||||
klog() << "CPU #" << cpu << " processor_info at " << VirtualAddress(FlatPtr(processor_info));
|
klog() << "CPU #" << cpu << " processor_info at " << VirtualAddress(FlatPtr(processor_info));
|
||||||
|
|
||||||
cpu_setup(cpu);
|
|
||||||
processor_info->initialize(cpu);
|
processor_info->initialize(cpu);
|
||||||
MemoryManager::initialize(cpu);
|
MemoryManager::initialize(cpu);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue