1 #![allow(dead_code)] 2 3 pub mod ipi; 4 5 use core::{ 6 arch::asm, 7 sync::atomic::{compiler_fence, Ordering}, 8 }; 9 10 use crate::exception::{InterruptArch, IrqFlags, IrqFlagsGuard}; 11 12 use super::asm::irqflags::{local_irq_restore, local_irq_save}; 13 14 /// @brief 关闭中断 15 #[inline] cli()16pub fn cli() { 17 unsafe { 18 asm!("cli"); 19 } 20 } 21 22 /// @brief 开启中断 23 #[inline] sti()24pub fn sti() { 25 unsafe { 26 asm!("sti"); 27 } 28 } 29 30 pub struct X86_64InterruptArch; 31 32 impl InterruptArch for X86_64InterruptArch { interrupt_enable()33 unsafe fn interrupt_enable() { 34 sti(); 35 } 36 interrupt_disable()37 unsafe fn interrupt_disable() { 38 cli(); 39 } 40 is_irq_enabled() -> bool41 fn is_irq_enabled() -> bool { 42 let rflags: u64; 43 unsafe { 44 asm!("pushfq; pop {}", out(reg) rflags, options(nomem, preserves_flags)); 45 } 46 return rflags & (1 << 9) != 0; 47 } 48 save_and_disable_irq() -> IrqFlagsGuard49 unsafe fn save_and_disable_irq() -> IrqFlagsGuard { 50 compiler_fence(Ordering::SeqCst); 51 let rflags = local_irq_save(); 52 let flags = IrqFlags::new(rflags); 53 let guard = IrqFlagsGuard::new(flags); 54 compiler_fence(Ordering::SeqCst); 55 return guard; 56 } 57 restore_irq(flags: IrqFlags)58 unsafe fn restore_irq(flags: IrqFlags) { 59 compiler_fence(Ordering::SeqCst); 60 local_irq_restore(flags.flags()); 61 compiler_fence(Ordering::SeqCst); 62 } 63 } 64