1 pub(super) mod entry;
2 mod handle;
3 pub mod ipi;
4 pub mod msi;
5 pub mod trap;
6
7 use core::any::Any;
8 use core::{
9 arch::asm,
10 sync::atomic::{compiler_fence, Ordering},
11 };
12 use kprobe::ProbeArgs;
13 use log::error;
14 use system_error::SystemError;
15
16 use crate::{
17 arch::CurrentIrqArch,
18 exception::{InterruptArch, IrqFlags, IrqFlagsGuard, IrqNumber},
19 };
20
21 use super::{
22 asm::irqflags::{local_irq_restore, local_irq_save},
23 driver::apic::{lapic_vector::arch_early_irq_init, CurrentApic, LocalAPIC},
24 };
25
26 /// @brief 关闭中断
27 #[inline]
cli()28 pub fn cli() {
29 unsafe {
30 asm!("cli");
31 }
32 }
33
34 /// @brief 开启中断
35 #[inline]
sti()36 pub fn sti() {
37 unsafe {
38 asm!("sti");
39 }
40 }
41
42 pub struct X86_64InterruptArch;
43
44 impl InterruptArch for X86_64InterruptArch {
45 #[inline(never)]
arch_irq_init() -> Result<(), SystemError>46 unsafe fn arch_irq_init() -> Result<(), SystemError> {
47 CurrentIrqArch::interrupt_disable();
48
49 return Ok(());
50 }
interrupt_enable()51 unsafe fn interrupt_enable() {
52 sti();
53 }
54
interrupt_disable()55 unsafe fn interrupt_disable() {
56 cli();
57 }
58
is_irq_enabled() -> bool59 fn is_irq_enabled() -> bool {
60 let rflags: u64;
61 unsafe {
62 asm!("pushfq; pop {}", out(reg) rflags, options(nomem, preserves_flags));
63 }
64 return (rflags & (1 << 9)) != 0;
65 }
66
save_and_disable_irq() -> IrqFlagsGuard67 unsafe fn save_and_disable_irq() -> IrqFlagsGuard {
68 compiler_fence(Ordering::SeqCst);
69 let rflags = local_irq_save();
70 let flags = IrqFlags::new(rflags);
71 let guard = IrqFlagsGuard::new(flags);
72 compiler_fence(Ordering::SeqCst);
73 return guard;
74 }
75
restore_irq(flags: IrqFlags)76 unsafe fn restore_irq(flags: IrqFlags) {
77 compiler_fence(Ordering::SeqCst);
78 local_irq_restore(flags.flags());
79 compiler_fence(Ordering::SeqCst);
80 }
81
probe_total_irq_num() -> u3282 fn probe_total_irq_num() -> u32 {
83 // todo: 从APIC获取
84 // 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/arch/x86/kernel/apic/vector.c?r=&mo=19514&fi=704#704
85 256
86 }
87
ack_bad_irq(irq: IrqNumber)88 fn ack_bad_irq(irq: IrqNumber) {
89 error!("Unexpected IRQ trap at vector {}", irq.data());
90 CurrentApic.send_eoi();
91 }
92
arch_early_irq_init() -> Result<(), SystemError>93 fn arch_early_irq_init() -> Result<(), SystemError> {
94 arch_early_irq_init()
95 }
96
arch_ap_early_irq_init() -> Result<(), SystemError>97 fn arch_ap_early_irq_init() -> Result<(), SystemError> {
98 if !CurrentApic.init_current_cpu() {
99 return Err(SystemError::ENODEV);
100 }
101
102 Ok(())
103 }
104 }
105
106 /// 中断栈帧结构体
107 #[repr(C)]
108 #[derive(Debug, Copy, Clone)]
109 pub struct TrapFrame {
110 pub r15: ::core::ffi::c_ulong,
111 pub r14: ::core::ffi::c_ulong,
112 pub r13: ::core::ffi::c_ulong,
113 pub r12: ::core::ffi::c_ulong,
114 pub r11: ::core::ffi::c_ulong,
115 pub r10: ::core::ffi::c_ulong,
116 pub r9: ::core::ffi::c_ulong,
117 pub r8: ::core::ffi::c_ulong,
118 pub rbx: ::core::ffi::c_ulong,
119 pub rcx: ::core::ffi::c_ulong,
120 pub rdx: ::core::ffi::c_ulong,
121 pub rsi: ::core::ffi::c_ulong,
122 pub rdi: ::core::ffi::c_ulong,
123 pub rbp: ::core::ffi::c_ulong,
124 pub ds: ::core::ffi::c_ulong,
125 pub es: ::core::ffi::c_ulong,
126 pub rax: ::core::ffi::c_ulong,
127 pub func: ::core::ffi::c_ulong,
128 pub errcode: ::core::ffi::c_ulong,
129 pub rip: ::core::ffi::c_ulong,
130 pub cs: ::core::ffi::c_ulong,
131 pub rflags: ::core::ffi::c_ulong,
132 pub rsp: ::core::ffi::c_ulong,
133 pub ss: ::core::ffi::c_ulong,
134 }
135
136 impl Default for TrapFrame {
default() -> Self137 fn default() -> Self {
138 Self::new()
139 }
140 }
141
142 impl TrapFrame {
new() -> Self143 pub fn new() -> Self {
144 Self {
145 r15: 0,
146 r14: 0,
147 r13: 0,
148 r12: 0,
149 r11: 0,
150 r10: 0,
151 r9: 0,
152 r8: 0,
153 rbx: 0,
154 rcx: 0,
155 rdx: 0,
156 rsi: 0,
157 rdi: 0,
158 rbp: 0,
159 ds: 0,
160 es: 0,
161 rax: 0,
162 func: 0,
163 errcode: 0,
164 rip: 0,
165 cs: 0,
166 rflags: 0,
167 rsp: 0,
168 ss: 0,
169 }
170 }
171
172 /// 设置中断栈帧返回值
set_return_value(&mut self, value: usize)173 pub fn set_return_value(&mut self, value: usize) {
174 self.rax = value as u64;
175 }
176
177 /// 判断当前中断是否来自用户模式
is_from_user(&self) -> bool178 pub fn is_from_user(&self) -> bool {
179 return (self.cs & 0x3) != 0;
180 }
181 /// 设置当前的程序计数器
set_pc(&mut self, pc: usize)182 pub fn set_pc(&mut self, pc: usize) {
183 self.rip = pc as u64;
184 }
185 }
186
187 impl ProbeArgs for TrapFrame {
as_any(&self) -> &dyn Any188 fn as_any(&self) -> &dyn Any {
189 self
190 }
break_address(&self) -> usize191 fn break_address(&self) -> usize {
192 (self.rip - 1) as usize
193 }
194
debug_address(&self) -> usize195 fn debug_address(&self) -> usize {
196 self.rip as usize
197 }
198 }
199