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]
cli()13 pub fn cli() {
14     unsafe {
15         asm!("cli");
16     }
17 }
18 
19 /// @brief 开启中断
20 #[inline]
sti()21 pub fn sti() {
22     unsafe {
23         asm!("sti");
24     }
25 }
26 
27 pub struct X86_64InterruptArch;
28 
29 impl InterruptArch for X86_64InterruptArch {
interrupt_enable()30     unsafe fn interrupt_enable() {
31         sti();
32     }
33 
interrupt_disable()34     unsafe fn interrupt_disable() {
35         cli();
36     }
37 
is_irq_enabled() -> bool38     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 
save_and_disable_irq() -> IrqFlagsGuard46     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 
restore_irq(flags: IrqFlags)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