pub use x86_64::{
PrivilegeLevel, VirtAddr as DescriptorAddress,
addr::VirtAddrNotValid,
registers::segmentation::SegmentSelector,
structures::{
gdt::{Descriptor, Entry as GdtEntry, GlobalDescriptorTable},
tss::{InvalidIoMap, TaskStateSegment},
},
};
pub use super::gdt::{TrapStorage, TrapStorageProvider, trap_storage_provider};
pub fn init_trap() {
super::gdt::init();
super::idt::init();
#[cfg(feature = "uspace")]
super::uspace::init_syscall();
}
pub use super::entry::boot::{
BootVectorTable, current_vector_table, install as install_boot_vectors,
};
pub const KERNEL_CR0_STATE: usize = x86::controlregs::Cr0::CR0_ENABLE_PAGING.bits()
| x86::controlregs::Cr0::CR0_ALIGNMENT_MASK.bits()
| x86::controlregs::Cr0::CR0_WRITE_PROTECT.bits()
| x86::controlregs::Cr0::CR0_NUMERIC_ERROR.bits()
| x86::controlregs::Cr0::CR0_EXTENSION_TYPE.bits()
| x86::controlregs::Cr0::CR0_MONITOR_COPROCESSOR.bits()
| x86::controlregs::Cr0::CR0_PROTECTED_MODE.bits();
pub unsafe fn assert_kernel_cr0_state() {
let current = unsafe { x86::controlregs::cr0() };
assert_eq!(
current.bits(),
KERNEL_CR0_STATE,
"invalid x86_64 kernel CR0 state on this CPU"
);
}
pub unsafe fn enable_execute_disable() {
unsafe {
let value = x86::msr::rdmsr(x86::msr::IA32_EFER);
x86::msr::wrmsr(x86::msr::IA32_EFER, value | (1 << 11));
}
}
pub unsafe fn configure_paging() {
use x86::controlregs::{self, Cr0, Cr4};
unsafe {
controlregs::cr0_write(Cr0::from_bits_truncate(KERNEL_CR0_STATE));
controlregs::cr4_write(controlregs::cr4() | Cr4::CR4_ENABLE_GLOBAL_PAGES);
assert_kernel_cr0_state();
}
}
pub unsafe fn enable_xsave_features() {
use x86::{controlregs, cpuid::CpuId};
let Some(info) = CpuId::new().get_feature_info() else {
return;
};
if !info.has_xsave() {
return;
}
unsafe {
controlregs::cr4_write(controlregs::cr4() | controlregs::Cr4::CR4_ENABLE_OS_XSAVE);
let mut bits = controlregs::Xcr0::XCR0_FPU_MMX_STATE | controlregs::Xcr0::XCR0_SSE_STATE;
if info.has_avx() {
bits |= controlregs::Xcr0::XCR0_AVX_STATE;
}
controlregs::xcr0_write(bits);
}
}
#[unsafe(naked)]
pub unsafe extern "C" fn jump_to(_entry: usize, _stack: usize) -> ! {
core::arch::naked_asm!("mov rsp, rsi", "push 0", "xor ebp, ebp", "jmp rdi",);
}