diff --git a/moon/src/arch/x86_64/cpu.rs b/moon/src/arch/x86_64/cpu.rs index 16b3a9eb..8d9f0242 100644 --- a/moon/src/arch/x86_64/cpu.rs +++ b/moon/src/arch/x86_64/cpu.rs @@ -4,6 +4,8 @@ use core::arch::x86_64::{__cpuid as do_cpuid, CpuidResult}; use core::arch::asm; +use super::gdt; + fn safe_cpuid(leaf: u32) -> CpuidResult { return unsafe { do_cpuid(leaf) }; } @@ -22,10 +24,18 @@ pub fn halt() -> ! { } } -pub fn wait_for_interrupt() -> () { +pub fn wait_for_interrupt() +{ unsafe { asm!("hlt"); } } -pub fn breakpoint() -> () { +pub fn breakpoint() +{ unsafe { asm!("int3"); } +} + +pub fn platform_init() +{ + gdt::init(); + gdt::load_and_reload_segment_registers(); } \ No newline at end of file diff --git a/moon/src/arch/x86_64/gdt.rs b/moon/src/arch/x86_64/gdt.rs new file mode 100644 index 00000000..493d7043 --- /dev/null +++ b/moon/src/arch/x86_64/gdt.rs @@ -0,0 +1,35 @@ +#![cfg(target_arch = "x86_64")] +#![allow(dead_code)] + +use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable}; +use x86_64::registers::segmentation::{CS, SS, Segment, SegmentSelector}; +use x86_64::PrivilegeLevel; +use spin::Mutex; + +static mut GDT: GlobalDescriptorTable = GlobalDescriptorTable::new(); +static GDT_LOCK: Mutex = Mutex::new(0); // we cannot lock the GDT directly as it must stay in the same place in memory and that behaves weirdly with mutexes + +fn add_entry(descriptor: Descriptor) +{ + GDT_LOCK.lock(); + unsafe { GDT.add_entry(descriptor); } +} + +pub fn init() +{ + add_entry(Descriptor::kernel_code_segment()); + add_entry(Descriptor::kernel_data_segment()); + add_entry(Descriptor::user_code_segment()); + add_entry(Descriptor::user_data_segment()); + // TODO: add a TSS. +} + +pub fn load_and_reload_segment_registers() +{ + GDT_LOCK.lock(); + unsafe { + GDT.load(); + CS::set_reg(SegmentSelector::new(1, PrivilegeLevel::Ring0)); + SS::set_reg(SegmentSelector::new(2, PrivilegeLevel::Ring0)); + } +} \ No newline at end of file diff --git a/moon/src/arch/x86_64/mod.rs b/moon/src/arch/x86_64/mod.rs index be3cffa5..42037c1e 100644 --- a/moon/src/arch/x86_64/mod.rs +++ b/moon/src/arch/x86_64/mod.rs @@ -1,4 +1,5 @@ #![cfg(target_arch = "x86_64")] pub mod cpu; pub mod io; -pub mod interrupts; \ No newline at end of file +pub mod interrupts; +mod gdt; \ No newline at end of file diff --git a/moon/src/main.rs b/moon/src/main.rs index 5d6e5760..9ec548b9 100644 --- a/moon/src/main.rs +++ b/moon/src/main.rs @@ -25,6 +25,8 @@ pub extern "C" fn _start() -> ! { init::halt_other_cores(); init::check_magic(); + cpu::platform_init(); + interrupts::load(); video::clear(Color::White);