47 lines
1.1 KiB
Rust
47 lines
1.1 KiB
Rust
use x86_64::{VirtAddr, registers::rflags::RFlags, structures::idt::InterruptStackFrameValue};
|
|
|
|
use crate::{
|
|
arch::{
|
|
asm::ltr,
|
|
x86_64::{
|
|
gdt::{SELECTORS, dump_gdt},
|
|
interrupts::IDT,
|
|
},
|
|
},
|
|
log::{LOGGER, LogLevel},
|
|
log_info,
|
|
memory::alloc::format,
|
|
};
|
|
|
|
pub fn init() -> Result<(), ()> {
|
|
// Ensure GDT exists
|
|
SELECTORS.gdt.load();
|
|
log_info!("GDT loaded!");
|
|
// Load IDT
|
|
IDT.load();
|
|
log_info!("IDT loaded!");
|
|
x86_64::registers::model_specific::Star::write(
|
|
SELECTORS.sel_user_code,
|
|
SELECTORS.sel_user_stack,
|
|
SELECTORS.sel_kernel_code,
|
|
SELECTORS.sel_kernel_stack,
|
|
)
|
|
.expect("Segment order in GDT is bad");
|
|
dump_gdt();
|
|
ltr(SELECTORS.sel_tss.index());
|
|
Ok(())
|
|
}
|
|
|
|
pub fn jump_to_usermode(sp: VirtAddr, ip: VirtAddr) -> ! {
|
|
unsafe {
|
|
InterruptStackFrameValue::new(
|
|
ip,
|
|
SELECTORS.sel_user_code,
|
|
RFlags::INTERRUPT_FLAG,
|
|
sp,
|
|
SELECTORS.sel_user_stack,
|
|
)
|
|
.iretq();
|
|
}
|
|
}
|