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()16 pub fn cli() {
17     unsafe {
18         asm!("cli");
19     }
20 }
21 
22 /// @brief 开启中断
23 #[inline]
sti()24 pub 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