Compare commits
2 Commits
739fa56ece
...
f362e0e6f4
Author | SHA1 | Date | |
---|---|---|---|
f362e0e6f4 | |||
896ee2d7e9 |
@ -4,6 +4,8 @@
|
|||||||
use core::arch::x86_64::{__cpuid as do_cpuid, CpuidResult};
|
use core::arch::x86_64::{__cpuid as do_cpuid, CpuidResult};
|
||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
|
|
||||||
|
use super::gdt;
|
||||||
|
|
||||||
fn safe_cpuid(leaf: u32) -> CpuidResult {
|
fn safe_cpuid(leaf: u32) -> CpuidResult {
|
||||||
return unsafe { do_cpuid(leaf) };
|
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"); }
|
unsafe { asm!("hlt"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn breakpoint() -> () {
|
pub fn breakpoint()
|
||||||
|
{
|
||||||
unsafe { asm!("int3"); }
|
unsafe { asm!("int3"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn platform_init()
|
||||||
|
{
|
||||||
|
gdt::init();
|
||||||
|
gdt::load_and_reload_segment_registers();
|
||||||
|
}
|
35
moon/src/arch/x86_64/gdt.rs
Normal file
35
moon/src/arch/x86_64/gdt.rs
Normal file
@ -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<u64> = 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));
|
||||||
|
}
|
||||||
|
}
|
@ -2,3 +2,4 @@
|
|||||||
pub mod cpu;
|
pub mod cpu;
|
||||||
pub mod io;
|
pub mod io;
|
||||||
pub mod interrupts;
|
pub mod interrupts;
|
||||||
|
mod gdt;
|
@ -25,6 +25,8 @@ pub extern "C" fn _start() -> ! {
|
|||||||
init::halt_other_cores();
|
init::halt_other_cores();
|
||||||
init::check_magic();
|
init::check_magic();
|
||||||
|
|
||||||
|
cpu::platform_init();
|
||||||
|
|
||||||
interrupts::load();
|
interrupts::load();
|
||||||
|
|
||||||
video::clear(Color::White);
|
video::clear(Color::White);
|
||||||
|
0
tools/build-stable.sh
Normal file → Executable file
0
tools/build-stable.sh
Normal file → Executable file
0
tools/install-stable.sh
Normal file → Executable file
0
tools/install-stable.sh
Normal file → Executable file
0
tools/setup-bootloader.sh
Normal file → Executable file
0
tools/setup-bootloader.sh
Normal file → Executable file
Loading…
Reference in New Issue
Block a user