xref: /DragonOS/kernel/src/arch/x86_64/interrupt/mod.rs (revision 8d72b68da9339ec97e1b8929bcf2946f0fd83cd5)
1 #![allow(dead_code)]
2 
3 mod c_adapter;
4 pub mod ipi;
5 
6 use core::{
7     arch::asm,
8     sync::atomic::{compiler_fence, Ordering},
9 };
10 
11 use crate::exception::{InterruptArch, IrqFlags, IrqFlagsGuard};
12 
13 use super::asm::irqflags::{local_irq_restore, local_irq_save};
14 
15 /// @brief 关闭中断
16 #[inline]
17 pub fn cli() {
18     unsafe {
19         asm!("cli");
20     }
21 }
22 
23 /// @brief 开启中断
24 #[inline]
25 pub fn sti() {
26     unsafe {
27         asm!("sti");
28     }
29 }
30 
31 pub struct X86_64InterruptArch;
32 
33 impl InterruptArch for X86_64InterruptArch {
34     unsafe fn interrupt_enable() {
35         sti();
36     }
37 
38     unsafe fn interrupt_disable() {
39         cli();
40     }
41 
42     fn is_irq_enabled() -> bool {
43         let rflags: u64;
44         unsafe {
45             asm!("pushfq; pop {}", out(reg) rflags, options(nomem, preserves_flags));
46         }
47         return (rflags & (1 << 9)) != 0;
48     }
49 
50     unsafe fn save_and_disable_irq() -> IrqFlagsGuard {
51         compiler_fence(Ordering::SeqCst);
52         let rflags = local_irq_save();
53         let flags = IrqFlags::new(rflags);
54         let guard = IrqFlagsGuard::new(flags);
55         compiler_fence(Ordering::SeqCst);
56         return guard;
57     }
58 
59     unsafe fn restore_irq(flags: IrqFlags) {
60         compiler_fence(Ordering::SeqCst);
61         local_irq_restore(flags.flags());
62         compiler_fence(Ordering::SeqCst);
63     }
64 }
65 
66 /// 中断栈帧结构体
67 #[repr(C)]
68 #[derive(Debug, Copy, Clone)]
69 pub struct TrapFrame {
70     pub r15: ::core::ffi::c_ulong,
71     pub r14: ::core::ffi::c_ulong,
72     pub r13: ::core::ffi::c_ulong,
73     pub r12: ::core::ffi::c_ulong,
74     pub r11: ::core::ffi::c_ulong,
75     pub r10: ::core::ffi::c_ulong,
76     pub r9: ::core::ffi::c_ulong,
77     pub r8: ::core::ffi::c_ulong,
78     pub rbx: ::core::ffi::c_ulong,
79     pub rcx: ::core::ffi::c_ulong,
80     pub rdx: ::core::ffi::c_ulong,
81     pub rsi: ::core::ffi::c_ulong,
82     pub rdi: ::core::ffi::c_ulong,
83     pub rbp: ::core::ffi::c_ulong,
84     pub ds: ::core::ffi::c_ulong,
85     pub es: ::core::ffi::c_ulong,
86     pub rax: ::core::ffi::c_ulong,
87     pub func: ::core::ffi::c_ulong,
88     pub errcode: ::core::ffi::c_ulong,
89     pub rip: ::core::ffi::c_ulong,
90     pub cs: ::core::ffi::c_ulong,
91     pub rflags: ::core::ffi::c_ulong,
92     pub rsp: ::core::ffi::c_ulong,
93     pub ss: ::core::ffi::c_ulong,
94 }
95 
96 impl TrapFrame {
97     pub fn new() -> Self {
98         Self {
99             r15: 0,
100             r14: 0,
101             r13: 0,
102             r12: 0,
103             r11: 0,
104             r10: 0,
105             r9: 0,
106             r8: 0,
107             rbx: 0,
108             rcx: 0,
109             rdx: 0,
110             rsi: 0,
111             rdi: 0,
112             rbp: 0,
113             ds: 0,
114             es: 0,
115             rax: 0,
116             func: 0,
117             errcode: 0,
118             rip: 0,
119             cs: 0,
120             rflags: 0,
121             rsp: 0,
122             ss: 0,
123         }
124     }
125 
126     /// 设置中断栈帧返回值
127     pub fn set_return_value(&mut self, value: usize) {
128         self.rax = value as u64;
129     }
130 
131     /// 判断当前中断是否来自用户模式
132     pub fn from_user(&self) -> bool {
133         if (self.cs & 0x3) != 0 {
134             return true;
135         } else {
136             return false;
137         }
138     }
139 }
140