• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 // Copyright (C) 2022 Beken Corporation
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 
16 #include <stdio.h>
17 #include <string.h>
18 
19 #include <os/os.h>
20 #include "mailbox_channel.h"
21 #include "mb_ipc_cmd.h"
22 #include "amp_res_lock.h"
23 #include "amp_lock_api.h"
24 
25 #define AMP_CPU_CNT		2			/* < 32 CPUs. for the xchg_buff is 64-bytes. */
26 
27 typedef struct
28 {
29 	u8					inited;
30 	beken_semaphore_t	res_sema;
31 
32 #if CONFIG_MASTER_CORE
33 	u16		req_cnt[AMP_CPU_CNT];
34 #endif
35 
36 } amp_res_sync_t;
37 
38 static amp_res_sync_t	amp_res_sync[AMP_RES_ID_MAX];
39 
40 #if CONFIG_MASTER_CORE
41 
42 /* call this API in interrupt disabled state. */
amp_res_acquire_cnt(u16 res_id,u16 cpu_id,amp_res_req_cnt_t * cnt_list)43 bk_err_t amp_res_acquire_cnt(u16 res_id, u16 cpu_id, amp_res_req_cnt_t *cnt_list)
44 {
45 	if(res_id >= AMP_RES_ID_MAX)
46 		return BK_ERR_PARAM;
47 
48 	if(amp_res_sync[res_id].inited == 0)
49 		return BK_ERR_NOT_INIT;
50 
51 	if(cpu_id >= AMP_CPU_CNT)
52 		return BK_ERR_PARAM;
53 
54 	u16		i = 0;
55 	u16 	other_cnt = 0;
56 
57 	cnt_list->self_req_cnt = amp_res_sync[res_id].req_cnt[cpu_id];
58 
59 	for(i = 0; i < AMP_CPU_CNT; i++)
60 	{
61 		other_cnt += amp_res_sync[res_id].req_cnt[i];
62 	}
63 
64 	cnt_list->others_req_cnt = other_cnt - cnt_list->self_req_cnt;
65 
66 	amp_res_sync[res_id].req_cnt[cpu_id]++;
67 
68 	return BK_OK;
69 
70 }
71 
72 /* call this API in interrupt disabled state. */
amp_res_release_cnt(u16 res_id,u16 cpu_id,amp_res_req_cnt_t * cnt_list)73 bk_err_t amp_res_release_cnt(u16 res_id, u16 cpu_id, amp_res_req_cnt_t *cnt_list)
74 {
75 	if(res_id >= AMP_RES_ID_MAX)
76 		return BK_ERR_PARAM;
77 
78 	if(amp_res_sync[res_id].inited == 0)
79 		return BK_ERR_NOT_INIT;
80 
81 	if(cpu_id >= AMP_CPU_CNT)
82 		return BK_ERR_PARAM;
83 
84 	u16		i = 0;
85 
86 	if(amp_res_sync[res_id].req_cnt[cpu_id] > 0)
87 	{
88 		amp_res_sync[res_id].req_cnt[cpu_id]--;
89 
90 		u16 	other_cnt = 0;
91 
92 		for(i = 0; i < AMP_CPU_CNT; i++)
93 		{
94 			other_cnt += amp_res_sync[res_id].req_cnt[i];
95 		}
96 
97 		cnt_list->self_req_cnt = amp_res_sync[res_id].req_cnt[cpu_id];
98 		cnt_list->others_req_cnt = other_cnt - cnt_list->self_req_cnt;
99 
100 		return BK_OK;
101 	}
102 	else
103 	{
104 		return BK_FAIL;
105 	}
106 
107 }
108 
109 #endif
110 
111 #ifdef CONFIG_DUAL_CORE
112 
113 /* Apps can't call this API, it's for IPC isr only. */
amp_res_available(u16 res_id)114 bk_err_t amp_res_available(u16 res_id)
115 {
116 	if(res_id >= AMP_RES_ID_MAX)
117 		return BK_ERR_PARAM;
118 
119 	if(amp_res_sync[res_id].inited == 0)
120 		return BK_ERR_NOT_INIT;
121 
122 	return rtos_set_semaphore(&amp_res_sync[res_id].res_sema);
123 }
124 
125 #endif
126 
amp_res_lock_acquire(u16 res_id,u32 timeout_ms,const char * func_name,int line_no)127 bk_err_t amp_res_lock_acquire(u16 res_id, u32 timeout_ms, const char * func_name, int line_no)
128 {
129 	bk_err_t	ret_val = BK_FAIL;
130 
131 	if( rtos_is_in_interrupt_context() )
132 	{
133 		BK_LOGE("AMP", "can't call in ISR %s,%d\r\n", func_name, line_no);
134 
135 		return BK_FAIL;
136 	}
137 
138 	if(res_id >= AMP_RES_ID_MAX)
139 		return BK_ERR_PARAM;
140 
141 	if(amp_res_sync[res_id].inited == 0)
142 		return BK_ERR_NOT_INIT;
143 
144 #ifdef CONFIG_DUAL_CORE
145 
146 	amp_res_req_cnt_t	cnt_list;
147 
148 #if CONFIG_MASTER_CORE
149 
150 	u32  int_mask = rtos_disable_int();
151 
152 	ret_val = amp_res_acquire_cnt(res_id, SRC_CPU, &cnt_list);
153 
154 	rtos_enable_int(int_mask);
155 
156 #endif
157 
158 #if CONFIG_SLAVE_CORE
159 
160 	ret_val = ipc_send_res_acquire_cnt(res_id, SRC_CPU, &cnt_list);
161 
162 #endif
163 
164 	if(ret_val != BK_OK)
165 	{
166 		return ret_val;
167 	}
168 
169 	if((cnt_list.self_req_cnt == 0) && (cnt_list.others_req_cnt > 0))
170 	{
171 		/* resource was occupied by other CPU, so set semaphore state to unavailable. */
172 		ret_val = rtos_get_semaphore(&amp_res_sync[res_id].res_sema, 0);
173 
174 		if(ret_val != BK_OK)
175 		{
176 			return ret_val;
177 		}
178 	}
179 
180 #endif
181 
182 	ret_val = rtos_get_semaphore(&amp_res_sync[res_id].res_sema, timeout_ms);
183 
184 	return ret_val;
185 
186 }
187 
amp_res_lock_release(u16 res_id,const char * func_name,int line_no)188 bk_err_t amp_res_lock_release(u16 res_id, const char * func_name, int line_no)
189 {
190 	bk_err_t	ret_val = BK_FAIL;
191 
192 	if( rtos_is_in_interrupt_context() )
193 	{
194 		BK_LOGE("AMP", "can't call in ISR %s,%d\r\n", func_name, line_no);
195 
196 		return BK_FAIL;
197 	}
198 
199 	if(res_id >= AMP_RES_ID_MAX)
200 		return BK_ERR_PARAM;
201 
202 	if(amp_res_sync[res_id].inited == 0)
203 		return BK_ERR_NOT_INIT;
204 
205 #ifdef CONFIG_DUAL_CORE
206 
207 	amp_res_req_cnt_t	cnt_list;
208 
209 #if CONFIG_MASTER_CORE
210 
211 	u32  int_mask = rtos_disable_int();
212 
213 	ret_val = amp_res_release_cnt(res_id, SRC_CPU, &cnt_list);
214 
215 	rtos_enable_int(int_mask);
216 
217 #endif
218 
219 #if CONFIG_SLAVE_CORE
220 
221 	ret_val = ipc_send_res_release_cnt(res_id, SRC_CPU, &cnt_list);
222 
223 #endif
224 
225 	if(ret_val != BK_OK)
226 	{
227 		return ret_val;
228 	}
229 
230 	if((cnt_list.self_req_cnt == 0) && (cnt_list.others_req_cnt > 0))
231 	{
232 		/* other CPU is waiting for the resource, so inform CPU that it is available. */
233 		/* which CPU is selected in multi-cores? (over than 2 cores)*/
234 		ret_val = ipc_send_available_ind(res_id);
235 
236 		if(ret_val != BK_OK)
237 		{
238 			return ret_val;
239 		}
240 	}
241 
242 #endif
243 
244 	ret_val = rtos_set_semaphore(&amp_res_sync[res_id].res_sema);
245 
246 	return ret_val;
247 
248 }
249 
amp_res_lock_init(u16 res_id)250 bk_err_t amp_res_lock_init(u16 res_id)
251 {
252 	bk_err_t	ret_val = BK_FAIL;
253 
254 	if(res_id >= AMP_RES_ID_MAX)
255 		return BK_ERR_PARAM;
256 
257 	if(amp_res_sync[res_id].inited != 0)
258 		return BK_OK;
259 
260 #if CONFIG_MASTER_CORE
261 
262 	u16 i = 0;
263 
264 	for(i = 0; i < AMP_CPU_CNT; i++)
265 	{
266 		amp_res_sync[res_id].req_cnt[i] = 0;
267 	}
268 
269 #endif
270 
271 	ret_val = rtos_init_semaphore_adv(&amp_res_sync[res_id].res_sema, 1, 1);
272 
273 	if(ret_val != BK_OK)
274 		return ret_val;
275 
276 	amp_res_sync[res_id].inited = 1;
277 
278 	return BK_OK;
279 }
280 
281