11a2eaa40Slogin #![allow(dead_code)] 2*f678331aShanjiezhou use core::{ 3*f678331aShanjiezhou arch::asm, 4*f678331aShanjiezhou sync::atomic::{compiler_fence, Ordering}, 5*f678331aShanjiezhou }; 6*f678331aShanjiezhou 7*f678331aShanjiezhou use crate::exception::{InterruptArch, IrqFlags, IrqFlagsGuard}; 8*f678331aShanjiezhou 9*f678331aShanjiezhou use super::asm::irqflags::{local_irq_restore, local_irq_save}; 101a2eaa40Slogin 111a2eaa40Slogin /// @brief 关闭中断 121a2eaa40Slogin #[inline] 131a2eaa40Slogin pub fn cli() { 141a2eaa40Slogin unsafe { 151a2eaa40Slogin asm!("cli"); 161a2eaa40Slogin } 171a2eaa40Slogin } 181a2eaa40Slogin 191a2eaa40Slogin /// @brief 开启中断 201a2eaa40Slogin #[inline] 211a2eaa40Slogin pub fn sti() { 221a2eaa40Slogin unsafe { 231a2eaa40Slogin asm!("sti"); 241a2eaa40Slogin } 251a2eaa40Slogin } 26*f678331aShanjiezhou 27*f678331aShanjiezhou pub struct X86_64InterruptArch; 28*f678331aShanjiezhou 29*f678331aShanjiezhou impl InterruptArch for X86_64InterruptArch { 30*f678331aShanjiezhou unsafe fn interrupt_enable() { 31*f678331aShanjiezhou sti(); 32*f678331aShanjiezhou } 33*f678331aShanjiezhou 34*f678331aShanjiezhou unsafe fn interrupt_disable() { 35*f678331aShanjiezhou cli(); 36*f678331aShanjiezhou } 37*f678331aShanjiezhou 38*f678331aShanjiezhou fn is_irq_enabled() -> bool { 39*f678331aShanjiezhou let rflags: u64; 40*f678331aShanjiezhou unsafe { 41*f678331aShanjiezhou asm!("pushfq; pop {}", out(reg) rflags); 42*f678331aShanjiezhou } 43*f678331aShanjiezhou return rflags & (1 << 9) != 0; 44*f678331aShanjiezhou } 45*f678331aShanjiezhou 46*f678331aShanjiezhou unsafe fn save_and_disable_irq() -> IrqFlagsGuard { 47*f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 48*f678331aShanjiezhou let mut rflags: u64 = 0; 49*f678331aShanjiezhou local_irq_save(&mut rflags); 50*f678331aShanjiezhou let flags = IrqFlags::new(rflags); 51*f678331aShanjiezhou let guard = IrqFlagsGuard::new(flags); 52*f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 53*f678331aShanjiezhou return guard; 54*f678331aShanjiezhou } 55*f678331aShanjiezhou 56*f678331aShanjiezhou unsafe fn restore_irq(flags: IrqFlags) { 57*f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 58*f678331aShanjiezhou local_irq_restore(&flags.flags()); 59*f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 60*f678331aShanjiezhou } 61*f678331aShanjiezhou } 62