1 #![allow(dead_code)] 2 3 mod c_adapter; 4 pub mod ipi; 5 6 use core::{ 7 arch::asm, 8 sync::atomic::{compiler_fence, Ordering}, 9 }; 10 11 use crate::exception::{InterruptArch, IrqFlags, IrqFlagsGuard}; 12 13 use super::asm::irqflags::{local_irq_restore, local_irq_save}; 14 15 /// @brief 关闭中断 16 #[inline] 17 pub fn cli() { 18 unsafe { 19 asm!("cli"); 20 } 21 } 22 23 /// @brief 开启中断 24 #[inline] 25 pub fn sti() { 26 unsafe { 27 asm!("sti"); 28 } 29 } 30 31 pub struct X86_64InterruptArch; 32 33 impl InterruptArch for X86_64InterruptArch { 34 unsafe fn interrupt_enable() { 35 sti(); 36 } 37 38 unsafe fn interrupt_disable() { 39 cli(); 40 } 41 42 fn is_irq_enabled() -> bool { 43 let rflags: u64; 44 unsafe { 45 asm!("pushfq; pop {}", out(reg) rflags, options(nomem, preserves_flags)); 46 } 47 return (rflags & (1 << 9)) != 0; 48 } 49 50 unsafe fn save_and_disable_irq() -> IrqFlagsGuard { 51 compiler_fence(Ordering::SeqCst); 52 let rflags = local_irq_save(); 53 let flags = IrqFlags::new(rflags); 54 let guard = IrqFlagsGuard::new(flags); 55 compiler_fence(Ordering::SeqCst); 56 return guard; 57 } 58 59 unsafe fn restore_irq(flags: IrqFlags) { 60 compiler_fence(Ordering::SeqCst); 61 local_irq_restore(flags.flags()); 62 compiler_fence(Ordering::SeqCst); 63 } 64 } 65 66 /// 中断栈帧结构体 67 #[repr(C)] 68 #[derive(Debug, Copy, Clone)] 69 pub struct TrapFrame { 70 pub r15: ::core::ffi::c_ulong, 71 pub r14: ::core::ffi::c_ulong, 72 pub r13: ::core::ffi::c_ulong, 73 pub r12: ::core::ffi::c_ulong, 74 pub r11: ::core::ffi::c_ulong, 75 pub r10: ::core::ffi::c_ulong, 76 pub r9: ::core::ffi::c_ulong, 77 pub r8: ::core::ffi::c_ulong, 78 pub rbx: ::core::ffi::c_ulong, 79 pub rcx: ::core::ffi::c_ulong, 80 pub rdx: ::core::ffi::c_ulong, 81 pub rsi: ::core::ffi::c_ulong, 82 pub rdi: ::core::ffi::c_ulong, 83 pub rbp: ::core::ffi::c_ulong, 84 pub ds: ::core::ffi::c_ulong, 85 pub es: ::core::ffi::c_ulong, 86 pub rax: ::core::ffi::c_ulong, 87 pub func: ::core::ffi::c_ulong, 88 pub errcode: ::core::ffi::c_ulong, 89 pub rip: ::core::ffi::c_ulong, 90 pub cs: ::core::ffi::c_ulong, 91 pub rflags: ::core::ffi::c_ulong, 92 pub rsp: ::core::ffi::c_ulong, 93 pub ss: ::core::ffi::c_ulong, 94 } 95 96 impl TrapFrame { 97 pub fn new() -> Self { 98 Self { 99 r15: 0, 100 r14: 0, 101 r13: 0, 102 r12: 0, 103 r11: 0, 104 r10: 0, 105 r9: 0, 106 r8: 0, 107 rbx: 0, 108 rcx: 0, 109 rdx: 0, 110 rsi: 0, 111 rdi: 0, 112 rbp: 0, 113 ds: 0, 114 es: 0, 115 rax: 0, 116 func: 0, 117 errcode: 0, 118 rip: 0, 119 cs: 0, 120 rflags: 0, 121 rsp: 0, 122 ss: 0, 123 } 124 } 125 126 /// 设置中断栈帧返回值 127 pub fn set_return_value(&mut self, value: usize) { 128 self.rax = value as u64; 129 } 130 131 /// 判断当前中断是否来自用户模式 132 pub fn from_user(&self) -> bool { 133 if (self.cs & 0x3) != 0 { 134 return true; 135 } else { 136 return false; 137 } 138 } 139 } 140