mod context;
mod gdt;
mod idt;
#[cfg(target_os = "none")]
mod trap;
use core::arch::asm;
use memory_addr::{MemoryAddr, PhysAddr, VirtAddr};
use x86::{controlregs, msr, tlb};
use x86_64::instructions::interrupts;
pub use self::context::{ExtendedState, FxsaveArea, TaskContext, TrapFrame};
pub use self::gdt::GdtStruct;
pub use self::idt::IdtStruct;
pub use x86_64::structures::tss::TaskStateSegment;
#[inline]
pub fn enable_irqs() {
#[cfg(not(target_os = "none"))]
{
warn!("enable_irqs: not implemented");
}
#[cfg(target_os = "none")]
interrupts::enable()
}
#[inline]
pub fn disable_irqs() {
#[cfg(not(target_os = "none"))]
{
warn!("disable_irqs: not implemented");
}
#[cfg(target_os = "none")]
interrupts::disable()
}
#[inline]
pub fn irqs_enabled() -> bool {
interrupts::are_enabled()
}
#[inline]
pub fn wait_for_irqs() {
if cfg!(target_os = "none") {
unsafe { asm!("hlt") }
} else {
core::hint::spin_loop()
}
}
#[inline]
pub fn halt() {
disable_irqs();
wait_for_irqs(); }
#[inline]
pub fn read_page_table_root() -> PhysAddr {
pa!(unsafe { controlregs::cr3() } as usize).align_down_4k()
}
pub unsafe fn write_page_table_root(root_paddr: PhysAddr) {
let old_root = read_page_table_root();
trace!("set page table root: {:#x} => {:#x}", old_root, root_paddr);
if old_root != root_paddr {
unsafe { controlregs::cr3_write(root_paddr.as_usize() as _) }
}
}
#[inline]
pub fn flush_tlb(vaddr: Option<VirtAddr>) {
if let Some(vaddr) = vaddr {
unsafe { tlb::flush(vaddr.into()) }
} else {
unsafe { tlb::flush_all() }
}
}
#[inline]
pub fn read_thread_pointer() -> usize {
unsafe { msr::rdmsr(msr::IA32_FS_BASE) as usize }
}
#[inline]
pub unsafe fn write_thread_pointer(fs_base: usize) {
unsafe { msr::wrmsr(msr::IA32_FS_BASE, fs_base as u64) }
}