xref: /DragonOS/kernel/src/arch/x86_64/interrupt/mod.rs (revision f2022a8a1cc4a8e2a85e9061e036e9c491a2fa00)
170a4e555SLoGin mod c_adapter;
2*f2022a8aSLoGin pub(super) mod entry;
3aa0367d6SLoGin pub mod ipi;
4*f2022a8aSLoGin pub mod trap;
5aa0367d6SLoGin 
6f678331aShanjiezhou use core::{
7f678331aShanjiezhou     arch::asm,
8f678331aShanjiezhou     sync::atomic::{compiler_fence, Ordering},
9f678331aShanjiezhou };
10f678331aShanjiezhou 
11*f2022a8aSLoGin use system_error::SystemError;
12f678331aShanjiezhou 
13*f2022a8aSLoGin use crate::{
14*f2022a8aSLoGin     arch::CurrentIrqArch,
15*f2022a8aSLoGin     exception::{InterruptArch, IrqFlags, IrqFlagsGuard},
16*f2022a8aSLoGin };
17*f2022a8aSLoGin 
18*f2022a8aSLoGin use self::entry::setup_interrupt_gate;
19*f2022a8aSLoGin 
20*f2022a8aSLoGin use super::{
21*f2022a8aSLoGin     asm::irqflags::{local_irq_restore, local_irq_save},
22*f2022a8aSLoGin     driver::apic::{CurrentApic, LocalAPIC},
23*f2022a8aSLoGin };
241a2eaa40Slogin 
251a2eaa40Slogin /// @brief 关闭中断
261a2eaa40Slogin #[inline]
271a2eaa40Slogin pub fn cli() {
281a2eaa40Slogin     unsafe {
291a2eaa40Slogin         asm!("cli");
301a2eaa40Slogin     }
311a2eaa40Slogin }
321a2eaa40Slogin 
331a2eaa40Slogin /// @brief 开启中断
341a2eaa40Slogin #[inline]
351a2eaa40Slogin pub fn sti() {
361a2eaa40Slogin     unsafe {
371a2eaa40Slogin         asm!("sti");
381a2eaa40Slogin     }
391a2eaa40Slogin }
40f678331aShanjiezhou 
41f678331aShanjiezhou pub struct X86_64InterruptArch;
42f678331aShanjiezhou 
43f678331aShanjiezhou impl InterruptArch for X86_64InterruptArch {
44*f2022a8aSLoGin     #[inline(never)]
45*f2022a8aSLoGin     unsafe fn arch_irq_init() -> Result<(), SystemError> {
46*f2022a8aSLoGin         CurrentIrqArch::interrupt_disable();
47*f2022a8aSLoGin         setup_interrupt_gate();
48*f2022a8aSLoGin         CurrentApic.init_current_cpu();
49*f2022a8aSLoGin         return Ok(());
50*f2022a8aSLoGin     }
51f678331aShanjiezhou     unsafe fn interrupt_enable() {
52f678331aShanjiezhou         sti();
53f678331aShanjiezhou     }
54f678331aShanjiezhou 
55f678331aShanjiezhou     unsafe fn interrupt_disable() {
56f678331aShanjiezhou         cli();
57f678331aShanjiezhou     }
58f678331aShanjiezhou 
59f678331aShanjiezhou     fn is_irq_enabled() -> bool {
60f678331aShanjiezhou         let rflags: u64;
61f678331aShanjiezhou         unsafe {
6240fe15e0SLoGin             asm!("pushfq; pop {}", out(reg) rflags, options(nomem, preserves_flags));
63f678331aShanjiezhou         }
64de71ec25SLoGin         return (rflags & (1 << 9)) != 0;
65f678331aShanjiezhou     }
66f678331aShanjiezhou 
67f678331aShanjiezhou     unsafe fn save_and_disable_irq() -> IrqFlagsGuard {
68f678331aShanjiezhou         compiler_fence(Ordering::SeqCst);
6940fe15e0SLoGin         let rflags = local_irq_save();
70f678331aShanjiezhou         let flags = IrqFlags::new(rflags);
71f678331aShanjiezhou         let guard = IrqFlagsGuard::new(flags);
72f678331aShanjiezhou         compiler_fence(Ordering::SeqCst);
73f678331aShanjiezhou         return guard;
74f678331aShanjiezhou     }
75f678331aShanjiezhou 
76f678331aShanjiezhou     unsafe fn restore_irq(flags: IrqFlags) {
77f678331aShanjiezhou         compiler_fence(Ordering::SeqCst);
7840fe15e0SLoGin         local_irq_restore(flags.flags());
79f678331aShanjiezhou         compiler_fence(Ordering::SeqCst);
80f678331aShanjiezhou     }
81f678331aShanjiezhou }
821496ba7bSLoGin 
831496ba7bSLoGin /// 中断栈帧结构体
841496ba7bSLoGin #[repr(C)]
851496ba7bSLoGin #[derive(Debug, Copy, Clone)]
861496ba7bSLoGin pub struct TrapFrame {
871496ba7bSLoGin     pub r15: ::core::ffi::c_ulong,
881496ba7bSLoGin     pub r14: ::core::ffi::c_ulong,
891496ba7bSLoGin     pub r13: ::core::ffi::c_ulong,
901496ba7bSLoGin     pub r12: ::core::ffi::c_ulong,
911496ba7bSLoGin     pub r11: ::core::ffi::c_ulong,
921496ba7bSLoGin     pub r10: ::core::ffi::c_ulong,
931496ba7bSLoGin     pub r9: ::core::ffi::c_ulong,
941496ba7bSLoGin     pub r8: ::core::ffi::c_ulong,
951496ba7bSLoGin     pub rbx: ::core::ffi::c_ulong,
961496ba7bSLoGin     pub rcx: ::core::ffi::c_ulong,
971496ba7bSLoGin     pub rdx: ::core::ffi::c_ulong,
981496ba7bSLoGin     pub rsi: ::core::ffi::c_ulong,
991496ba7bSLoGin     pub rdi: ::core::ffi::c_ulong,
1001496ba7bSLoGin     pub rbp: ::core::ffi::c_ulong,
1011496ba7bSLoGin     pub ds: ::core::ffi::c_ulong,
1021496ba7bSLoGin     pub es: ::core::ffi::c_ulong,
1031496ba7bSLoGin     pub rax: ::core::ffi::c_ulong,
1041496ba7bSLoGin     pub func: ::core::ffi::c_ulong,
1051496ba7bSLoGin     pub errcode: ::core::ffi::c_ulong,
1061496ba7bSLoGin     pub rip: ::core::ffi::c_ulong,
1071496ba7bSLoGin     pub cs: ::core::ffi::c_ulong,
1081496ba7bSLoGin     pub rflags: ::core::ffi::c_ulong,
1091496ba7bSLoGin     pub rsp: ::core::ffi::c_ulong,
1101496ba7bSLoGin     pub ss: ::core::ffi::c_ulong,
1111496ba7bSLoGin }
1121496ba7bSLoGin 
1131496ba7bSLoGin impl TrapFrame {
1141496ba7bSLoGin     pub fn new() -> Self {
1151496ba7bSLoGin         Self {
1161496ba7bSLoGin             r15: 0,
1171496ba7bSLoGin             r14: 0,
1181496ba7bSLoGin             r13: 0,
1191496ba7bSLoGin             r12: 0,
1201496ba7bSLoGin             r11: 0,
1211496ba7bSLoGin             r10: 0,
1221496ba7bSLoGin             r9: 0,
1231496ba7bSLoGin             r8: 0,
1241496ba7bSLoGin             rbx: 0,
1251496ba7bSLoGin             rcx: 0,
1261496ba7bSLoGin             rdx: 0,
1271496ba7bSLoGin             rsi: 0,
1281496ba7bSLoGin             rdi: 0,
1291496ba7bSLoGin             rbp: 0,
1301496ba7bSLoGin             ds: 0,
1311496ba7bSLoGin             es: 0,
1321496ba7bSLoGin             rax: 0,
1331496ba7bSLoGin             func: 0,
1341496ba7bSLoGin             errcode: 0,
1351496ba7bSLoGin             rip: 0,
1361496ba7bSLoGin             cs: 0,
1371496ba7bSLoGin             rflags: 0,
1381496ba7bSLoGin             rsp: 0,
1391496ba7bSLoGin             ss: 0,
1401496ba7bSLoGin         }
1411496ba7bSLoGin     }
1421496ba7bSLoGin 
1431496ba7bSLoGin     /// 设置中断栈帧返回值
1441496ba7bSLoGin     pub fn set_return_value(&mut self, value: usize) {
1451496ba7bSLoGin         self.rax = value as u64;
1461496ba7bSLoGin     }
1471496ba7bSLoGin 
1481496ba7bSLoGin     /// 判断当前中断是否来自用户模式
1491496ba7bSLoGin     pub fn from_user(&self) -> bool {
1501496ba7bSLoGin         if (self.cs & 0x3) != 0 {
1511496ba7bSLoGin             return true;
1521496ba7bSLoGin         } else {
1531496ba7bSLoGin             return false;
1541496ba7bSLoGin         }
1551496ba7bSLoGin     }
1561496ba7bSLoGin }
157