170a4e555SLoGin mod c_adapter; 2f2022a8aSLoGin pub(super) mod entry; 3aa0367d6SLoGin pub mod ipi; 4f2022a8aSLoGin pub mod trap; 5aa0367d6SLoGin 6f678331aShanjiezhou use core::{ 7f678331aShanjiezhou arch::asm, 8f678331aShanjiezhou sync::atomic::{compiler_fence, Ordering}, 9f678331aShanjiezhou }; 10f678331aShanjiezhou 11f2022a8aSLoGin use system_error::SystemError; 12f678331aShanjiezhou 13f2022a8aSLoGin use crate::{ 14f2022a8aSLoGin arch::CurrentIrqArch, 15*3bc96fa4SLoGin exception::{InterruptArch, IrqFlags, IrqFlagsGuard, IrqNumber}, 16*3bc96fa4SLoGin kerror, 17f2022a8aSLoGin }; 18f2022a8aSLoGin 19f2022a8aSLoGin use self::entry::setup_interrupt_gate; 20f2022a8aSLoGin 21f2022a8aSLoGin use super::{ 22f2022a8aSLoGin asm::irqflags::{local_irq_restore, local_irq_save}, 23f2022a8aSLoGin driver::apic::{CurrentApic, LocalAPIC}, 24f2022a8aSLoGin }; 251a2eaa40Slogin 261a2eaa40Slogin /// @brief 关闭中断 271a2eaa40Slogin #[inline] 281a2eaa40Slogin pub fn cli() { 291a2eaa40Slogin unsafe { 301a2eaa40Slogin asm!("cli"); 311a2eaa40Slogin } 321a2eaa40Slogin } 331a2eaa40Slogin 341a2eaa40Slogin /// @brief 开启中断 351a2eaa40Slogin #[inline] 361a2eaa40Slogin pub fn sti() { 371a2eaa40Slogin unsafe { 381a2eaa40Slogin asm!("sti"); 391a2eaa40Slogin } 401a2eaa40Slogin } 41f678331aShanjiezhou 42f678331aShanjiezhou pub struct X86_64InterruptArch; 43f678331aShanjiezhou 44f678331aShanjiezhou impl InterruptArch for X86_64InterruptArch { 45f2022a8aSLoGin #[inline(never)] 46f2022a8aSLoGin unsafe fn arch_irq_init() -> Result<(), SystemError> { 47f2022a8aSLoGin CurrentIrqArch::interrupt_disable(); 48f2022a8aSLoGin setup_interrupt_gate(); 49f2022a8aSLoGin CurrentApic.init_current_cpu(); 50f2022a8aSLoGin return Ok(()); 51f2022a8aSLoGin } 52f678331aShanjiezhou unsafe fn interrupt_enable() { 53f678331aShanjiezhou sti(); 54f678331aShanjiezhou } 55f678331aShanjiezhou 56f678331aShanjiezhou unsafe fn interrupt_disable() { 57f678331aShanjiezhou cli(); 58f678331aShanjiezhou } 59f678331aShanjiezhou 60f678331aShanjiezhou fn is_irq_enabled() -> bool { 61f678331aShanjiezhou let rflags: u64; 62f678331aShanjiezhou unsafe { 6340fe15e0SLoGin asm!("pushfq; pop {}", out(reg) rflags, options(nomem, preserves_flags)); 64f678331aShanjiezhou } 65de71ec25SLoGin return (rflags & (1 << 9)) != 0; 66f678331aShanjiezhou } 67f678331aShanjiezhou 68f678331aShanjiezhou unsafe fn save_and_disable_irq() -> IrqFlagsGuard { 69f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 7040fe15e0SLoGin let rflags = local_irq_save(); 71f678331aShanjiezhou let flags = IrqFlags::new(rflags); 72f678331aShanjiezhou let guard = IrqFlagsGuard::new(flags); 73f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 74f678331aShanjiezhou return guard; 75f678331aShanjiezhou } 76f678331aShanjiezhou 77f678331aShanjiezhou unsafe fn restore_irq(flags: IrqFlags) { 78f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 7940fe15e0SLoGin local_irq_restore(flags.flags()); 80f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 81f678331aShanjiezhou } 82*3bc96fa4SLoGin 83*3bc96fa4SLoGin fn probe_total_irq_num() -> u32 { 84*3bc96fa4SLoGin // todo: 从APIC获取 85*3bc96fa4SLoGin // 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/arch/x86/kernel/apic/vector.c?r=&mo=19514&fi=704#704 86*3bc96fa4SLoGin 256 87*3bc96fa4SLoGin } 88*3bc96fa4SLoGin 89*3bc96fa4SLoGin fn ack_bad_irq(irq: IrqNumber) { 90*3bc96fa4SLoGin kerror!("Unexpected IRQ trap at vector {}", irq.data()); 91*3bc96fa4SLoGin CurrentApic.send_eoi(); 92*3bc96fa4SLoGin } 93f678331aShanjiezhou } 941496ba7bSLoGin 951496ba7bSLoGin /// 中断栈帧结构体 961496ba7bSLoGin #[repr(C)] 971496ba7bSLoGin #[derive(Debug, Copy, Clone)] 981496ba7bSLoGin pub struct TrapFrame { 991496ba7bSLoGin pub r15: ::core::ffi::c_ulong, 1001496ba7bSLoGin pub r14: ::core::ffi::c_ulong, 1011496ba7bSLoGin pub r13: ::core::ffi::c_ulong, 1021496ba7bSLoGin pub r12: ::core::ffi::c_ulong, 1031496ba7bSLoGin pub r11: ::core::ffi::c_ulong, 1041496ba7bSLoGin pub r10: ::core::ffi::c_ulong, 1051496ba7bSLoGin pub r9: ::core::ffi::c_ulong, 1061496ba7bSLoGin pub r8: ::core::ffi::c_ulong, 1071496ba7bSLoGin pub rbx: ::core::ffi::c_ulong, 1081496ba7bSLoGin pub rcx: ::core::ffi::c_ulong, 1091496ba7bSLoGin pub rdx: ::core::ffi::c_ulong, 1101496ba7bSLoGin pub rsi: ::core::ffi::c_ulong, 1111496ba7bSLoGin pub rdi: ::core::ffi::c_ulong, 1121496ba7bSLoGin pub rbp: ::core::ffi::c_ulong, 1131496ba7bSLoGin pub ds: ::core::ffi::c_ulong, 1141496ba7bSLoGin pub es: ::core::ffi::c_ulong, 1151496ba7bSLoGin pub rax: ::core::ffi::c_ulong, 1161496ba7bSLoGin pub func: ::core::ffi::c_ulong, 1171496ba7bSLoGin pub errcode: ::core::ffi::c_ulong, 1181496ba7bSLoGin pub rip: ::core::ffi::c_ulong, 1191496ba7bSLoGin pub cs: ::core::ffi::c_ulong, 1201496ba7bSLoGin pub rflags: ::core::ffi::c_ulong, 1211496ba7bSLoGin pub rsp: ::core::ffi::c_ulong, 1221496ba7bSLoGin pub ss: ::core::ffi::c_ulong, 1231496ba7bSLoGin } 1241496ba7bSLoGin 1251496ba7bSLoGin impl TrapFrame { 1261496ba7bSLoGin pub fn new() -> Self { 1271496ba7bSLoGin Self { 1281496ba7bSLoGin r15: 0, 1291496ba7bSLoGin r14: 0, 1301496ba7bSLoGin r13: 0, 1311496ba7bSLoGin r12: 0, 1321496ba7bSLoGin r11: 0, 1331496ba7bSLoGin r10: 0, 1341496ba7bSLoGin r9: 0, 1351496ba7bSLoGin r8: 0, 1361496ba7bSLoGin rbx: 0, 1371496ba7bSLoGin rcx: 0, 1381496ba7bSLoGin rdx: 0, 1391496ba7bSLoGin rsi: 0, 1401496ba7bSLoGin rdi: 0, 1411496ba7bSLoGin rbp: 0, 1421496ba7bSLoGin ds: 0, 1431496ba7bSLoGin es: 0, 1441496ba7bSLoGin rax: 0, 1451496ba7bSLoGin func: 0, 1461496ba7bSLoGin errcode: 0, 1471496ba7bSLoGin rip: 0, 1481496ba7bSLoGin cs: 0, 1491496ba7bSLoGin rflags: 0, 1501496ba7bSLoGin rsp: 0, 1511496ba7bSLoGin ss: 0, 1521496ba7bSLoGin } 1531496ba7bSLoGin } 1541496ba7bSLoGin 1551496ba7bSLoGin /// 设置中断栈帧返回值 1561496ba7bSLoGin pub fn set_return_value(&mut self, value: usize) { 1571496ba7bSLoGin self.rax = value as u64; 1581496ba7bSLoGin } 1591496ba7bSLoGin 1601496ba7bSLoGin /// 判断当前中断是否来自用户模式 1611496ba7bSLoGin pub fn from_user(&self) -> bool { 1621496ba7bSLoGin if (self.cs & 0x3) != 0 { 1631496ba7bSLoGin return true; 1641496ba7bSLoGin } else { 1651496ba7bSLoGin return false; 1661496ba7bSLoGin } 1671496ba7bSLoGin } 1681496ba7bSLoGin } 169