1mod context;
2mod gdt;
3mod idt;
4
5#[cfg(feature = "uspace")]
6mod syscall;
7
8#[cfg(feature = "uspace")]
9mod tls;
10
11#[cfg(target_os = "none")]
12mod trap;
13
14use core::arch::asm;
15
16use memory_addr::{MemoryAddr, PhysAddr, VirtAddr};
17use x86::{controlregs, msr, tlb};
18use x86_64::instructions::interrupts;
19
20pub use self::context::{ExtendedState, FxsaveArea, TaskContext, TrapFrame};
21pub use self::gdt::{GdtStruct, init_gdt, tss_get_rsp0, tss_set_rsp0};
22pub use self::idt::{IdtStruct, init_idt};
23
24#[cfg(feature = "uspace")]
25pub use self::{context::UspaceContext, syscall::init_syscall};
26
27#[inline]
29pub fn enable_irqs() {
30 #[cfg(not(target_os = "none"))]
31 {
32 warn!("enable_irqs: not implemented");
33 }
34 #[cfg(target_os = "none")]
35 interrupts::enable()
36}
37
38#[inline]
40pub fn disable_irqs() {
41 #[cfg(not(target_os = "none"))]
42 {
43 warn!("disable_irqs: not implemented");
44 }
45 #[cfg(target_os = "none")]
46 interrupts::disable()
47}
48
49#[inline]
51pub fn irqs_enabled() -> bool {
52 interrupts::are_enabled()
53}
54
55#[inline]
59pub fn wait_for_irqs() {
60 if cfg!(target_os = "none") {
61 unsafe { asm!("hlt") }
62 } else {
63 core::hint::spin_loop()
64 }
65}
66
67#[inline]
69pub fn halt() {
70 disable_irqs();
71 wait_for_irqs(); }
73
74#[inline]
78pub fn read_page_table_root() -> PhysAddr {
79 pa!(unsafe { controlregs::cr3() } as usize).align_down_4k()
80}
81
82pub unsafe fn write_page_table_root(root_paddr: PhysAddr) {
88 let old_root = read_page_table_root();
89 trace!("set page table root: {:#x} => {:#x}", old_root, root_paddr);
90 if old_root != root_paddr {
91 unsafe { controlregs::cr3_write(root_paddr.as_usize() as _) }
92 }
93}
94
95#[inline]
100pub fn flush_tlb(vaddr: Option<VirtAddr>) {
101 if let Some(vaddr) = vaddr {
102 unsafe { tlb::flush(vaddr.into()) }
103 } else {
104 unsafe { tlb::flush_all() }
105 }
106}
107
108#[inline]
112pub fn read_thread_pointer() -> usize {
113 unsafe { msr::rdmsr(msr::IA32_FS_BASE) as usize }
114}
115
116#[inline]
124pub unsafe fn write_thread_pointer(fs_base: usize) {
125 unsafe { msr::wrmsr(msr::IA32_FS_BASE, fs_base as u64) }
126}
127
128pub fn cpu_init() {
134 init_gdt();
135 init_idt();
136 #[cfg(feature = "uspace")]
137 init_syscall();
138}