Zephyr API Documentation  3.5.0
A Scalable Open Source RTOS
3.5.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
asm_inline_gcc.h
Go to the documentation of this file.
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 <zephyr/arch/arm/exc.h>
23
24#if defined(CONFIG_CPU_AARCH32_CORTEX_R) || defined(CONFIG_CPU_AARCH32_CORTEX_A)
26#endif
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32/* On ARMv7-M and ARMv8-M Mainline CPUs, this function prevents regular
33 * exceptions (i.e. with interrupt priority lower than or equal to
34 * _EXC_IRQ_DEFAULT_PRIO) from interrupting the CPU. NMI, Faults, SVC,
35 * and Zero Latency IRQs (if supported) may still interrupt the CPU.
36 *
37 * On ARMv6-M and ARMv8-M Baseline CPUs, this function reads the value of
38 * PRIMASK which shows if interrupts are enabled, then disables all interrupts
39 * except NMI.
40 */
41
42static ALWAYS_INLINE unsigned int arch_irq_lock(void)
43{
44 unsigned int key;
45
46#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) && !defined(CONFIG_ARMV8_M_BASELINE)
47#if CONFIG_MP_MAX_NUM_CPUS == 1
48 __asm__ volatile("mrs %0, PRIMASK;"
49 "cpsid i"
50 : "=r" (key)
51 :
52 : "memory");
53#else
54#error "Cortex-M0 and Cortex-M0+ require SoC specific support for cross core synchronisation."
55#endif
56#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) || defined(CONFIG_ARMV8_M_BASELINE)
57 unsigned int tmp;
58
59 __asm__ volatile(
60 "mov %1, %2;"
61 "mrs %0, BASEPRI;"
62 "msr BASEPRI_MAX, %1;"
63 "isb;"
64 : "=r"(key),
65#if defined(CONFIG_ARMV8_M_BASELINE)
66 /* armv8-m.baseline's mov is limited to registers r0-r7.
67 * Let the compiler know we have this constraint on tmp.
68 */
69 "=l"(tmp)
70#else
71 "=r"(tmp)
72#endif
73 : "i"(_EXC_IRQ_DEFAULT_PRIO)
74 : "memory");
75#elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \
76 || defined(CONFIG_ARMV7_A)
77 __asm__ volatile(
78 "mrs %0, cpsr;"
79 "and %0, #" TOSTR(I_BIT) ";"
80 "cpsid i;"
81 : "=r" (key)
82 :
83 : "memory", "cc");
84#else
85#error Unknown ARM architecture
86#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */
87
88 return key;
89}
90
91
92/* On Cortex-M0/M0+, this enables all interrupts if they were not
93 * previously disabled.
94 */
95
96static ALWAYS_INLINE void arch_irq_unlock(unsigned int key)
97{
98#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) && !defined(CONFIG_ARMV8_M_BASELINE)
99 if (key != 0U) {
100 return;
101 }
102 __asm__ volatile(
103 "cpsie i;"
104 "isb"
105 : : : "memory");
106#elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) || defined(CONFIG_ARMV8_M_BASELINE)
107 __asm__ volatile(
108 "msr BASEPRI, %0;"
109 "isb;"
110 : : "r"(key) : "memory");
111#elif defined(CONFIG_ARMV7_R) || defined(CONFIG_AARCH32_ARMV8_R) \
112 || defined(CONFIG_ARMV7_A)
113 if (key != 0U) {
114 return;
115 }
116 __asm__ volatile(
117 "cpsie i;"
118 : : : "memory", "cc");
119#else
120#error Unknown ARM architecture
121#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */
122}
123
124static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key)
125{
126 /* This convention works for both PRIMASK and BASEPRI */
127 return key == 0U;
128}
129
130#ifdef __cplusplus
131}
132#endif
133
134#endif /* _ASMLANGUAGE */
135
136#endif /* ZEPHYR_INCLUDE_ARCH_ARM_AARCH32_ASM_INLINE_GCC_H_ */
#define TOSTR(s)
Definition: irq.h:80
static ALWAYS_INLINE unsigned int arch_irq_lock(void)
Definition: asm_inline_gcc.h:42
static ALWAYS_INLINE void arch_irq_unlock(unsigned int key)
Definition: asm_inline_gcc.h:96
static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key)
Definition: asm_inline_gcc.h:124
ARM AArch32 public exception handling.
#define ALWAYS_INLINE
Definition: common.h:129
#define I_BIT
Definition: cpu.h:30