1 /*
2 * Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the
12 * distribution.
13 * 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #ifndef _SYS_INTERRUPT_H_
31 #define _SYS_INTERRUPT_H_
32
33 #include "compiler.h"
34
35 #if defined(__CC_ARM)
36 /* ARM Compiler */
37
38 /*
39 * CPU interrupt mask handling.
40 */
41 #define IRQMASK_REG_NAME_R primask
42 #define IRQMASK_REG_NAME_W primask
43
44 /*
45 * Save the current interrupt enable state & disable IRQs
46 */
arch_irq_save(void)47 static __always_inline unsigned long arch_irq_save(void)
48 {
49 unsigned long flags;
50
51 __asm {
52 mrs flags, IRQMASK_REG_NAME_R
53 cpsid i
54 }
55 return flags;
56 }
57
58 /*
59 * restore saved IRQ state
60 */
arch_irq_restore(unsigned long flags)61 static __always_inline void arch_irq_restore(unsigned long flags)
62 {
63 __asm { msr IRQMASK_REG_NAME_W, flags }
64 }
65
66 /*
67 * Enable IRQs
68 */
69 #define arch_irq_enable() __enable_irq()
70
71 /*
72 * Disable IRQs
73 */
74 #define arch_irq_disable() __disable_irq()
75
76 /*
77 * Enable FIQs
78 */
79 #define arch_fiq_enable() __enable_fiq()
80
81 /*
82 * Disable FIQs
83 */
84 #define arch_fiq_disable() __disable_fiq()
85
86 #elif defined(__GNUC__)
87 /* GNU Compiler */
88
89 #ifdef __CONFIG_OS_RTTHREAD
90
91 /*
92 * Save the current interrupt enable state & disable IRQs
93 */
94 #define arch_irq_save(void) rt_hw_interrupt_disable()
95
96 /*
97 * restore saved IRQ state
98 */
99 #define arch_irq_restore(flags) rt_hw_interrupt_enable(flags)
100
101 /*
102 * Enable IRQs
103 */
104 #define arch_irq_enable() rt_hw_interrupt_enable(__irq_level)
105
106 /*
107 * Disable IRQs
108 */
109 #define arch_irq_disable() rt_base_t __irq_level = rt_hw_interrupt_disable()
110
111 #else /* __CONFIG_OS_RTTHREAD */
112
113 /*
114 * CPU interrupt mask handling.
115 */
116 #define IRQMASK_REG_NAME_R "primask"
117 #define IRQMASK_REG_NAME_W "primask"
118
119 /*
120 * Save the current interrupt enable state & disable IRQs
121 */
arch_irq_save(void)122 static __always_inline unsigned long arch_irq_save(void)
123 {
124 unsigned long flags;
125
126 __asm volatile(
127 "mrs %0, " IRQMASK_REG_NAME_R "\n"
128 "cpsid i"
129 : "=r" (flags) : : "memory", "cc");
130 return flags;
131 }
132
133 /*
134 * restore saved IRQ state
135 */
arch_irq_restore(unsigned long flags)136 static __always_inline void arch_irq_restore(unsigned long flags)
137 {
138 __asm volatile(
139 "msr " IRQMASK_REG_NAME_W ", %0"
140 :
141 : "r" (flags)
142 : "memory", "cc");
143 }
144
145 /*
146 * Save the current interrupt enable state.
147 */
arch_irq_get_flags(void)148 static __always_inline unsigned long arch_irq_get_flags(void)
149 {
150 unsigned long flags;
151
152 __asm volatile(
153 "mrs %0, " IRQMASK_REG_NAME_R "\n"
154 : "=r" (flags) : : "memory", "cc");
155 return flags;
156
157 }
158
159 /*
160 * Enable IRQs
161 */
162 #define arch_irq_enable() __asm volatile("cpsie i" : : : "memory", "cc")
163
164 /*
165 * Disable IRQs
166 */
167 #define arch_irq_disable() __asm volatile("cpsid i" : : : "memory", "cc")
168
169 /*
170 * Enable FIQs
171 */
172 #define arch_fiq_enable() __asm volatile("cpsie f" : : : "memory", "cc")
173
174 /*
175 * Disable FIQs
176 */
177 #define arch_fiq_disable() __asm volatile("cpsid f" : : : "memory", "cc")
178
179 #endif /* __CONFIG_OS_RTTHREAD */
180
181 #else
182 #error "Compiler not supported."
183 #endif
184
185 #endif /* _SYS_INTERRUPT_H_ */
186