diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h index 30e0584..a6fe14f 100644 --- a/include/lib/aarch32/arch_helpers.h +++ b/include/lib/aarch32/arch_helpers.h @@ -391,4 +391,59 @@ #define read_amcntenset0_el0() read_amcntenset0() #define read_amcntenset1_el0() read_amcntenset1() +/* Helper functions to manipulate CPSR */ +static inline void enable_irq(void) +{ + /* + * The compiler memory barrier will prevent the compiler from + * scheduling non-volatile memory access after the write to the + * register. + * + * This could happen if some initialization code issues non-volatile + * accesses to an area used by an interrupt handler, in the assumption + * that it is safe as the interrupts are disabled at the time it does + * that (according to program order). However, non-volatile accesses + * are not necessarily in program order relatively with volatile inline + * assembly statements (and volatile accesses). + */ + COMPILER_BARRIER(); + __asm__ volatile ("cpsie i"); + isb(); +} + +static inline void enable_serror(void) +{ + COMPILER_BARRIER(); + __asm__ volatile ("cpsie a"); + isb(); +} + +static inline void enable_fiq(void) +{ + COMPILER_BARRIER(); + __asm__ volatile ("cpsie f"); + isb(); +} + +static inline void disable_irq(void) +{ + COMPILER_BARRIER(); + __asm__ volatile ("cpsid i"); + isb(); +} + +static inline void disable_serror(void) +{ + COMPILER_BARRIER(); + __asm__ volatile ("cpsid a"); + isb(); +} + +static inline void disable_fiq(void) +{ + COMPILER_BARRIER(); + __asm__ volatile ("cpsid f"); + isb(); +} + #endif /* ARCH_HELPERS_H */ diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h index 92b16fc..7222b9d 100644 --- a/include/lib/aarch64/arch_helpers.h +++ b/include/lib/aarch64/arch_helpers.h @@ -215,6 +215,74 @@ DEFINE_SYSOP_TYPE_FUNC(dmb, ish) DEFINE_SYSOP_FUNC(isb) +static inline void enable_irq(void) +{ + /* + * The compiler memory barrier will prevent the compiler from + * scheduling non-volatile memory access after the write to the + * register. + * + * This could happen if some initialization code issues non-volatile + * accesses to an area used by an interrupt handler, in the assumption + * that it is safe as the interrupts are disabled at the time it does + * that (according to program order). However, non-volatile accesses + * are not necessarily in program order relatively with volatile inline + * assembly statements (and volatile accesses). + */ + COMPILER_BARRIER(); + write_daifclr(DAIF_IRQ_BIT); + isb(); +} + +static inline void enable_fiq(void) +{ + COMPILER_BARRIER(); + write_daifclr(DAIF_FIQ_BIT); + isb(); +} + +static inline void enable_serror(void) +{ + COMPILER_BARRIER(); + write_daifclr(DAIF_ABT_BIT); + isb(); +} + +static inline void enable_debug_exceptions(void) +{ + COMPILER_BARRIER(); + write_daifclr(DAIF_DBG_BIT); + isb(); +} + +static inline void disable_irq(void) +{ + COMPILER_BARRIER(); + write_daifset(DAIF_IRQ_BIT); + isb(); +} + +static inline void disable_fiq(void) +{ + COMPILER_BARRIER(); + write_daifset(DAIF_FIQ_BIT); + isb(); +} + +static inline void disable_serror(void) +{ + COMPILER_BARRIER(); + write_daifset(DAIF_ABT_BIT); + isb(); +} + +static inline void disable_debug_exceptions(void) +{ + COMPILER_BARRIER(); + write_daifset(DAIF_DBG_BIT); + isb(); +} + #if !ERROR_DEPRECATED uint32_t get_afflvl_shift(uint32_t); uint32_t mpidr_mask_lower_afflvls(uint64_t, uint32_t);