Branch data Line data Source code
1 : : /* ARM AArch32 GCC specific public inline assembler functions and macros */ 2 : : 3 : : /* 4 : : * Copyright (c) 2015, Wind River Systems, Inc. 5 : : * 6 : : * SPDX-License-Identifier: Apache-2.0 7 : : */ 8 : : 9 : : /* Either public functions or macros or invoked by public functions */ 10 : : 11 : : #ifndef ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_ASM_INLINE_GCC_H_ 12 : : #define ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_ASM_INLINE_GCC_H_ 13 : : 14 : : /* 15 : : * The file must not be included directly 16 : : * Include arch/cpu.h instead 17 : : */ 18 : : 19 : : #ifndef _ASMLANGUAGE 20 : : 21 : : #include <zephyr/types.h> 22 : : #include <arch/arm/aarch32/exc.h> 23 : : #include <irq.h> 24 : : 25 : : #if defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A) 26 : : #include <arch/arm/aarch32/cortex_a_r/cpu.h> 27 : : #endif 28 : : 29 : : #ifdef __cplusplus 30 : : extern "C" { 31 : : #endif 32 : : 33 : : /* On ARMv7-M and ARMv8-M Mainline CPUs, this function prevents regular 34 : : * exceptions (i.e. with interrupt priority lower than or equal to 35 : : * _EXC_IRQ_DEFAULT_PRIO) from interrupting the CPU. NMI, Faults, SVC, 36 : : * and Zero Latency IRQs (if supported) may still interrupt the CPU. 37 : : * 38 : : * On ARMv6-M and ARMv8-M Baseline CPUs, this function reads the value of 39 : : * PRIMASK which shows if interrupts are enabled, then disables all interrupts 40 : : * except NMI. 41 : : */ 42 : : 43 : 191198 : static ALWAYS_INLINE unsigned int arch_irq_lock(void) 44 : : { 45 : : unsigned int key; 46 : : 47 : : #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) 48 : : __asm__ volatile("mrs %0, PRIMASK;" 49 : : "cpsid i" 50 : : : "=r" (key) 51 : : : 52 : : : "memory"); 53 : : #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) 54 : : unsigned int tmp; 55 : : 56 : 191198 : __asm__ volatile( 57 : : "mov %1, %2;" 58 : : "mrs %0, BASEPRI;" 59 : : "msr BASEPRI_MAX, %1;" 60 : : "isb;" 61 : : : "=r"(key), "=r"(tmp) 62 : : : "i"(_EXC_IRQ_DEFAULT_PRIO) 63 : : : "memory"); 64 : : #elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \ 65 : : || defined(CONFIG_ARMV7_A) 66 : : __asm__ volatile( 67 : : "mrs %0, cpsr;" 68 : : "and %0, #" TOSTR(I_BIT) ";" 69 : : "cpsid i;" 70 : : : "=r" (key) 71 : : : 72 : : : "memory", "cc"); 73 : : #else 74 : : #error Unknown ARM architecture 75 : : #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ 76 : : 77 : 191198 : return key; 78 : : } 79 : : 80 : : 81 : : /* On Cortex-M0/M0+, this enables all interrupts if they were not 82 : : * previously disabled. 83 : : */ 84 : : 85 : 191198 : static ALWAYS_INLINE void arch_irq_unlock(unsigned int key) 86 : : { 87 : : #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) 88 : : if (key != 0U) { 89 : : return; 90 : : } 91 : : __asm__ volatile( 92 : : "cpsie i;" 93 : : "isb" 94 : : : : : "memory"); 95 : : #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) 96 : 191198 : __asm__ volatile( 97 : : "msr BASEPRI, %0;" 98 : : "isb;" 99 : : : : "r"(key) : "memory"); 100 : : #elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \ 101 : : || defined(CONFIG_ARMV7_A) 102 : : if (key != 0U) { 103 : : return; 104 : : } 105 : : __asm__ volatile( 106 : : "cpsie i;" 107 : : : : : "memory", "cc"); 108 : : #else 109 : : #error Unknown ARM architecture 110 : : #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ 111 : 191197 : } 112 : : 113 : 2 : static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key) 114 : : { 115 : : /* This convention works for both PRIMASK and BASEPRI */ 116 : 2 : return key == 0U; 117 : : } 118 : : 119 : : #ifdef __cplusplus 120 : : } 121 : : #endif 122 : : 123 : : #endif /* _ASMLANGUAGE */ 124 : : 125 : : #endif /* ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_ASM_INLINE_GCC_H_ */