mod allocator;
mod gdt;
mod interrupts;
pub mod keyboard;
mod memory;
pub fn hlt_loop() -> !
{
loop
{
x86_64::instructions::hlt();
}
}
pub struct System {}
impl System
{
pub fn new() -> Self
{
Self {}
}
pub fn initialise(&self, boot_info: &'static bootloader::BootInfo)
{
gdt::init();
interrupts::init_idt();
unsafe {
interrupts::PICS.lock().initialize();
}
x86_64::instructions::interrupts::enable();
let phys_mem_offset = x86_64::VirtAddr::new(boot_info.physical_memory_offset);
let mut mapper = unsafe { memory::init(phys_mem_offset) };
let mut frame_allocator =
unsafe { memory::BootInfoFrameAllocator::init(&boot_info.memory_map) };
allocator::init_heap(&mut mapper, &mut frame_allocator).unwrap();
}
}
impl crate::devices::Device for System {}
impl crate::devices::System for System
{
fn shutdown(&self)
{
#[cfg(feature = "qemu")]
{
mango_core::qemu::exit_qemu(mango_core::qemu::QemuExitCode::Success);
}
}
fn wait_forever(&self) -> !
{
loop
{
x86_64::instructions::hlt();
}
}
fn idle_if<T: Fn() -> bool>(&self, cond: T)
{
use x86_64::instructions::interrupts;
interrupts::disable();
if cond()
{
interrupts::enable_and_hlt();
}
else
{
interrupts::enable();
}
}
fn disable_interruptions(&self)
{
x86_64::instructions::interrupts::disable();
}
fn enable_interruptions(&self)
{
x86_64::instructions::interrupts::enable();
}
}