170a4e555SLoGin mod c_adapter; 2*f2022a8aSLoGin pub(super) mod entry; 3aa0367d6SLoGin pub mod ipi; 4*f2022a8aSLoGin pub mod trap; 5aa0367d6SLoGin 6f678331aShanjiezhou use core::{ 7f678331aShanjiezhou arch::asm, 8f678331aShanjiezhou sync::atomic::{compiler_fence, Ordering}, 9f678331aShanjiezhou }; 10f678331aShanjiezhou 11*f2022a8aSLoGin use system_error::SystemError; 12f678331aShanjiezhou 13*f2022a8aSLoGin use crate::{ 14*f2022a8aSLoGin arch::CurrentIrqArch, 15*f2022a8aSLoGin exception::{InterruptArch, IrqFlags, IrqFlagsGuard}, 16*f2022a8aSLoGin }; 17*f2022a8aSLoGin 18*f2022a8aSLoGin use self::entry::setup_interrupt_gate; 19*f2022a8aSLoGin 20*f2022a8aSLoGin use super::{ 21*f2022a8aSLoGin asm::irqflags::{local_irq_restore, local_irq_save}, 22*f2022a8aSLoGin driver::apic::{CurrentApic, LocalAPIC}, 23*f2022a8aSLoGin }; 241a2eaa40Slogin 251a2eaa40Slogin /// @brief 关闭中断 261a2eaa40Slogin #[inline] 271a2eaa40Slogin pub fn cli() { 281a2eaa40Slogin unsafe { 291a2eaa40Slogin asm!("cli"); 301a2eaa40Slogin } 311a2eaa40Slogin } 321a2eaa40Slogin 331a2eaa40Slogin /// @brief 开启中断 341a2eaa40Slogin #[inline] 351a2eaa40Slogin pub fn sti() { 361a2eaa40Slogin unsafe { 371a2eaa40Slogin asm!("sti"); 381a2eaa40Slogin } 391a2eaa40Slogin } 40f678331aShanjiezhou 41f678331aShanjiezhou pub struct X86_64InterruptArch; 42f678331aShanjiezhou 43f678331aShanjiezhou impl InterruptArch for X86_64InterruptArch { 44*f2022a8aSLoGin #[inline(never)] 45*f2022a8aSLoGin unsafe fn arch_irq_init() -> Result<(), SystemError> { 46*f2022a8aSLoGin CurrentIrqArch::interrupt_disable(); 47*f2022a8aSLoGin setup_interrupt_gate(); 48*f2022a8aSLoGin CurrentApic.init_current_cpu(); 49*f2022a8aSLoGin return Ok(()); 50*f2022a8aSLoGin } 51f678331aShanjiezhou unsafe fn interrupt_enable() { 52f678331aShanjiezhou sti(); 53f678331aShanjiezhou } 54f678331aShanjiezhou 55f678331aShanjiezhou unsafe fn interrupt_disable() { 56f678331aShanjiezhou cli(); 57f678331aShanjiezhou } 58f678331aShanjiezhou 59f678331aShanjiezhou fn is_irq_enabled() -> bool { 60f678331aShanjiezhou let rflags: u64; 61f678331aShanjiezhou unsafe { 6240fe15e0SLoGin asm!("pushfq; pop {}", out(reg) rflags, options(nomem, preserves_flags)); 63f678331aShanjiezhou } 64de71ec25SLoGin return (rflags & (1 << 9)) != 0; 65f678331aShanjiezhou } 66f678331aShanjiezhou 67f678331aShanjiezhou unsafe fn save_and_disable_irq() -> IrqFlagsGuard { 68f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 6940fe15e0SLoGin let rflags = local_irq_save(); 70f678331aShanjiezhou let flags = IrqFlags::new(rflags); 71f678331aShanjiezhou let guard = IrqFlagsGuard::new(flags); 72f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 73f678331aShanjiezhou return guard; 74f678331aShanjiezhou } 75f678331aShanjiezhou 76f678331aShanjiezhou unsafe fn restore_irq(flags: IrqFlags) { 77f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 7840fe15e0SLoGin local_irq_restore(flags.flags()); 79f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 80f678331aShanjiezhou } 81f678331aShanjiezhou } 821496ba7bSLoGin 831496ba7bSLoGin /// 中断栈帧结构体 841496ba7bSLoGin #[repr(C)] 851496ba7bSLoGin #[derive(Debug, Copy, Clone)] 861496ba7bSLoGin pub struct TrapFrame { 871496ba7bSLoGin pub r15: ::core::ffi::c_ulong, 881496ba7bSLoGin pub r14: ::core::ffi::c_ulong, 891496ba7bSLoGin pub r13: ::core::ffi::c_ulong, 901496ba7bSLoGin pub r12: ::core::ffi::c_ulong, 911496ba7bSLoGin pub r11: ::core::ffi::c_ulong, 921496ba7bSLoGin pub r10: ::core::ffi::c_ulong, 931496ba7bSLoGin pub r9: ::core::ffi::c_ulong, 941496ba7bSLoGin pub r8: ::core::ffi::c_ulong, 951496ba7bSLoGin pub rbx: ::core::ffi::c_ulong, 961496ba7bSLoGin pub rcx: ::core::ffi::c_ulong, 971496ba7bSLoGin pub rdx: ::core::ffi::c_ulong, 981496ba7bSLoGin pub rsi: ::core::ffi::c_ulong, 991496ba7bSLoGin pub rdi: ::core::ffi::c_ulong, 1001496ba7bSLoGin pub rbp: ::core::ffi::c_ulong, 1011496ba7bSLoGin pub ds: ::core::ffi::c_ulong, 1021496ba7bSLoGin pub es: ::core::ffi::c_ulong, 1031496ba7bSLoGin pub rax: ::core::ffi::c_ulong, 1041496ba7bSLoGin pub func: ::core::ffi::c_ulong, 1051496ba7bSLoGin pub errcode: ::core::ffi::c_ulong, 1061496ba7bSLoGin pub rip: ::core::ffi::c_ulong, 1071496ba7bSLoGin pub cs: ::core::ffi::c_ulong, 1081496ba7bSLoGin pub rflags: ::core::ffi::c_ulong, 1091496ba7bSLoGin pub rsp: ::core::ffi::c_ulong, 1101496ba7bSLoGin pub ss: ::core::ffi::c_ulong, 1111496ba7bSLoGin } 1121496ba7bSLoGin 1131496ba7bSLoGin impl TrapFrame { 1141496ba7bSLoGin pub fn new() -> Self { 1151496ba7bSLoGin Self { 1161496ba7bSLoGin r15: 0, 1171496ba7bSLoGin r14: 0, 1181496ba7bSLoGin r13: 0, 1191496ba7bSLoGin r12: 0, 1201496ba7bSLoGin r11: 0, 1211496ba7bSLoGin r10: 0, 1221496ba7bSLoGin r9: 0, 1231496ba7bSLoGin r8: 0, 1241496ba7bSLoGin rbx: 0, 1251496ba7bSLoGin rcx: 0, 1261496ba7bSLoGin rdx: 0, 1271496ba7bSLoGin rsi: 0, 1281496ba7bSLoGin rdi: 0, 1291496ba7bSLoGin rbp: 0, 1301496ba7bSLoGin ds: 0, 1311496ba7bSLoGin es: 0, 1321496ba7bSLoGin rax: 0, 1331496ba7bSLoGin func: 0, 1341496ba7bSLoGin errcode: 0, 1351496ba7bSLoGin rip: 0, 1361496ba7bSLoGin cs: 0, 1371496ba7bSLoGin rflags: 0, 1381496ba7bSLoGin rsp: 0, 1391496ba7bSLoGin ss: 0, 1401496ba7bSLoGin } 1411496ba7bSLoGin } 1421496ba7bSLoGin 1431496ba7bSLoGin /// 设置中断栈帧返回值 1441496ba7bSLoGin pub fn set_return_value(&mut self, value: usize) { 1451496ba7bSLoGin self.rax = value as u64; 1461496ba7bSLoGin } 1471496ba7bSLoGin 1481496ba7bSLoGin /// 判断当前中断是否来自用户模式 1491496ba7bSLoGin pub fn from_user(&self) -> bool { 1501496ba7bSLoGin if (self.cs & 0x3) != 0 { 1511496ba7bSLoGin return true; 1521496ba7bSLoGin } else { 1531496ba7bSLoGin return false; 1541496ba7bSLoGin } 1551496ba7bSLoGin } 1561496ba7bSLoGin } 157