aarch32-cpu 0.3.0

CPU support for AArch32 Arm Processors
Documentation
//! Simple assembly routines for ARMv4

/// Emit an NOP instruction
#[cfg_attr(not(feature = "check-asm"), inline)]
pub fn nop() {
    unsafe { core::arch::asm!("nop", options(nomem, nostack, preserves_flags)) }
}

/// Mask IRQ
#[cfg_attr(not(feature = "check-asm"), inline)]
#[cfg_attr(target_arch = "arm", instruction_set(arm::a32))]
pub fn irq_disable() {
    #[cfg(target_arch = "arm")]
    unsafe {
        core::arch::asm!(r#"
            mrs {0}, cpsr 
            orr {0}, {flag}
            msr cpsr, {0}
        "#,
        inout(reg) 0 => _,
        flag = const {
            crate::register::Cpsr::new_with_raw_value(0)
                .with_i(true)
                .raw_value()
        },
        options(nomem, nostack, preserves_flags));
    };
}

/// Unmask IRQ
///
/// # Safety
///
/// Do not call this function inside an interrupt-based critical section
#[cfg_attr(not(feature = "check-asm"), inline)]
#[cfg_attr(target_arch = "arm", instruction_set(arm::a32))]
pub unsafe fn irq_enable() {
    #[cfg(target_arch = "arm")]
    unsafe {
        core::arch::asm!(r#"
            mrs {0}, cpsr 
            bic {0}, #{flag}
            msr cpsr, {0}
        "#,
        inout(reg) 0 => _,
        flag = const {
            crate::register::Cpsr::new_with_raw_value(0)
                .with_i(true)
                .raw_value()
        },
        options(nomem, nostack, preserves_flags));
    };
}

/// Mask FIQ
#[cfg_attr(not(feature = "check-asm"), inline)]
#[cfg_attr(target_arch = "arm", instruction_set(arm::a32))]
pub fn fiq_disable() {
    #[cfg(target_arch = "arm")]
    unsafe {
        core::arch::asm!(r#"
            mrs {0}, cpsr 
            orr {0}, {flag}
            msr cpsr, {0}
        "#,
        inout(reg) 0 => _,
        flag = const {
            crate::register::Cpsr::new_with_raw_value(0)
                .with_f(true)
                .raw_value()
        },
        options(nomem, nostack, preserves_flags));
    };
}

/// Unmask FIQ
///
/// FIQ is safe to enable because it is unsafe to handle (because the handler is raw assembly).
#[cfg_attr(not(feature = "check-asm"), inline)]
#[cfg_attr(target_arch = "arm", instruction_set(arm::a32))]
pub fn fiq_enable() {
    #[cfg(target_arch = "arm")]
    unsafe {
        core::arch::asm!(r#"
            mrs {0}, cpsr 
            bic {0}, #{flag}
            msr cpsr, {0}
        "#,
        inout(reg) 0 => _,
        flag = const {
            crate::register::Cpsr::new_with_raw_value(0)
                .with_f(true)
                .raw_value()
        },
        options(nomem, nostack, preserves_flags));
    };
}

/// Which core are we?
///
/// Return the bottom 24-bits of the MPIDR
#[cfg_attr(not(feature = "check-asm"), inline)]
#[cfg(target_arch = "arm")]
#[instruction_set(arm::a32)]
pub fn core_id() -> u32 {
    let r: u32;
    unsafe {
        core::arch::asm!("MRC p15, 0, {}, c0, c0, 5", out(reg) r, options(nomem, nostack, preserves_flags));
    }
    r & 0x00FF_FFFF
}