zynq-rs/libcortex_a9/src/asm.rs

84 lines
1.3 KiB
Rust
Raw Normal View History

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
}
/// Enable FIQ
#[inline]
pub unsafe fn enable_fiq() {
2024-10-22 12:04:08 +08:00
asm!("cpsie f");
}
/// Enable IRQ
#[inline]
pub unsafe fn enable_irq() {
2024-10-22 12:04:08 +08:00
asm!("cpsie i");
}
/// 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);
(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!(
"mrs r1, cpsr
2024-10-22 12:04:08 +08:00
bic r1, r1, {}
msr cpsr_c, r1"
2024-10-22 12:04:08 +08:00
, in(reg) mask, out("r1") _);
}
/// Exiting IRQ
#[inline]
pub unsafe fn exit_irq() {
2024-10-22 12:04:08 +08:00
asm!("
mrs r0, SPSR
msr CPSR, r0
2024-10-22 12:04:08 +08:00
", out("r0") _);
}