xref: /DragonOS/kernel/src/arch/x86_64/interrupt/mod.rs (revision de71ec259cd21c782f4031b01635eb8ad3df1943)
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]
16 pub fn cli() {
17     unsafe {
18         asm!("cli");
19     }
20 }
21 
22 /// @brief 开启中断
23 #[inline]
24 pub fn sti() {
25     unsafe {
26         asm!("sti");
27     }
28 }
29 
30 pub struct X86_64InterruptArch;
31 
32 impl InterruptArch for X86_64InterruptArch {
33     unsafe fn interrupt_enable() {
34         sti();
35     }
36 
37     unsafe fn interrupt_disable() {
38         cli();
39     }
40 
41     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 
49     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 
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 
65 /// 中断栈帧结构体
66 #[repr(C)]
67 #[derive(Debug, Copy, Clone)]
68 pub struct TrapFrame {
69     pub r15: ::core::ffi::c_ulong,
70     pub r14: ::core::ffi::c_ulong,
71     pub r13: ::core::ffi::c_ulong,
72     pub r12: ::core::ffi::c_ulong,
73     pub r11: ::core::ffi::c_ulong,
74     pub r10: ::core::ffi::c_ulong,
75     pub r9: ::core::ffi::c_ulong,
76     pub r8: ::core::ffi::c_ulong,
77     pub rbx: ::core::ffi::c_ulong,
78     pub rcx: ::core::ffi::c_ulong,
79     pub rdx: ::core::ffi::c_ulong,
80     pub rsi: ::core::ffi::c_ulong,
81     pub rdi: ::core::ffi::c_ulong,
82     pub rbp: ::core::ffi::c_ulong,
83     pub ds: ::core::ffi::c_ulong,
84     pub es: ::core::ffi::c_ulong,
85     pub rax: ::core::ffi::c_ulong,
86     pub func: ::core::ffi::c_ulong,
87     pub errcode: ::core::ffi::c_ulong,
88     pub rip: ::core::ffi::c_ulong,
89     pub cs: ::core::ffi::c_ulong,
90     pub rflags: ::core::ffi::c_ulong,
91     pub rsp: ::core::ffi::c_ulong,
92     pub ss: ::core::ffi::c_ulong,
93 }
94 
95 impl TrapFrame {
96     pub fn new() -> Self {
97         Self {
98             r15: 0,
99             r14: 0,
100             r13: 0,
101             r12: 0,
102             r11: 0,
103             r10: 0,
104             r9: 0,
105             r8: 0,
106             rbx: 0,
107             rcx: 0,
108             rdx: 0,
109             rsi: 0,
110             rdi: 0,
111             rbp: 0,
112             ds: 0,
113             es: 0,
114             rax: 0,
115             func: 0,
116             errcode: 0,
117             rip: 0,
118             cs: 0,
119             rflags: 0,
120             rsp: 0,
121             ss: 0,
122         }
123     }
124 
125     /// 设置中断栈帧返回值
126     pub fn set_return_value(&mut self, value: usize) {
127         self.rax = value as u64;
128     }
129 
130     /// 判断当前中断是否来自用户模式
131     pub fn from_user(&self) -> bool {
132         if (self.cs & 0x3) != 0 {
133             return true;
134         } else {
135             return false;
136         }
137     }
138 }
139