11a2eaa40Slogin #![allow(dead_code)] 2aa0367d6SLoGin 3aa0367d6SLoGin pub mod ipi; 4aa0367d6SLoGin 5f678331aShanjiezhou use core::{ 6f678331aShanjiezhou arch::asm, 7f678331aShanjiezhou sync::atomic::{compiler_fence, Ordering}, 8f678331aShanjiezhou }; 9f678331aShanjiezhou 10f678331aShanjiezhou use crate::exception::{InterruptArch, IrqFlags, IrqFlagsGuard}; 11f678331aShanjiezhou 12f678331aShanjiezhou use super::asm::irqflags::{local_irq_restore, local_irq_save}; 131a2eaa40Slogin 141a2eaa40Slogin /// @brief 关闭中断 151a2eaa40Slogin #[inline] 161a2eaa40Slogin pub fn cli() { 171a2eaa40Slogin unsafe { 181a2eaa40Slogin asm!("cli"); 191a2eaa40Slogin } 201a2eaa40Slogin } 211a2eaa40Slogin 221a2eaa40Slogin /// @brief 开启中断 231a2eaa40Slogin #[inline] 241a2eaa40Slogin pub fn sti() { 251a2eaa40Slogin unsafe { 261a2eaa40Slogin asm!("sti"); 271a2eaa40Slogin } 281a2eaa40Slogin } 29f678331aShanjiezhou 30f678331aShanjiezhou pub struct X86_64InterruptArch; 31f678331aShanjiezhou 32f678331aShanjiezhou impl InterruptArch for X86_64InterruptArch { 33f678331aShanjiezhou unsafe fn interrupt_enable() { 34f678331aShanjiezhou sti(); 35f678331aShanjiezhou } 36f678331aShanjiezhou 37f678331aShanjiezhou unsafe fn interrupt_disable() { 38f678331aShanjiezhou cli(); 39f678331aShanjiezhou } 40f678331aShanjiezhou 41f678331aShanjiezhou fn is_irq_enabled() -> bool { 42f678331aShanjiezhou let rflags: u64; 43f678331aShanjiezhou unsafe { 4440fe15e0SLoGin asm!("pushfq; pop {}", out(reg) rflags, options(nomem, preserves_flags)); 45f678331aShanjiezhou } 46*de71ec25SLoGin return (rflags & (1 << 9)) != 0; 47f678331aShanjiezhou } 48f678331aShanjiezhou 49f678331aShanjiezhou unsafe fn save_and_disable_irq() -> IrqFlagsGuard { 50f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 5140fe15e0SLoGin let rflags = local_irq_save(); 52f678331aShanjiezhou let flags = IrqFlags::new(rflags); 53f678331aShanjiezhou let guard = IrqFlagsGuard::new(flags); 54f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 55f678331aShanjiezhou return guard; 56f678331aShanjiezhou } 57f678331aShanjiezhou 58f678331aShanjiezhou unsafe fn restore_irq(flags: IrqFlags) { 59f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 6040fe15e0SLoGin local_irq_restore(flags.flags()); 61f678331aShanjiezhou compiler_fence(Ordering::SeqCst); 62f678331aShanjiezhou } 63f678331aShanjiezhou } 641496ba7bSLoGin 651496ba7bSLoGin /// 中断栈帧结构体 661496ba7bSLoGin #[repr(C)] 671496ba7bSLoGin #[derive(Debug, Copy, Clone)] 681496ba7bSLoGin pub struct TrapFrame { 691496ba7bSLoGin pub r15: ::core::ffi::c_ulong, 701496ba7bSLoGin pub r14: ::core::ffi::c_ulong, 711496ba7bSLoGin pub r13: ::core::ffi::c_ulong, 721496ba7bSLoGin pub r12: ::core::ffi::c_ulong, 731496ba7bSLoGin pub r11: ::core::ffi::c_ulong, 741496ba7bSLoGin pub r10: ::core::ffi::c_ulong, 751496ba7bSLoGin pub r9: ::core::ffi::c_ulong, 761496ba7bSLoGin pub r8: ::core::ffi::c_ulong, 771496ba7bSLoGin pub rbx: ::core::ffi::c_ulong, 781496ba7bSLoGin pub rcx: ::core::ffi::c_ulong, 791496ba7bSLoGin pub rdx: ::core::ffi::c_ulong, 801496ba7bSLoGin pub rsi: ::core::ffi::c_ulong, 811496ba7bSLoGin pub rdi: ::core::ffi::c_ulong, 821496ba7bSLoGin pub rbp: ::core::ffi::c_ulong, 831496ba7bSLoGin pub ds: ::core::ffi::c_ulong, 841496ba7bSLoGin pub es: ::core::ffi::c_ulong, 851496ba7bSLoGin pub rax: ::core::ffi::c_ulong, 861496ba7bSLoGin pub func: ::core::ffi::c_ulong, 871496ba7bSLoGin pub errcode: ::core::ffi::c_ulong, 881496ba7bSLoGin pub rip: ::core::ffi::c_ulong, 891496ba7bSLoGin pub cs: ::core::ffi::c_ulong, 901496ba7bSLoGin pub rflags: ::core::ffi::c_ulong, 911496ba7bSLoGin pub rsp: ::core::ffi::c_ulong, 921496ba7bSLoGin pub ss: ::core::ffi::c_ulong, 931496ba7bSLoGin } 941496ba7bSLoGin 951496ba7bSLoGin impl TrapFrame { 961496ba7bSLoGin pub fn new() -> Self { 971496ba7bSLoGin Self { 981496ba7bSLoGin r15: 0, 991496ba7bSLoGin r14: 0, 1001496ba7bSLoGin r13: 0, 1011496ba7bSLoGin r12: 0, 1021496ba7bSLoGin r11: 0, 1031496ba7bSLoGin r10: 0, 1041496ba7bSLoGin r9: 0, 1051496ba7bSLoGin r8: 0, 1061496ba7bSLoGin rbx: 0, 1071496ba7bSLoGin rcx: 0, 1081496ba7bSLoGin rdx: 0, 1091496ba7bSLoGin rsi: 0, 1101496ba7bSLoGin rdi: 0, 1111496ba7bSLoGin rbp: 0, 1121496ba7bSLoGin ds: 0, 1131496ba7bSLoGin es: 0, 1141496ba7bSLoGin rax: 0, 1151496ba7bSLoGin func: 0, 1161496ba7bSLoGin errcode: 0, 1171496ba7bSLoGin rip: 0, 1181496ba7bSLoGin cs: 0, 1191496ba7bSLoGin rflags: 0, 1201496ba7bSLoGin rsp: 0, 1211496ba7bSLoGin ss: 0, 1221496ba7bSLoGin } 1231496ba7bSLoGin } 1241496ba7bSLoGin 1251496ba7bSLoGin /// 设置中断栈帧返回值 1261496ba7bSLoGin pub fn set_return_value(&mut self, value: usize) { 1271496ba7bSLoGin self.rax = value as u64; 1281496ba7bSLoGin } 1291496ba7bSLoGin 1301496ba7bSLoGin /// 判断当前中断是否来自用户模式 1311496ba7bSLoGin pub fn from_user(&self) -> bool { 1321496ba7bSLoGin if (self.cs & 0x3) != 0 { 1331496ba7bSLoGin return true; 1341496ba7bSLoGin } else { 1351496ba7bSLoGin return false; 1361496ba7bSLoGin } 1371496ba7bSLoGin } 1381496ba7bSLoGin } 139