1 mod c_adapter; 2 pub(super) mod entry; 3 pub mod ipi; 4 pub mod trap; 5 6 use core::{ 7 arch::asm, 8 sync::atomic::{compiler_fence, Ordering}, 9 }; 10 11 use system_error::SystemError; 12 13 use crate::{ 14 arch::CurrentIrqArch, 15 exception::{InterruptArch, IrqFlags, IrqFlagsGuard}, 16 }; 17 18 use self::entry::setup_interrupt_gate; 19 20 use super::{ 21 asm::irqflags::{local_irq_restore, local_irq_save}, 22 driver::apic::{CurrentApic, LocalAPIC}, 23 }; 24 25 /// @brief 关闭中断 26 #[inline] 27 pub fn cli() { 28 unsafe { 29 asm!("cli"); 30 } 31 } 32 33 /// @brief 开启中断 34 #[inline] 35 pub fn sti() { 36 unsafe { 37 asm!("sti"); 38 } 39 } 40 41 pub struct X86_64InterruptArch; 42 43 impl InterruptArch for X86_64InterruptArch { 44 #[inline(never)] 45 unsafe fn arch_irq_init() -> Result<(), SystemError> { 46 CurrentIrqArch::interrupt_disable(); 47 setup_interrupt_gate(); 48 CurrentApic.init_current_cpu(); 49 return Ok(()); 50 } 51 unsafe fn interrupt_enable() { 52 sti(); 53 } 54 55 unsafe fn interrupt_disable() { 56 cli(); 57 } 58 59 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 67 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 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 } 82 83 /// 中断栈帧结构体 84 #[repr(C)] 85 #[derive(Debug, Copy, Clone)] 86 pub struct TrapFrame { 87 pub r15: ::core::ffi::c_ulong, 88 pub r14: ::core::ffi::c_ulong, 89 pub r13: ::core::ffi::c_ulong, 90 pub r12: ::core::ffi::c_ulong, 91 pub r11: ::core::ffi::c_ulong, 92 pub r10: ::core::ffi::c_ulong, 93 pub r9: ::core::ffi::c_ulong, 94 pub r8: ::core::ffi::c_ulong, 95 pub rbx: ::core::ffi::c_ulong, 96 pub rcx: ::core::ffi::c_ulong, 97 pub rdx: ::core::ffi::c_ulong, 98 pub rsi: ::core::ffi::c_ulong, 99 pub rdi: ::core::ffi::c_ulong, 100 pub rbp: ::core::ffi::c_ulong, 101 pub ds: ::core::ffi::c_ulong, 102 pub es: ::core::ffi::c_ulong, 103 pub rax: ::core::ffi::c_ulong, 104 pub func: ::core::ffi::c_ulong, 105 pub errcode: ::core::ffi::c_ulong, 106 pub rip: ::core::ffi::c_ulong, 107 pub cs: ::core::ffi::c_ulong, 108 pub rflags: ::core::ffi::c_ulong, 109 pub rsp: ::core::ffi::c_ulong, 110 pub ss: ::core::ffi::c_ulong, 111 } 112 113 impl TrapFrame { 114 pub fn new() -> Self { 115 Self { 116 r15: 0, 117 r14: 0, 118 r13: 0, 119 r12: 0, 120 r11: 0, 121 r10: 0, 122 r9: 0, 123 r8: 0, 124 rbx: 0, 125 rcx: 0, 126 rdx: 0, 127 rsi: 0, 128 rdi: 0, 129 rbp: 0, 130 ds: 0, 131 es: 0, 132 rax: 0, 133 func: 0, 134 errcode: 0, 135 rip: 0, 136 cs: 0, 137 rflags: 0, 138 rsp: 0, 139 ss: 0, 140 } 141 } 142 143 /// 设置中断栈帧返回值 144 pub fn set_return_value(&mut self, value: usize) { 145 self.rax = value as u64; 146 } 147 148 /// 判断当前中断是否来自用户模式 149 pub fn from_user(&self) -> bool { 150 if (self.cs & 0x3) != 0 { 151 return true; 152 } else { 153 return false; 154 } 155 } 156 } 157