diff --git a/headers/private/kernel/arch/x86/arch_cpu.h b/headers/private/kernel/arch/x86/arch_cpu.h index fbf9009046..4d769b3a47 100644 --- a/headers/private/kernel/arch/x86/arch_cpu.h +++ b/headers/private/kernel/arch/x86/arch_cpu.h @@ -449,10 +449,14 @@ | X86_EFLAGS_AUXILIARY_CARRY | X86_EFLAGS_ZERO | X86_EFLAGS_SIGN \ | X86_EFLAGS_DIRECTION | X86_EFLAGS_OVERFLOW) +#define CR0_PAGING (1UL << 31) #define CR0_CACHE_DISABLE (1UL << 30) #define CR0_NOT_WRITE_THROUGH (1UL << 29) +#define CR0_WRITE_PROTECT (1UL << 16) +#define CR0_NUMERIC_ERROR (1UL << 5) #define CR0_FPU_EMULATION (1UL << 2) #define CR0_MONITOR_FPU (1UL << 1) +#define CR0_PROTECTED_MODE (1UL << 0) // Control Register CR4 flags §2.5 // Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3A: System Programming Guide, Part 1 diff --git a/src/system/boot/platform/bios_ia32/long.cpp b/src/system/boot/platform/bios_ia32/long.cpp index 4cee5d2d81..91dfd917a6 100644 --- a/src/system/boot/platform/bios_ia32/long.cpp +++ b/src/system/boot/platform/bios_ia32/long.cpp @@ -318,8 +318,6 @@ long_smp_start_kernel(void) { uint32 cpu = smp_get_current_cpu(); - // Important. Make sure supervisor threads can fault on read only pages... - asm("movl %%eax, %%cr0" : : "a" ((1 << 31) | (1 << 16) | (1 << 5) | 1)); asm("cld"); asm("fninit"); enable_sse(); diff --git a/src/system/boot/platform/bios_ia32/mmu.cpp b/src/system/boot/platform/bios_ia32/mmu.cpp index 22158aae85..744334c36c 100644 --- a/src/system/boot/platform/bios_ia32/mmu.cpp +++ b/src/system/boot/platform/bios_ia32/mmu.cpp @@ -372,8 +372,6 @@ init_page_directory(void) // switch to the new pgdir and enable paging asm("movl %0, %%eax;" "movl %%eax, %%cr3;" : : "m" (sPageDirectory) : "eax"); - // Important. Make sure supervisor threads can fault on read only pages... - asm("movl %%eax, %%cr0" : : "a" ((1 << 31) | (1 << 16) | (1 << 5) | 1)); } diff --git a/src/system/boot/platform/bios_ia32/start.cpp b/src/system/boot/platform/bios_ia32/start.cpp index 7477853bd0..a651487cad 100644 --- a/src/system/boot/platform/bios_ia32/start.cpp +++ b/src/system/boot/platform/bios_ia32/start.cpp @@ -89,8 +89,6 @@ smp_start_kernel(void) preloaded_elf32_image *image = static_cast( gKernelArgs.kernel_image.Pointer()); - // Important. Make sure supervisor threads can fault on read only pages... - asm("movl %%eax, %%cr0" : : "a" ((1 << 31) | (1 << 16) | (1 << 5) | 1)); asm("cld"); asm("fninit"); diff --git a/src/system/boot/platform/efi/arch/x86/entry.S b/src/system/boot/platform/efi/arch/x86/entry.S index 72865cff06..1bbe10668b 100644 --- a/src/system/boot/platform/efi/arch/x86/entry.S +++ b/src/system/boot/platform/efi/arch/x86/entry.S @@ -53,12 +53,9 @@ FUNCTION(arch_enter_kernel): movl %esi, %eax lgdt (%eax) - // initialize CR0 - // - bit #31: Enable Paging - // - bit #16: Write Protect - // - bit #5: Numeric Error Handling - // - bit #0: Protected Mode - movl $0x80010021, %eax + movl %cr0, %eax + orl $0x01, %eax // set the PE bit (0) to switch to protected mode + orl $0x80000000, %eax // set the PG bit (31) to enable paging movl %eax, %cr0 // Set data segments. diff --git a/src/system/boot/platform/efi/arch/x86_64/arch_mmu.cpp b/src/system/boot/platform/efi/arch/x86_64/arch_mmu.cpp index d5e385686d..049e16450c 100644 --- a/src/system/boot/platform/efi/arch/x86_64/arch_mmu.cpp +++ b/src/system/boot/platform/efi/arch/x86_64/arch_mmu.cpp @@ -181,9 +181,6 @@ arch_mmu_post_efi_setup(size_t memory_map_size, start, start + size, size); } #endif - - // Important. Make sure supervisor threads can fault on read only pages... - asm("mov %%rax, %%cr0" : : "a" ((1 << 31) | (1 << 16) | (1 << 5) | 1)); } diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index b8b978b928..44529ad6d3 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -350,7 +350,7 @@ x86_init_fpu(void) #ifndef __x86_64__ if (!x86_check_feature(IA32_FEATURE_FPU, FEATURE_COMMON)) { // No FPU... time to install one in your 386? - dprintf("%s: Warning: CPU has no reported FPU.\n", __func__); + panic("CPU has no reported FPU!\n"); gX86SwapFPUFunc = x86_noop_swap; return; } @@ -359,17 +359,13 @@ x86_init_fpu(void) || !x86_check_feature(IA32_FEATURE_FXSR, FEATURE_COMMON)) { dprintf("%s: CPU has no SSE... just enabling FPU.\n", __func__); // we don't have proper SSE support, just enable FPU - x86_write_cr0(x86_read_cr0() & ~(CR0_FPU_EMULATION | CR0_MONITOR_FPU)); gX86SwapFPUFunc = x86_fnsave_swap; return; } -#endif - dprintf("%s: CPU has SSE... enabling FXSR and XMM.\n", __func__); -#ifndef __x86_64__ // enable OS support for SSE + dprintf("%s: CPU has SSE... enabling FXSR and XMM.\n", __func__); x86_write_cr4(x86_read_cr4() | CR4_OS_FXSR | CR4_OS_XMM_EXCEPTION); - x86_write_cr0(x86_read_cr0() & ~(CR0_FPU_EMULATION | CR0_MONITOR_FPU)); gX86SwapFPUFunc = x86_fxsave_swap; gHasSSE = true; @@ -1565,6 +1561,9 @@ x86_double_fault_get_cpu() status_t arch_cpu_preboot_init_percpu(kernel_args* args, int cpu) { + // Reset CR0. + x86_write_cr0(CR0_PROTECTED_MODE | CR0_PAGING | CR0_WRITE_PROTECT | CR0_NUMERIC_ERROR); + if (cpu == 0) { // We can't allocate pages at this stage in the boot process, only virtual addresses. sDoubleFaultStacks = vm_allocate_early(args,