• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 #ifndef __OAL_LINUX_SPINLOCK_H__
20 #define __OAL_LINUX_SPINLOCK_H__
21 
22 /* ****************************************************************************
23   1 其他头文件包含
24 **************************************************************************** */
25 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
26 #include <linux/spinlock.h>
27 #endif
28 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
29 #include <los_task.h>
30 #include <los_spinlock.h>
31 #endif
32 
33 #ifdef __cplusplus
34 #if __cplusplus
35 extern "C" {
36 #endif
37 #endif
38 
39 /* ****************************************************************************
40   2 宏定义
41 **************************************************************************** */
42 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
43 typedef spinlock_t oal_spinlock;
44 
45 #define OAL_SPIN_LOCK_MAGIC_TAG (0xdead4ead)
46 typedef struct _oal_spin_lock_stru_ {
47 #ifdef CONFIG_SPIN_LOCK_MAGIC_DEBUG
48     hi_u32 magic;
49     hi_u32 reserved;
50 #endif
51     spinlock_t lock;
52 } oal_spin_lock_stru;
53 
54 #ifdef CONFIG_SPIN_LOCK_MAGIC_DEBUG
55 #define OAL_DEFINE_SPINLOCK(x) oal_spin_lock_stru x = {              \
56         .magic = OAL_SPIN_LOCK_MAGIC_TAG, \
57         .lock = __SPIN_LOCK_UNLOCKED(x)   \
58     }
59 #else
60 #define OAL_DEFINE_SPINLOCK(x) oal_spin_lock_stru x = {            \
61         .lock = __SPIN_LOCK_UNLOCKED(x) \
62     }
63 #endif
64 
65 /* 函数指针,用来指向需要自旋锁保护的的函数 */
66 typedef hi_u32 (*oal_irqlocked_func)(hi_void *);
67 #endif
68 
69 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
70 typedef struct _oal_spin_lock_stru_ {
71     SPIN_LOCK_S lock;
72 } oal_spin_lock_stru;
73 
74 
oal_spin_lock_init(oal_spin_lock_stru * pst_lock)75 static inline hi_void oal_spin_lock_init(oal_spin_lock_stru *pst_lock)
76 {
77 #ifdef LOSCFG_KERNEL_SMP
78     LOS_SpinInit(&pst_lock->lock);
79 #else
80     (void)pst_lock;
81 #endif
82 }
83 
84 /*
85 锁线程调度,支持嵌套
86 */
oal_spin_lock(oal_spin_lock_stru * pst_lock)87 static inline hi_void oal_spin_lock(oal_spin_lock_stru *pst_lock)
88 {
89 #ifdef LOSCFG_KERNEL_SMP
90     LOS_SpinLock(&pst_lock->lock);
91 #else
92     (void)pst_lock;
93     LOS_TaskLock();
94 #endif
95 }
oal_spin_unlock(oal_spin_lock_stru * pst_lock)96 static inline hi_void oal_spin_unlock(oal_spin_lock_stru *pst_lock)
97 {
98 #ifdef LOSCFG_KERNEL_SMP
99     LOS_SpinUnlock(&pst_lock->lock);
100 #else
101     (void)pst_lock;
102     LOS_TaskUnlock();
103 #endif
104 }
105 
106 /*
107 锁线程调度,支持嵌套
108 */
oal_spin_lock_bh(oal_spin_lock_stru * pst_lock)109 static inline hi_void oal_spin_lock_bh(oal_spin_lock_stru *pst_lock)
110 {
111 #ifdef LOSCFG_KERNEL_SMP
112     LOS_SpinLock(&pst_lock->lock);
113 #else
114     (void)pst_lock;
115     LOS_TaskLock();
116 #endif
117 }
oal_spin_unlock_bh(oal_spin_lock_stru * pst_lock)118 static inline hi_void oal_spin_unlock_bh(oal_spin_lock_stru *pst_lock)
119 {
120 #ifdef LOSCFG_KERNEL_SMP
121     LOS_SpinUnlock(&pst_lock->lock);
122 #else
123     (void)pst_lock;
124     LOS_TaskUnlock();
125 #endif
126 }
127 
128 /*
129 锁硬件中断,支持嵌套
130 */
oal_spin_lock_irq_save(oal_spin_lock_stru * pst_lock,unsigned long * flags)131 static inline hi_void oal_spin_lock_irq_save(oal_spin_lock_stru *pst_lock, unsigned long *flags)
132 {
133 #ifdef LOSCFG_KERNEL_SMP
134     LOS_SpinLockSave(&pst_lock->lock, (UINT32 *)flags);
135 #else
136     (void)pst_lock;
137     *flags = LOS_IntLock();
138 #endif
139 }
oal_spin_unlock_irq_restore(oal_spin_lock_stru * pst_lock,unsigned long * flags)140 static inline hi_void oal_spin_unlock_irq_restore(oal_spin_lock_stru *pst_lock, unsigned long *flags)
141 {
142 #ifdef LOSCFG_KERNEL_SMP
143     LOS_SpinUnlockRestore(&pst_lock->lock, (UINT32)*flags);
144 #else
145     (void)pst_lock;
146     LOS_IntRestore(*flags);
147 #endif
148 }
149 #endif
150 
151 /* ****************************************************************************
152   3 枚举定义
153 **************************************************************************** */
154 /* ****************************************************************************
155   4 全局变量声明
156 **************************************************************************** */
157 /* ****************************************************************************
158   5 消息头定义
159 **************************************************************************** */
160 /* ****************************************************************************
161   6 消息定义
162 **************************************************************************** */
163 /* ****************************************************************************
164   7 STRUCT定义
165 **************************************************************************** */
166 /* ****************************************************************************
167   8 UNION定义
168 **************************************************************************** */
169 /* ****************************************************************************
170   9 OTHERS定义
171 **************************************************************************** */
172 /* ****************************************************************************
173   10 函数声明
174 **************************************************************************** */
175 #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
176 /* ****************************************************************************
177  功能描述  : 自旋锁初始化,把自旋锁设置为1(未锁状态)。
178  输入参数  : *pst_lock: 锁的地址
179  输出参数  : 无
180  返 回 值  : 无
181 **************************************************************************** */
oal_spin_lock_init(oal_spin_lock_stru * pst_lock)182 static inline hi_void oal_spin_lock_init(oal_spin_lock_stru *pst_lock)
183 {
184     spin_lock_init(&pst_lock->lock);
185 #ifdef CONFIG_SPIN_LOCK_MAGIC_DEBUG
186     pst_lock->magic = OAL_SPIN_LOCK_MAGIC_TAG;
187 #endif
188 }
189 #define SPIN_LOCK_CONSTANT (32)
oal_spin_lock_magic_bug(oal_spin_lock_stru * pst_lock)190 static inline hi_void oal_spin_lock_magic_bug(oal_spin_lock_stru *pst_lock)
191 {
192 #ifdef CONFIG_SPIN_LOCK_MAGIC_DEBUG
193     if (oal_unlikely((hi_u32)OAL_SPIN_LOCK_MAGIC_TAG != pst_lock->magic)) {
194 #ifdef CONFIG_PRINTK
195         /* spinlock never init or memory overwrite */
196         printk(KERN_EMERG "[E]SPIN_LOCK_BUG: spinlock:%p on CPU#%d, %s,magic:%08x should be %08x\n", pst_lock,
197             raw_smp_processor_id(), current->comm, pst_lock->magic, OAL_SPIN_LOCK_MAGIC_TAG);
198         print_hex_dump(KERN_EMERG, "spinlock_magic: ", DUMP_PREFIX_ADDRESS, 16, 1, /* 16:hex */
199             (hi_u8 *)((uintptr_t)pst_lock - SPIN_LOCK_CONSTANT),
200             SPIN_LOCK_CONSTANT + sizeof(oal_spin_lock_stru) + SPIN_LOCK_CONSTANT, true);
201         printk(KERN_EMERG "\n");
202 #endif
203     }
204 #else
205     hi_unref_param(pst_lock);
206 #endif
207 }
208 
209 /* ****************************************************************************
210  功能描述  : 自旋锁在软中断以及内核线程等核心态上下文环境下的加锁操作。如果
211              能够立即获得锁,它就马上返回,否则,它将自旋在那里,直到该自旋
212              锁的保持者释放,这时,它获得锁并返回。
213  输入参数  : *pst_lock:自旋锁地址
214  输出参数  : 无
215  返 回 值  : 无
216 **************************************************************************** */
oal_spin_lock(oal_spin_lock_stru * pst_lock)217 static inline hi_void oal_spin_lock(oal_spin_lock_stru *pst_lock)
218 {
219     oal_spin_lock_magic_bug(pst_lock);
220     spin_lock(&pst_lock->lock);
221 }
222 
223 /* ****************************************************************************
224  功能描述  : Spinlock在内核线程等核心态上下文环境下的解锁操作。
225  输入参数  : *pst_lock:自旋锁地址
226  输出参数  : 无
227  返 回 值  : 无
228 **************************************************************************** */
oal_spin_unlock(oal_spin_lock_stru * pst_lock)229 static inline hi_void oal_spin_unlock(oal_spin_lock_stru *pst_lock)
230 {
231     oal_spin_lock_magic_bug(pst_lock);
232     spin_unlock(&pst_lock->lock);
233 }
234 
235 /* ****************************************************************************
236  功能描述  : 自旋锁在软中断以及内核线程等核心态上下文环境下的加锁操作。如果
237              能够立即获得锁,它就马上返回,否则,它将自旋在那里,直到该自旋
238              锁的保持者释放,这时,它获得锁并返回。
239  输入参数  : pst_lock:自旋锁地址
240  输出参数  : 无
241  返 回 值  : 无
242 **************************************************************************** */
oal_spin_lock_bh(oal_spin_lock_stru * pst_lock)243 static inline hi_void oal_spin_lock_bh(oal_spin_lock_stru *pst_lock)
244 {
245     oal_spin_lock_magic_bug(pst_lock);
246     spin_lock_bh(&pst_lock->lock);
247 }
248 
249 /* ****************************************************************************
250  功能描述  : Spinlock在软中断以及内核线程等核心态上下文环境下的解锁操作。
251  输入参数  : 无
252  输出参数  : 无
253  返 回 值  : hi_void
254 **************************************************************************** */
oal_spin_unlock_bh(oal_spin_lock_stru * pst_lock)255 static inline hi_void oal_spin_unlock_bh(oal_spin_lock_stru *pst_lock)
256 {
257     oal_spin_lock_magic_bug(pst_lock);
258     spin_unlock_bh(&pst_lock->lock);
259 }
260 
261 /* ****************************************************************************
262  功能描述  : 获得自旋锁的同时获得保存标志寄存器的值,并且失效本地中断。
263  输入参数  : *pst_lock:自旋锁地址
264              pui_flags:标志寄存器
265  输出参数  : 无
266  返 回 值  : 无
267 **************************************************************************** */
oal_spin_lock_irq_save(oal_spin_lock_stru * pst_lock,unsigned long * pui_flags)268 static inline hi_void oal_spin_lock_irq_save(oal_spin_lock_stru *pst_lock, unsigned long *pui_flags)
269 {
270     oal_spin_lock_magic_bug(pst_lock);
271     spin_lock_irqsave(&pst_lock->lock, *pui_flags);
272 }
273 
274 /* ****************************************************************************
275  功能描述  : 释放自旋锁的同时,恢复标志寄存器的值,恢复本地中断。它与oal_sp-
276              in_lock_irq配对使用
277  输入参数  : *pst_lock:自旋锁地址
278              pui_flags:标志寄存器
279  输出参数  : 无
280  返 回 值  : 无
281 **************************************************************************** */
oal_spin_unlock_irq_restore(oal_spin_lock_stru * pst_lock,unsigned long * pui_flags)282 static inline hi_void oal_spin_unlock_irq_restore(oal_spin_lock_stru *pst_lock, unsigned long *pui_flags)
283 {
284     oal_spin_lock_magic_bug(pst_lock);
285     spin_unlock_irqrestore(&pst_lock->lock, *pui_flags);
286 }
287 
288 /* ****************************************************************************
289  功能描述  : 获取自旋锁,关闭中断,执行某个函数,完了之后再打开中断,释放自
290              旋锁。
291  输入参数  : *pst_lock:自旋锁地址
292              func:函数指针地址
293              *p_arg:函数参数
294              *pui_flags: 中断标志寄存器
295  输出参数  : 无
296  返 回 值  :
297 **************************************************************************** */
oal_spin_lock_irq_exec(oal_spin_lock_stru * pst_lock,oal_irqlocked_func func,hi_void * p_arg,unsigned long * pui_flags)298 static inline hi_u32 oal_spin_lock_irq_exec(oal_spin_lock_stru *pst_lock, oal_irqlocked_func func, hi_void *p_arg,
299     unsigned long *pui_flags)
300 {
301     hi_u32 ul_rslt;
302 
303     spin_lock_irqsave(&pst_lock->lock, *pui_flags);
304     ul_rslt = func(p_arg);
305     spin_unlock_irqrestore(&pst_lock->lock, *pui_flags);
306 
307     return ul_rslt;
308 }
309 #endif
310 
311 #ifdef __cplusplus
312 #if __cplusplus
313 }
314 #endif
315 #endif
316 
317 #endif /* end of oal_spinlock.h */
318