• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2022 Beken Corporation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <common/bk_include.h>
16 #include <common/bk_typedef.h>
17 #include "spinlock.h"
18 
19 #if 0  /* dual core have the separated memory space. */
20 #ifdef CONFIG_DUAL_CORE
21 #define CONFIG_CPU_NUM		2
22 #else
23 #define CONFIG_CPU_NUM		1
24 #endif
25 #endif
26 
27 extern void		arch_fence(void);
28 extern u32		arch_atomic_set(u32 * lock_addr);
29 extern void		arch_atomic_clear(u32 * lock_addr);
30 
31 extern u32		arch_int_lock(void);
32 extern void		arch_int_restore(u32 int_flag);
33 
34 typedef struct
35 {
36 //	u32		cpu_id;
37 	u32		nest_cnt;
38 	u32		int_flag;
39 } cpu_info_t;
40 
41 //static cpu_info_t	cpu_info[CONFIG_CPU_NUM];
42 /* dual core have the separated memory space, so don't need cpu_info array for each core. */
43 static cpu_info_t	cpu_info = { .nest_cnt = 0, .int_flag = 0 };
44 
45 #if 0
46 void init_cpu_info(void)
47 {
48 	u32	i;
49 
50 	for(i = 0; i < CONFIG_CPU_NUM; i++)
51 	{
52 		cpu_info[i].cpu_id = i;
53 		cpu_info[i].int_flag = 0;
54 		cpu_info[i].nest_cnt = 0;
55 	}
56 }
57 #endif
58 
get_cur_cpu(void)59 static cpu_info_t * get_cur_cpu(void)
60 {
61 #if 0
62 #ifdef CONFIG_SLAVE_CORE
63 
64 	return &cpu_info[1];
65 
66 #endif
67 
68 	return &cpu_info[0];
69 #else
70 	return &cpu_info;
71 #endif
72 }
73 
push_disable_int_flag(void)74 static void push_disable_int_flag(void)
75 {
76 	cpu_info_t *cur_cpu = get_cur_cpu();
77 	u32			int_flag = arch_int_lock();
78 
79 	if(cur_cpu->nest_cnt == 0)
80 		cur_cpu->int_flag = int_flag;
81 
82 	cur_cpu->nest_cnt++;
83 }
84 
pop_int_flag(void)85 static void pop_int_flag(void)
86 {
87 	cpu_info_t * cur_cpu = get_cur_cpu();
88 
89 	if(cur_cpu->nest_cnt < 1)
90 	{
91 		/*
92 		 *  FATAL ERROR!!!
93 		 */
94 		return;
95 	}
96 
97 	cur_cpu->nest_cnt--;
98 
99 	if(cur_cpu->nest_cnt == 0)
100 		arch_int_restore(cur_cpu->int_flag);
101 }
102 
103 #ifdef CONFIG_DUAL_CORE
spinlock_owner(spinlock_t * slock)104 static u32 spinlock_owner(spinlock_t *slock)
105 {
106 	if(slock->locked == 0)
107 		return 0;
108 
109 	if(slock->owner_cpu != get_cur_cpu())
110 		return 0;
111 
112 	return 1;
113 }
114 #endif
115 
spinlock_init(spinlock_t * slock)116 void spinlock_init(spinlock_t *slock)
117 {
118 	slock->owner_cpu = NULL;
119 	slock->locked = 0;
120 }
121 
spinlock_acquire(spinlock_t * slock)122 void spinlock_acquire(spinlock_t *slock)
123 {
124 	push_disable_int_flag();
125 
126 #ifdef CONFIG_DUAL_CORE
127 	if(spinlock_owner(slock))
128 	{
129 		/*
130 		 *  FATAL ERROR!!!
131 		 */
132 
133 		BK_LOG_RAW("FATAL ERROR in %s\r\n", __func__);
134 		pop_int_flag();
135 		return;
136 
137 	}
138 
139 	while( arch_atomic_set(&slock->locked) ) ;
140 
141 	arch_fence();
142 
143 	slock->owner_cpu = get_cur_cpu();
144 #endif
145 }
146 
spinlock_release(spinlock_t * slock)147 void spinlock_release(spinlock_t *slock)
148 {
149 #ifdef CONFIG_DUAL_CORE
150 	if(!spinlock_owner(slock))
151 	{
152 		/*
153 		 *  FATAL ERROR!!!
154 		 */
155 
156 		BK_LOG_RAW("FATAL ERROR in %s\r\n", __func__);
157 		return;
158 	}
159 
160 	slock->owner_cpu = NULL;
161 
162 	arch_fence();
163 
164 	arch_atomic_clear(&slock->locked);
165 #endif
166 
167 	pop_int_flag();
168 }
169 
170