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