diff --git a/src/arch/arm.rs b/src/arch/arm.rs new file mode 100644 index 0000000..31b044c --- /dev/null +++ b/src/arch/arm.rs @@ -0,0 +1,29 @@ +use core::arch::asm; + +/// Bit 7: IRQ disable bit in CPSR +const IRQ_DISABLE_BIT: usize = 1 << 7; + +#[inline] +pub fn local_irq_save_and_disable() -> usize { + let flags: usize; + unsafe { + // Save CPSR and disable IRQs by setting the I bit + asm!( + "mrs {0}, cpsr", + "cpsid i", + out(reg) flags, + options(nomem, nostack, preserves_flags) + ); + } + flags & IRQ_DISABLE_BIT +} + +#[inline] +pub fn local_irq_restore(flags: usize) { + if flags & IRQ_DISABLE_BIT == 0 { + // IRQs were enabled before, re-enable them + unsafe { + asm!("cpsie i", options(nomem, nostack)); + } + } +} diff --git a/src/arch/mod.rs b/src/arch/mod.rs index 56b5d69..5a320b2 100644 --- a/src/arch/mod.rs +++ b/src/arch/mod.rs @@ -13,5 +13,8 @@ cfg_if::cfg_if! { } else if #[cfg(target_arch = "loongarch64")] { mod loongarch64; pub use self::loongarch64::*; + } else if #[cfg(target_arch = "arm")] { + mod arm; + pub use self::arm::*; } }