xref: /DragonOS/kernel/src/arch/x86_64/interrupt/mod.rs (revision de71ec259cd21c782f4031b01635eb8ad3df1943)
11a2eaa40Slogin #![allow(dead_code)]
2aa0367d6SLoGin 
3aa0367d6SLoGin pub mod ipi;
4aa0367d6SLoGin 
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 {
4440fe15e0SLoGin             asm!("pushfq; pop {}", out(reg) rflags, options(nomem, preserves_flags));
45f678331aShanjiezhou         }
46*de71ec25SLoGin         return (rflags & (1 << 9)) != 0;
47f678331aShanjiezhou     }
48f678331aShanjiezhou 
49f678331aShanjiezhou     unsafe fn save_and_disable_irq() -> IrqFlagsGuard {
50f678331aShanjiezhou         compiler_fence(Ordering::SeqCst);
5140fe15e0SLoGin         let rflags = local_irq_save();
52f678331aShanjiezhou         let flags = IrqFlags::new(rflags);
53f678331aShanjiezhou         let guard = IrqFlagsGuard::new(flags);
54f678331aShanjiezhou         compiler_fence(Ordering::SeqCst);
55f678331aShanjiezhou         return guard;
56f678331aShanjiezhou     }
57f678331aShanjiezhou 
58f678331aShanjiezhou     unsafe fn restore_irq(flags: IrqFlags) {
59f678331aShanjiezhou         compiler_fence(Ordering::SeqCst);
6040fe15e0SLoGin         local_irq_restore(flags.flags());
61f678331aShanjiezhou         compiler_fence(Ordering::SeqCst);
62f678331aShanjiezhou     }
63f678331aShanjiezhou }
641496ba7bSLoGin 
651496ba7bSLoGin /// 中断栈帧结构体
661496ba7bSLoGin #[repr(C)]
671496ba7bSLoGin #[derive(Debug, Copy, Clone)]
681496ba7bSLoGin pub struct TrapFrame {
691496ba7bSLoGin     pub r15: ::core::ffi::c_ulong,
701496ba7bSLoGin     pub r14: ::core::ffi::c_ulong,
711496ba7bSLoGin     pub r13: ::core::ffi::c_ulong,
721496ba7bSLoGin     pub r12: ::core::ffi::c_ulong,
731496ba7bSLoGin     pub r11: ::core::ffi::c_ulong,
741496ba7bSLoGin     pub r10: ::core::ffi::c_ulong,
751496ba7bSLoGin     pub r9: ::core::ffi::c_ulong,
761496ba7bSLoGin     pub r8: ::core::ffi::c_ulong,
771496ba7bSLoGin     pub rbx: ::core::ffi::c_ulong,
781496ba7bSLoGin     pub rcx: ::core::ffi::c_ulong,
791496ba7bSLoGin     pub rdx: ::core::ffi::c_ulong,
801496ba7bSLoGin     pub rsi: ::core::ffi::c_ulong,
811496ba7bSLoGin     pub rdi: ::core::ffi::c_ulong,
821496ba7bSLoGin     pub rbp: ::core::ffi::c_ulong,
831496ba7bSLoGin     pub ds: ::core::ffi::c_ulong,
841496ba7bSLoGin     pub es: ::core::ffi::c_ulong,
851496ba7bSLoGin     pub rax: ::core::ffi::c_ulong,
861496ba7bSLoGin     pub func: ::core::ffi::c_ulong,
871496ba7bSLoGin     pub errcode: ::core::ffi::c_ulong,
881496ba7bSLoGin     pub rip: ::core::ffi::c_ulong,
891496ba7bSLoGin     pub cs: ::core::ffi::c_ulong,
901496ba7bSLoGin     pub rflags: ::core::ffi::c_ulong,
911496ba7bSLoGin     pub rsp: ::core::ffi::c_ulong,
921496ba7bSLoGin     pub ss: ::core::ffi::c_ulong,
931496ba7bSLoGin }
941496ba7bSLoGin 
951496ba7bSLoGin impl TrapFrame {
961496ba7bSLoGin     pub fn new() -> Self {
971496ba7bSLoGin         Self {
981496ba7bSLoGin             r15: 0,
991496ba7bSLoGin             r14: 0,
1001496ba7bSLoGin             r13: 0,
1011496ba7bSLoGin             r12: 0,
1021496ba7bSLoGin             r11: 0,
1031496ba7bSLoGin             r10: 0,
1041496ba7bSLoGin             r9: 0,
1051496ba7bSLoGin             r8: 0,
1061496ba7bSLoGin             rbx: 0,
1071496ba7bSLoGin             rcx: 0,
1081496ba7bSLoGin             rdx: 0,
1091496ba7bSLoGin             rsi: 0,
1101496ba7bSLoGin             rdi: 0,
1111496ba7bSLoGin             rbp: 0,
1121496ba7bSLoGin             ds: 0,
1131496ba7bSLoGin             es: 0,
1141496ba7bSLoGin             rax: 0,
1151496ba7bSLoGin             func: 0,
1161496ba7bSLoGin             errcode: 0,
1171496ba7bSLoGin             rip: 0,
1181496ba7bSLoGin             cs: 0,
1191496ba7bSLoGin             rflags: 0,
1201496ba7bSLoGin             rsp: 0,
1211496ba7bSLoGin             ss: 0,
1221496ba7bSLoGin         }
1231496ba7bSLoGin     }
1241496ba7bSLoGin 
1251496ba7bSLoGin     /// 设置中断栈帧返回值
1261496ba7bSLoGin     pub fn set_return_value(&mut self, value: usize) {
1271496ba7bSLoGin         self.rax = value as u64;
1281496ba7bSLoGin     }
1291496ba7bSLoGin 
1301496ba7bSLoGin     /// 判断当前中断是否来自用户模式
1311496ba7bSLoGin     pub fn from_user(&self) -> bool {
1321496ba7bSLoGin         if (self.cs & 0x3) != 0 {
1331496ba7bSLoGin             return true;
1341496ba7bSLoGin         } else {
1351496ba7bSLoGin             return false;
1361496ba7bSLoGin         }
1371496ba7bSLoGin     }
1381496ba7bSLoGin }
139