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