2024-10-22 12:04:08 +08:00
|
|
|
use core::arch::asm;
|
|
|
|
|
2019-05-05 20:56:23 +08:00
|
|
|
/// The classic no-op
|
|
|
|
#[inline]
|
|
|
|
pub fn nop() {
|
2024-10-22 12:04:08 +08:00
|
|
|
unsafe { asm!("nop") }
|
2019-05-05 20:56:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Wait For Event
|
|
|
|
#[inline]
|
|
|
|
pub fn wfe() {
|
2024-10-22 12:04:08 +08:00
|
|
|
unsafe { asm!("wfe") }
|
2019-05-05 20:56:23 +08:00
|
|
|
}
|
2019-05-24 01:05:06 +08:00
|
|
|
|
2019-11-16 06:54:26 +08:00
|
|
|
/// Send Event
|
|
|
|
#[inline]
|
|
|
|
pub fn sev() {
|
2024-10-22 12:04:08 +08:00
|
|
|
unsafe { asm!("sev") }
|
2019-11-16 06:54:26 +08:00
|
|
|
}
|
|
|
|
|
2019-05-24 01:05:06 +08:00
|
|
|
/// Data Memory Barrier
|
|
|
|
#[inline]
|
|
|
|
pub fn dmb() {
|
2024-10-22 12:04:08 +08:00
|
|
|
unsafe { asm!("dmb") }
|
2019-05-24 01:05:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Data Synchronization Barrier
|
|
|
|
#[inline]
|
|
|
|
pub fn dsb() {
|
2024-10-22 12:04:08 +08:00
|
|
|
unsafe { asm!("dsb") }
|
2019-05-24 01:05:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Instruction Synchronization Barrier
|
|
|
|
#[inline]
|
|
|
|
pub fn isb() {
|
2024-10-22 12:04:08 +08:00
|
|
|
unsafe { asm!("isb") }
|
2019-05-24 01:05:06 +08:00
|
|
|
}
|
2020-08-03 11:21:38 +08:00
|
|
|
|
2024-02-02 16:15:46 +08:00
|
|
|
/// Enable FIQ
|
|
|
|
#[inline]
|
|
|
|
pub unsafe fn enable_fiq() {
|
2024-10-22 12:04:08 +08:00
|
|
|
asm!("cpsie f");
|
2024-02-02 16:15:46 +08:00
|
|
|
}
|
|
|
|
|
2020-08-03 11:21:38 +08:00
|
|
|
/// Enable IRQ
|
|
|
|
#[inline]
|
|
|
|
pub unsafe fn enable_irq() {
|
2024-10-22 12:04:08 +08:00
|
|
|
asm!("cpsie i");
|
2020-08-03 11:21:38 +08:00
|
|
|
}
|
2020-08-03 11:23:41 +08:00
|
|
|
|
2020-08-03 11:24:18 +08:00
|
|
|
/// Disable IRQ, return if IRQ was originally enabled.
|
|
|
|
#[inline]
|
|
|
|
pub unsafe fn enter_critical() -> bool {
|
|
|
|
let mut cpsr: u32;
|
2024-10-22 12:04:08 +08:00
|
|
|
asm!(
|
|
|
|
"mrs {}, cpsr
|
|
|
|
cpsid i", lateout(reg) cpsr);
|
2020-08-03 11:24:18 +08:00
|
|
|
(cpsr & (1 << 7)) == 0
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub unsafe fn exit_critical(enable: bool) {
|
|
|
|
// https://stackoverflow.com/questions/40019929/temporarily-disable-interrupts-on-arm
|
|
|
|
let mask: u32 = if enable {
|
|
|
|
1 << 7
|
|
|
|
} else {
|
|
|
|
0
|
|
|
|
};
|
2024-10-22 12:04:08 +08:00
|
|
|
asm!(
|
2020-08-03 11:24:18 +08:00
|
|
|
"mrs r1, cpsr
|
2024-10-22 12:04:08 +08:00
|
|
|
bic r1, r1, {}
|
2020-08-03 11:24:18 +08:00
|
|
|
msr cpsr_c, r1"
|
2024-10-22 12:04:08 +08:00
|
|
|
, in(reg) mask, out("r1") _);
|
2020-08-03 11:24:18 +08:00
|
|
|
}
|
|
|
|
|
2020-08-03 11:23:41 +08:00
|
|
|
/// Exiting IRQ
|
|
|
|
#[inline]
|
|
|
|
pub unsafe fn exit_irq() {
|
2024-10-22 12:04:08 +08:00
|
|
|
asm!("
|
2020-08-03 11:23:41 +08:00
|
|
|
mrs r0, SPSR
|
|
|
|
msr CPSR, r0
|
2024-10-22 12:04:08 +08:00
|
|
|
", out("r0") _);
|
2020-08-03 11:23:41 +08:00
|
|
|
}
|