1 pub(super) mod entry; 2 mod handle; 3 pub mod ipi; 4 pub mod msi; 5 pub mod trap; 6 7 use core::{ 8 arch::asm, 9 sync::atomic::{compiler_fence, Ordering}, 10 }; 11 12 use system_error::SystemError; 13 14 use crate::{ 15 arch::CurrentIrqArch, 16 exception::{InterruptArch, IrqFlags, IrqFlagsGuard, IrqNumber}, 17 kerror, 18 }; 19 20 use super::{ 21 asm::irqflags::{local_irq_restore, local_irq_save}, 22 driver::apic::{lapic_vector::arch_early_irq_init, 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 48 return Ok(()); 49 } 50 unsafe fn interrupt_enable() { 51 sti(); 52 } 53 54 unsafe fn interrupt_disable() { 55 cli(); 56 } 57 58 fn is_irq_enabled() -> bool { 59 let rflags: u64; 60 unsafe { 61 asm!("pushfq; pop {}", out(reg) rflags, options(nomem, preserves_flags)); 62 } 63 return (rflags & (1 << 9)) != 0; 64 } 65 66 unsafe fn save_and_disable_irq() -> IrqFlagsGuard { 67 compiler_fence(Ordering::SeqCst); 68 let rflags = local_irq_save(); 69 let flags = IrqFlags::new(rflags); 70 let guard = IrqFlagsGuard::new(flags); 71 compiler_fence(Ordering::SeqCst); 72 return guard; 73 } 74 75 unsafe fn restore_irq(flags: IrqFlags) { 76 compiler_fence(Ordering::SeqCst); 77 local_irq_restore(flags.flags()); 78 compiler_fence(Ordering::SeqCst); 79 } 80 81 fn probe_total_irq_num() -> u32 { 82 // todo: 从APIC获取 83 // 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/arch/x86/kernel/apic/vector.c?r=&mo=19514&fi=704#704 84 256 85 } 86 87 fn ack_bad_irq(irq: IrqNumber) { 88 kerror!("Unexpected IRQ trap at vector {}", irq.data()); 89 CurrentApic.send_eoi(); 90 } 91 92 fn arch_early_irq_init() -> Result<(), SystemError> { 93 arch_early_irq_init() 94 } 95 96 fn arch_ap_early_irq_init() -> Result<(), SystemError> { 97 if !CurrentApic.init_current_cpu() { 98 return Err(SystemError::ENODEV); 99 } 100 101 Ok(()) 102 } 103 } 104 105 /// 中断栈帧结构体 106 #[repr(C)] 107 #[derive(Debug, Copy, Clone)] 108 pub struct TrapFrame { 109 pub r15: ::core::ffi::c_ulong, 110 pub r14: ::core::ffi::c_ulong, 111 pub r13: ::core::ffi::c_ulong, 112 pub r12: ::core::ffi::c_ulong, 113 pub r11: ::core::ffi::c_ulong, 114 pub r10: ::core::ffi::c_ulong, 115 pub r9: ::core::ffi::c_ulong, 116 pub r8: ::core::ffi::c_ulong, 117 pub rbx: ::core::ffi::c_ulong, 118 pub rcx: ::core::ffi::c_ulong, 119 pub rdx: ::core::ffi::c_ulong, 120 pub rsi: ::core::ffi::c_ulong, 121 pub rdi: ::core::ffi::c_ulong, 122 pub rbp: ::core::ffi::c_ulong, 123 pub ds: ::core::ffi::c_ulong, 124 pub es: ::core::ffi::c_ulong, 125 pub rax: ::core::ffi::c_ulong, 126 pub func: ::core::ffi::c_ulong, 127 pub errcode: ::core::ffi::c_ulong, 128 pub rip: ::core::ffi::c_ulong, 129 pub cs: ::core::ffi::c_ulong, 130 pub rflags: ::core::ffi::c_ulong, 131 pub rsp: ::core::ffi::c_ulong, 132 pub ss: ::core::ffi::c_ulong, 133 } 134 135 impl TrapFrame { 136 pub fn new() -> Self { 137 Self { 138 r15: 0, 139 r14: 0, 140 r13: 0, 141 r12: 0, 142 r11: 0, 143 r10: 0, 144 r9: 0, 145 r8: 0, 146 rbx: 0, 147 rcx: 0, 148 rdx: 0, 149 rsi: 0, 150 rdi: 0, 151 rbp: 0, 152 ds: 0, 153 es: 0, 154 rax: 0, 155 func: 0, 156 errcode: 0, 157 rip: 0, 158 cs: 0, 159 rflags: 0, 160 rsp: 0, 161 ss: 0, 162 } 163 } 164 165 /// 设置中断栈帧返回值 166 pub fn set_return_value(&mut self, value: usize) { 167 self.rax = value as u64; 168 } 169 170 /// 判断当前中断是否来自用户模式 171 pub fn is_from_user(&self) -> bool { 172 return (self.cs & 0x3) != 0; 173 } 174 } 175