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