kernel/x86: Initialize CR0 in the kernel more than the bootloader.

The bootloader is now only responsible for setting up Protected Mode
and Paging. It otherwise preserves the existing CR0, and leaves setup
to the kernel.

The kernel now sets CR0 for each CPU in preboot_init_percpu().
Some redundant sets are removed from x86_init_fpu, which now
panic()s in the case where we don't have a FPU, and avoids
unnecessary prints.

This fixes a massive oversight where CR0 was never reset on x86
systems booted using the EFI loader, except on the boot CPU! That
meant that NUMERIC_ERROR and possibly even WRITE_PROTECT were
simply not set on non-boot CPUs, unless the EFI BIOS had set them up
already. (On the BIOS loader, smp_start_kernel() ran on all CPUs.)

Fixes NVMM initialization on non-boot CPUs on Intel hardware.
This commit is contained in:
Augustin Cavalier
2026-06-04 18:18:28 -04:00
parent f03734abc9
commit 658cb74bed
7 changed files with 12 additions and 21 deletions
@@ -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