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