Line data Source code
1 0 : /* 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_ASM_INLINE_GCC_H_ 12 : #define ZEPHYR_INCLUDE_ARCH_ARM_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/toolchain.h> 22 : #include <zephyr/types.h> 23 : #include <zephyr/arch/arm/exception.h> 24 : #include <cmsis_core.h> 25 : 26 : #if defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A) 27 : #include <zephyr/arch/arm/cortex_a_r/cpu.h> 28 : #endif 29 : 30 : #ifdef __cplusplus 31 : extern "C" { 32 : #endif 33 : 34 : /* On ARMv7-M and ARMv8-M Mainline CPUs, this function prevents regular 35 : * exceptions (i.e. with interrupt priority lower than or equal to 36 : * _EXC_IRQ_DEFAULT_PRIO) from interrupting the CPU. NMI, Faults, SVC, 37 : * and Zero Latency IRQs (if supported) may still interrupt the CPU. 38 : * 39 : * On ARMv6-M and ARMv8-M Baseline CPUs, this function reads the value of 40 : * PRIMASK which shows if interrupts are enabled, then disables all interrupts 41 : * except NMI. 42 : */ 43 : 44 0 : static ALWAYS_INLINE unsigned int arch_irq_lock(void) 45 : { 46 : unsigned int key; 47 : 48 : #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) 49 : #if CONFIG_MP_MAX_NUM_CPUS == 1 || defined(CONFIG_ARMV8_M_BASELINE) 50 : key = __get_PRIMASK(); 51 : __disable_irq(); 52 : #else 53 : #error "Cortex-M0 and Cortex-M0+ require SoC specific support for cross core synchronisation." 54 : #endif 55 : #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) 56 : key = __get_BASEPRI(); 57 : __set_BASEPRI_MAX(_EXC_IRQ_DEFAULT_PRIO); 58 : __ISB(); 59 : #elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \ 60 : || defined(CONFIG_ARMV7_A) 61 : __asm__ volatile( 62 : "mrs %0, cpsr;" 63 : "and %0, #" STRINGIFY(I_BIT) ";" 64 : "cpsid i;" 65 : : "=r" (key) 66 : : 67 : : "memory", "cc"); 68 : #else 69 : #error Unknown ARM architecture 70 : #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ 71 : 72 : return key; 73 : } 74 : 75 : 76 : /* On Cortex-M0/M0+, this enables all interrupts if they were not 77 : * previously disabled. 78 : */ 79 : 80 0 : static ALWAYS_INLINE void arch_irq_unlock(unsigned int key) 81 : { 82 : #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) 83 : if (key != 0U) { 84 : return; 85 : } 86 : __enable_irq(); 87 : __ISB(); 88 : #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) 89 : __set_BASEPRI(key); 90 : __ISB(); 91 : #elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \ 92 : || defined(CONFIG_ARMV7_A) 93 : if (key != 0U) { 94 : return; 95 : } 96 : __enable_irq(); 97 : #else 98 : #error Unknown ARM architecture 99 : #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ 100 : } 101 : 102 0 : static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key) 103 : { 104 : /* This convention works for both PRIMASK and BASEPRI */ 105 : return key == 0U; 106 : } 107 : 108 : #ifdef __cplusplus 109 : } 110 : #endif 111 : 112 : #endif /* _ASMLANGUAGE */ 113 : 114 : #endif /* ZEPHYR_INCLUDE_ARCH_ARM_ASM_INLINE_GCC_H_ */