[kernel] Unify CPUs' control register settings

Previously, the CPU control registers were being set in a number of
different ways. Now, since the APs' need this to be set in the CPU
initialization code, always do it there. This removes some of the
settings from the bootloader, and some unused ones from smp.s.
Additionally, the control registers' flags are now enums in cpu.h and
manipulated via util::bitset.
This commit is contained in:
Justin C. Miller
2022-03-13 17:45:16 -07:00
parent cca07d97b5
commit 90663a674a
4 changed files with 69 additions and 20 deletions

View File

@@ -60,12 +60,7 @@ setup_control_regs()
{
uint64_t cr4 = 0;
asm volatile ( "mov %%cr4, %0" : "=r" (cr4) );
cr4 |=
0x000080 | // Enable global pages
0x000200 | // Enable FXSAVE/FXRSTOR
0x010000 | // Enable FSGSBASE
0x020000 | // Enable PCIDs
0;
cr4 |= 0x000080; // Enable global pages
asm volatile ( "mov %0, %%cr4" :: "r" (cr4) );
// Set up IA32_EFER

View File

@@ -64,6 +64,22 @@ cpu_early_init(cpu_data *cpu)
cpu->idt->install();
cpu->gdt->install();
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);
asm volatile ( "mov %0, %%cr4" :: "r" (cr4_val) );
// Enable SYSCALL and NX bit
util::bitset64 efer_val = rdmsr(msr::ia32_efer);
efer_val
.set(efer::SCE)
.set(efer::NXE);
wrmsr(msr::ia32_efer, efer_val);
// Install the GS base pointint to the cpu_data
wrmsr(msr::ia32_gs_base, reinterpret_cast<uintptr_t>(cpu));
}
@@ -100,11 +116,12 @@ bsp_late_init()
uint8_t ist_entries = IDT::used_ist_entries();
g_bsp_tss.create_ist_stacks(ist_entries);
uint64_t cr0, cr4;
asm ("mov %%cr0, %0" : "=r"(cr0));
asm ("mov %%cr4, %0" : "=r"(cr4));
uint64_t cr0v, cr4v;
asm ("mov %%cr0, %0" : "=r"(cr0v));
asm ("mov %%cr4, %0" : "=r"(cr4v));
uint64_t efer = rdmsr(msr::ia32_efer);
log::debug(logs::boot, "Control regs: cr0:%lx cr4:%lx efer:%lx", cr0, cr4, efer);
log::debug(logs::boot, "Control regs: cr0:%lx cr4:%lx efer:%lx", cr0v, cr4v, efer);
}
cpu_data *

View File

@@ -13,6 +13,51 @@ namespace obj {
class thread;
}
enum class cr0
{
PE = 0, // Protected mode enable
MP = 1, // Monitor co-processor
ET = 4, // Extension type
NE = 5, // Numeric error
WP = 16, // (ring 0) Write protect
PG = 31, // Paging
};
enum class cr4
{
DE = 3, // Debugging extensions
PAE = 5, // Physical address extension
MCE = 6, // Machine check exception
PGE = 7, // Page global enable
OSXFSR = 9, // OS supports FXSAVE
OSXMMEXCPT = 10, // OS supports SIMD FP exceptions
FSGSBASE = 16, // Enable {RD|WR}{F|G}SBASE instructions
PCIDE = 17, // PCID enable
OSXSAVE = 18, // OS supports XSAVE and extended states
};
enum class xcr0
{
X87,
SSE,
AVX,
BINDREG,
BINDCSR,
OPMASK,
ZMM_Hi256,
ZMM_Hi16,
PKRU = 9,
};
enum class efer
{
SCE = 0, // System call extensions (SYSCALL/SYSRET)
LME = 8, // Long mode enable
LMA = 10, // Long mode active
NXE = 11, // No-execute enable
FFXSR = 14, // Fast FXSAVE
};
struct cpu_state
{
uint64_t r15, r14, r13, r12, r11, r10, r9, r8;

View File

@@ -12,16 +12,9 @@ CR0_WP equ (1 << 16)
CR0_PG equ (1 << 31)
CR0_VAL equ CR0_PE|CR0_MP|CR0_ET|CR0_NE|CR0_WP|CR0_PG
CR4_DE equ (1 << 3)
CR4_PAE equ (1 << 5)
CR4_MCE equ (1 << 6)
CR4_PGE equ (1 << 7)
CR4_OSFXSR equ (1 << 9)
CR4_OSCMMEXCPT equ (1 << 10)
CR4_FSGSBASE equ (1 << 16)
CR4_PCIDE equ (1 << 17)
CR4_INIT equ CR4_PAE|CR4_PGE
CR4_VAL equ CR4_DE|CR4_PAE|CR4_MCE|CR4_PGE|CR4_OSFXSR|CR4_OSCMMEXCPT|CR4_FSGSBASE|CR4_PCIDE
EFER_MSR equ 0xC0000080
EFER_SCE equ (1 << 0)
@@ -102,10 +95,9 @@ align 8
mov gs, ax
mov ss, ax
mov eax, CR4_VAL
mov rdi, [BASE + (.cpu - ap_startup)]
mov rax, [rdi + CPU_DATA.rsp0]
mov rbp, rax
mov rsp, rax
mov rax, [BASE + (.ret - ap_startup)]