1 mod c_adapter; 2 pub(super) mod entry; 3 mod handle; 4 pub mod ipi; 5 pub mod msi; 6 pub mod trap; 7 8 use core::{ 9 arch::asm, 10 sync::atomic::{compiler_fence, Ordering}, 11 }; 12 13 use system_error::SystemError; 14 15 use crate::{ 16 arch::CurrentIrqArch, 17 exception::{InterruptArch, IrqFlags, IrqFlagsGuard, IrqNumber}, 18 kerror, 19 }; 20 21 use super::{ 22 asm::irqflags::{local_irq_restore, local_irq_save}, 23 driver::apic::{lapic_vector::arch_early_irq_init, CurrentApic, LocalAPIC}, 24 }; 25 26 /// @brief 关闭中断 27 #[inline] 28 pub fn cli() { 29 unsafe { 30 asm!("cli"); 31 } 32 } 33 34 /// @brief 开启中断 35 #[inline] 36 pub fn sti() { 37 unsafe { 38 asm!("sti"); 39 } 40 } 41 42 pub struct X86_64InterruptArch; 43 44 impl InterruptArch for X86_64InterruptArch { 45 #[inline(never)] 46 unsafe fn arch_irq_init() -> Result<(), SystemError> { 47 CurrentIrqArch::interrupt_disable(); 48 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 fn probe_total_irq_num() -> u32 { 83 // todo: 从APIC获取 84 // 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/arch/x86/kernel/apic/vector.c?r=&mo=19514&fi=704#704 85 256 86 } 87 88 fn ack_bad_irq(irq: IrqNumber) { 89 kerror!("Unexpected IRQ trap at vector {}", irq.data()); 90 CurrentApic.send_eoi(); 91 } 92 93 fn arch_early_irq_init() -> Result<(), SystemError> { 94 arch_early_irq_init() 95 } 96 } 97 98 /// 中断栈帧结构体 99 #[repr(C)] 100 #[derive(Debug, Copy, Clone)] 101 pub struct TrapFrame { 102 pub r15: ::core::ffi::c_ulong, 103 pub r14: ::core::ffi::c_ulong, 104 pub r13: ::core::ffi::c_ulong, 105 pub r12: ::core::ffi::c_ulong, 106 pub r11: ::core::ffi::c_ulong, 107 pub r10: ::core::ffi::c_ulong, 108 pub r9: ::core::ffi::c_ulong, 109 pub r8: ::core::ffi::c_ulong, 110 pub rbx: ::core::ffi::c_ulong, 111 pub rcx: ::core::ffi::c_ulong, 112 pub rdx: ::core::ffi::c_ulong, 113 pub rsi: ::core::ffi::c_ulong, 114 pub rdi: ::core::ffi::c_ulong, 115 pub rbp: ::core::ffi::c_ulong, 116 pub ds: ::core::ffi::c_ulong, 117 pub es: ::core::ffi::c_ulong, 118 pub rax: ::core::ffi::c_ulong, 119 pub func: ::core::ffi::c_ulong, 120 pub errcode: ::core::ffi::c_ulong, 121 pub rip: ::core::ffi::c_ulong, 122 pub cs: ::core::ffi::c_ulong, 123 pub rflags: ::core::ffi::c_ulong, 124 pub rsp: ::core::ffi::c_ulong, 125 pub ss: ::core::ffi::c_ulong, 126 } 127 128 impl TrapFrame { 129 pub fn new() -> Self { 130 Self { 131 r15: 0, 132 r14: 0, 133 r13: 0, 134 r12: 0, 135 r11: 0, 136 r10: 0, 137 r9: 0, 138 r8: 0, 139 rbx: 0, 140 rcx: 0, 141 rdx: 0, 142 rsi: 0, 143 rdi: 0, 144 rbp: 0, 145 ds: 0, 146 es: 0, 147 rax: 0, 148 func: 0, 149 errcode: 0, 150 rip: 0, 151 cs: 0, 152 rflags: 0, 153 rsp: 0, 154 ss: 0, 155 } 156 } 157 158 /// 设置中断栈帧返回值 159 pub fn set_return_value(&mut self, value: usize) { 160 self.rax = value as u64; 161 } 162 163 /// 判断当前中断是否来自用户模式 164 pub fn from_user(&self) -> bool { 165 if (self.cs & 0x3) != 0 { 166 return true; 167 } else { 168 return false; 169 } 170 } 171 } 172