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