xref: /DragonOS/kernel/src/arch/x86_64/interrupt/mod.rs (revision f678331a3315b7847f08ab32b42d5bf49a9f3a6a)
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