mod.rs 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #![allow(dead_code)]
  2. pub mod ipi;
  3. use core::{
  4. arch::asm,
  5. sync::atomic::{compiler_fence, Ordering},
  6. };
  7. use crate::exception::{InterruptArch, IrqFlags, IrqFlagsGuard};
  8. use super::asm::irqflags::{local_irq_restore, local_irq_save};
  9. /// @brief 关闭中断
  10. #[inline]
  11. pub fn cli() {
  12. unsafe {
  13. asm!("cli");
  14. }
  15. }
  16. /// @brief 开启中断
  17. #[inline]
  18. pub fn sti() {
  19. unsafe {
  20. asm!("sti");
  21. }
  22. }
  23. pub struct X86_64InterruptArch;
  24. impl InterruptArch for X86_64InterruptArch {
  25. unsafe fn interrupt_enable() {
  26. sti();
  27. }
  28. unsafe fn interrupt_disable() {
  29. cli();
  30. }
  31. fn is_irq_enabled() -> bool {
  32. let rflags: u64;
  33. unsafe {
  34. asm!("pushfq; pop {}", out(reg) rflags, options(nomem, preserves_flags));
  35. }
  36. return rflags & (1 << 9) != 0;
  37. }
  38. unsafe fn save_and_disable_irq() -> IrqFlagsGuard {
  39. compiler_fence(Ordering::SeqCst);
  40. let rflags = local_irq_save();
  41. let flags = IrqFlags::new(rflags);
  42. let guard = IrqFlagsGuard::new(flags);
  43. compiler_fence(Ordering::SeqCst);
  44. return guard;
  45. }
  46. unsafe fn restore_irq(flags: IrqFlags) {
  47. compiler_fence(Ordering::SeqCst);
  48. local_irq_restore(flags.flags());
  49. compiler_fence(Ordering::SeqCst);
  50. }
  51. }