1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 // Software and any modification/derivatives thereof.
18 // No right, ownership, or interest to MStar Software and any
19 // modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 // supplied together with third party`s software and the use of MStar
23 // Software may require additional licenses from third parties.
24 // Therefore, you hereby agree it is your sole responsibility to separately
25 // obtain any and all third party right and license necessary for your use of
26 // such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 // MStar`s confidential information and you agree to keep MStar`s
30 // confidential information in strictest confidence and not disclose to any
31 // third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 // kind. Any warranties are hereby expressly disclaimed by MStar, including
35 // without limitation, any warranties of merchantability, non-infringement of
36 // intellectual property rights, fitness for a particular purpose, error free
37 // and in conformity with any international standard. You agree to waive any
38 // claim against MStar for any loss, damage, cost or expense that you may
39 // incur related to your use of MStar Software.
40 // In no event shall MStar be liable for any direct, indirect, incidental or
41 // consequential damages, including without limitation, lost of profit or
42 // revenues, lost or damage of data, and unauthorized system use.
43 // You agree that this Section 4 shall still apply without being affected
44 // even if MStar Software has been modified by MStar in accordance with your
45 // request or instruction for your use, except otherwise agreed by both
46 // parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 // services in relation with MStar Software to you for your use of
50 // MStar Software in conjunction with your or your customer`s product
51 // ("Services").
52 // You understand and agree that, except otherwise agreed by both parties in
53 // writing, Services are provided on an "AS IS" basis and the warranty
54 // disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 // or otherwise:
58 // (a) conferring any license or right to use MStar name, trademark, service
59 // mark, symbol or any other identification;
60 // (b) obligating MStar or any of its affiliates to furnish any person,
61 // including without limitation, you and your customers, any assistance
62 // of any kind whatsoever, or any information; or
63 // (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 // of Taiwan, R.O.C., excluding its conflict of law rules.
67 // Any and all dispute arising out hereof or related hereto shall be finally
68 // settled by arbitration referred to the Chinese Arbitration Association,
69 // Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 // Rules of the Association by three (3) arbitrators appointed in accordance
71 // with the said Rules.
72 // The place of arbitration shall be in Taipei, Taiwan and the language shall
73 // be English.
74 // The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ////////////////////////////////////////////////////////////////////////////////
79 //
80 // Copyright (c) 2008-2009 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // ("MStar Confidential Information") by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94
95 ///////////////////////////////////////////////////////////////////////////////////////////////////
96 ///
97 /// file drvIPAPool.c
98 /// @brief IPA Pool Driver
99 /// @author MStar Semiconductor Inc.
100 ///////////////////////////////////////////////////////////////////////////////////////////////////
101
102
103 //-------------------------------------------------------------------------------------------------
104 // Include Files
105 //-------------------------------------------------------------------------------------------------
106 #if defined (MSOS_TYPE_LINUX)
107 #include<sys/types.h>
108 #include <sys/ioctl.h>
109 #include <sys/mman.h>
110 #include <poll.h>
111 #include <pthread.h>
112 #include<fcntl.h>
113 #include <unistd.h>
114 #include <string.h>
115 #include "MsCommon.h"
116 #include "halCHIP.h"
117 #include "halMPool.h"
118 #include "drvIPAPool.h"
119 #include "mdrv_ipa_pool_uapi.h"
120
121 #ifndef ANDROID
122 #define VPRINTF printf
123 #else
124 #include <sys/mman.h>
125 #include <cutils/ashmem.h>
126 #include <cutils/log.h>
127 #define VPRINTF ALOGD
128 #endif
129
130 //-------------------------------------------------------------------------------------------------
131 // Local Defines
132 //-------------------------------------------------------------------------------------------------
133 #define MAX_IPAPOOLSIZE 16UL
134
135
136 //
137 //
138 //for example:
139 //area 1 map 2 times,area 2 map 2times,area 3 map 1 times,total map 2+2+1=5
140 //
141 // map 2t map 2t map 1t
142 // ------ ----
143 // ------ ---- ---
144 // 1 2 3
145 // ------ ---- ------
146 //-----------------------------same client
147 #define MAX_CLIENT_MAP_NUM 8UL
148 //-------------------------------------------------------------------------------------------------
149 // Local Structurs
150 //-------------------------------------------------------------------------------------------------
151
152 struct VIRT_MAP_INFO
153 {
154 MS_U64 virt_addr;
155 MS_U64 length;
156 MS_BOOL bNonCache;
157 MS_U64 Physaddr;
158 };
159 struct IPA_Pool_Init_Param_No_P
160 {
161 MS_U32 heap_id; //in: heap id the pool will be created in
162 MS_U64 pool_name;//in: global identify name for pool to shared between multiple process
163
164 MS_U64 offset_in_heap; //in: pool location in heap
165 MS_U64 len; //in: pool length in heap
166
167 MS_U32 pool_handle_id; //out: generate pool id based on heap specified by heap_id
168 MS_U32 miu; //out: miu id this heap belongs, index from 0.
169 enum IPA_SPACE_TYPE heap_type;//out: return heap type to application
170 MS_S32 error_code; // error code when pool init failed
171
172 MS_U64 heap_length; //out: heap leagth
173 MS_U64 heap_miu_start_offset; //out: heap start offset in miu
174 };
175
176 typedef struct
177 {
178 struct IPA_Pool_Init_Param_No_P Init_Param;
179 MS_BOOL bIsUsed;
180 struct VIRT_MAP_INFO map_info[MAX_CLIENT_MAP_NUM];
181 volatile MS_U32 polling_thread_delete_task_flag;
182 pthread_t pthIPAPollingId;
183 void (*polling_callback)(MS_U32 pool_handle_id,MS_U64 start,MS_U64 length);
184 } IPAPOOL_INFO;
185
186 //-------------------------------------------------------------------------------------------------
187 // Global Variables
188 //-------------------------------------------------------------------------------------------------
189 static MS_S32 _s32FdIPAPool = -1;
190 static pthread_mutex_t _IPA_POOL_Mutex = PTHREAD_MUTEX_INITIALIZER;
191 static IPAPOOL_INFO IPAPool_Info[MAX_IPAPOOLSIZE];
192
193 //-------------------------------------------------------------------------------------------------
194 // Debug Functions
195 //-------------------------------------------------------------------------------------------------
196
197 //-------------------------------------------------------------------------------------------------
198 // Local Functions
199 //-------------------------------------------------------------------------------------------------
_findEmpty_IPA_Pool_Entry(MS_U32 * index)200 static MS_BOOL _findEmpty_IPA_Pool_Entry(MS_U32 *index)
201 {
202 MS_BOOL find = FALSE;
203 MS_U32 i;
204
205 *index = 0;
206 for (i = 0; i < MAX_IPAPOOLSIZE; i++)
207 {
208 if(IPAPool_Info[i].bIsUsed == FALSE)
209 {
210 find = TRUE;
211 *index = i;
212 break;
213 }
214 }
215
216 if(find == FALSE)
217 VPRINTF("Not enough IPAPool, must increase MAX_IPAPOOLSIZE!!\n");
218
219 return find;
220 }
221
222
_findPoolHandleId_InIPA_Pool_Table(MS_U32 pool_handle_id,MS_U32 * index)223 static MS_BOOL _findPoolHandleId_InIPA_Pool_Table(MS_U32 pool_handle_id, MS_U32 *index)
224 {
225 MS_BOOL find = FALSE;
226 MS_U32 i;
227
228 *index = 0;
229 for (i = 0; i < MAX_IPAPOOLSIZE; i++)
230 {
231 if((IPAPool_Info[i].bIsUsed == TRUE) && (IPAPool_Info[i].Init_Param.pool_handle_id == pool_handle_id))
232 {
233 find = TRUE;
234 *index = i;
235 break;
236 }
237 }
238
239 return find;
240 }
241
_findHeapId_InIPA_Pool_Table(struct IPA_Pool_Init_Param * Init_Param,MS_U32 * index)242 static MS_BOOL _findHeapId_InIPA_Pool_Table(struct IPA_Pool_Init_Param * Init_Param,MS_U32 *index)
243 {
244 MS_BOOL find = FALSE;
245 MS_U32 i;
246
247 *index = 0;
248 for (i = 0; i < MAX_IPAPOOLSIZE; i++)
249 {
250 if((IPAPool_Info[i].bIsUsed == TRUE)
251 && (IPAPool_Info[i].Init_Param.heap_id == Init_Param->space_id)
252 &&(!strncmp((char *)(intptr_t)IPAPool_Info[i].Init_Param.pool_name, Init_Param->pool_name,strlen(Init_Param->pool_name)))
253 && (IPAPool_Info[i].Init_Param.offset_in_heap == Init_Param->offset_in_heap)
254 && (IPAPool_Info[i].Init_Param.len == Init_Param->len))
255 {
256 find = TRUE;
257 *index = i;
258 break;
259 }
260 }
261
262 return find;
263 }
264
265 //N.B. This API only for each module debug code use,in each module release code,please do not call it !!!
266 //in:pa value
267 //out:whether in miu/heap/pool,and info about miu/heap/pool,and if in pool whether allocated.
268 //return value:only allocated in pool will return TRUE,otherwise return FALSE.
PA_in_IPA_POOL_info(struct PA_In_IPA_Pool_Param * in_ipa_pool_info)269 MS_BOOL __attribute__((weak)) PA_in_IPA_POOL_info(struct PA_In_IPA_Pool_Param * in_ipa_pool_info)
270 {
271 MS_BOOL ret = FALSE;
272 int res = 0;
273 struct PA_In_IPA_Pool_Args in_ipa_pool_info_args;
274 pthread_mutex_lock(&_IPA_POOL_Mutex);
275 if (_s32FdIPAPool <= 0)//may never open device
276 {
277 if ((_s32FdIPAPool = open("/dev/ipapool", O_RDWR)) < 0)
278 {
279 VPRINTF("open /dev/ipapool fail\n");
280 ret = FALSE;
281 goto PA_in_IPA_POOL_info;
282 }
283
284 memset(IPAPool_Info, 0, sizeof(IPAPOOL_INFO)*MAX_IPAPOOLSIZE);
285 }
286 in_ipa_pool_info_args.PA = in_ipa_pool_info->PA;
287 res = ioctl(_s32FdIPAPool, IPA_POOL_IOC_PA_INFO, &in_ipa_pool_info_args);
288 if (res < 0 || in_ipa_pool_info_args.error_code < 0)
289 {
290 ret = FALSE;//ioctl fail,return false.
291 VPRINTF("ipa error: %s , PA 0x%lx,res=%d ,error_code=0x%x\n",__FUNCTION__, (unsigned long)in_ipa_pool_info_args.PA,res,in_ipa_pool_info_args.error_code);
292 goto PA_in_IPA_POOL_info;
293
294 }
295 VPRINTF(" %s PA:0x%lx pa_state=%d\n",__FUNCTION__, (unsigned long)in_ipa_pool_info_args.PA,in_ipa_pool_info_args.pa_state);
296
297 in_ipa_pool_info->pa_state= in_ipa_pool_info_args.pa_state;
298 in_ipa_pool_info->miu= in_ipa_pool_info_args.miu;
299 if(in_ipa_pool_info->miu < 0)
300 {
301 VPRINTF("ipa error: %s failed, PA 0x%lx,miu=%d\n",__FUNCTION__, (unsigned long)in_ipa_pool_info_args.PA,in_ipa_pool_info_args.miu);
302 in_ipa_pool_info->in_heap = FALSE;
303 in_ipa_pool_info->allocated = FALSE;
304 ret = TRUE;//ioctl success,but not in miu,return TRUE!!!
305 goto PA_in_IPA_POOL_info;
306 }
307 in_ipa_pool_info->in_heap= in_ipa_pool_info_args.in_heap;
308 if(FALSE == in_ipa_pool_info->in_heap)
309 {
310 VPRINTF("ipa error: %s failed, PA 0x%lx,miu=%d,in_heap is FALSE\n",__FUNCTION__, (unsigned long)in_ipa_pool_info_args.PA,in_ipa_pool_info_args.miu);
311 in_ipa_pool_info->allocated = FALSE;
312 ret = TRUE;//ioctl success,but not in heap,return TRUE!!!
313 goto PA_in_IPA_POOL_info;
314 }
315 else
316 {
317 in_ipa_pool_info->space_id= in_ipa_pool_info_args.heap_id;
318 in_ipa_pool_info->space_type= in_ipa_pool_info_args.heap_type;
319 in_ipa_pool_info->space_miu_start_offset= in_ipa_pool_info_args.heap_miu_start_offset;
320 in_ipa_pool_info->space_length= in_ipa_pool_info_args.heap_length;
321 in_ipa_pool_info->pa_offset_in_heap= in_ipa_pool_info_args.pa_offset_in_heap;
322
323 in_ipa_pool_info->allocated = in_ipa_pool_info_args.allocated;
324 if(FALSE == in_ipa_pool_info->allocated)
325 {
326 VPRINTF("ipa error: %s failed, PA 0x%lx,miu=%d,in_ipa_pool_info_args.heap_id=%d,allocated is FALSE\n",__FUNCTION__, (unsigned long)in_ipa_pool_info_args.PA,in_ipa_pool_info_args.miu,in_ipa_pool_info_args.heap_id);
327 ret = TRUE;//ioctl success,but not in pool(not allocated),return TRUE!!!
328 goto PA_in_IPA_POOL_info;
329 }
330 else
331 {
332 //in_ipa_pool_info->pool_handle_id= in_ipa_pool_info_args.pool_handle_id;
333 #if defined (__aarch64__)
334 strcpy((char *)in_ipa_pool_info->pool_name , (char *)in_ipa_pool_info_args.pool_name);
335 #else
336 strcpy((char *)in_ipa_pool_info->pool_name ,(char *)in_ipa_pool_info_args.pool_name);
337 #endif
338 in_ipa_pool_info->pool_len = in_ipa_pool_info_args.pool_len;
339 in_ipa_pool_info->pool_offset_in_heap = in_ipa_pool_info_args.pool_offset_in_heap;
340 in_ipa_pool_info->pa_offset_in_pool = in_ipa_pool_info_args.pa_offset_in_pool;
341 }
342 }
343 ret = TRUE;
344
345 PA_in_IPA_POOL_info:
346
347 pthread_mutex_unlock(&_IPA_POOL_Mutex);
348 return ret;
349 }
350
IN_IPA_POOL_To_PA(struct Pool_To_PA_Param * pool_to_pa_param)351 MS_BOOL __attribute__((weak)) IN_IPA_POOL_To_PA(struct Pool_To_PA_Param * pool_to_pa_param)
352 {
353 MS_BOOL ret = TRUE;
354 struct Pool_To_PA_Args pool_to_pa_args;
355 int res = 0;
356
357 VPRINTF("%s handle_id 0x%x offset_in_pool 0x%lx\n",
358 __FUNCTION__,pool_to_pa_param->pool_handle_id, (unsigned long)pool_to_pa_param->offset_in_pool);
359
360 pthread_mutex_lock(&_IPA_POOL_Mutex);
361 if (_s32FdIPAPool < 0)
362 {
363 ret = FALSE;
364 goto POOL_To_PA_DONE;
365 }
366
367 //input
368 pool_to_pa_args.pool_handle_id = pool_to_pa_param->pool_handle_id;
369 pool_to_pa_args.offset_in_pool = pool_to_pa_param->offset_in_pool;
370
371 res = ioctl(_s32FdIPAPool, IPA_POOL_IOC_POOL_TO_PA, &pool_to_pa_args);
372 if (res < 0 || pool_to_pa_args.error_code != IPAERROR_OK)
373 {
374 VPRINTF("%s fail: pool_handle_id %u, offset 0x%lx, error_code=0x%x res=%d\n",__FUNCTION__, pool_to_pa_param->pool_handle_id,
375 (unsigned long)pool_to_pa_param->offset_in_pool,pool_to_pa_args.error_code,res);
376 ret = FALSE;
377 goto POOL_To_PA_DONE;
378 }
379
380 //output
381 pool_to_pa_param->PA = pool_to_pa_args.PA;
382 pool_to_pa_param->error_code = pool_to_pa_args.error_code;
383 pool_to_pa_param->miu = pool_to_pa_args.miu;
384 pool_to_pa_param->heap_id = pool_to_pa_args.heap_id;
385
386 POOL_To_PA_DONE:
387 pthread_mutex_unlock(&_IPA_POOL_Mutex);
388
389 return ret;
390 }
391
392
393 //-------------------------------------------------------------------------------------------------
394 // Global Functions
395 //-------------------------------------------------------------------------------------------------
396
397 //-------------------------------------------------------------------------------------------------
398 /// System initialzation
399 /// @return TRUE(Success), FALSE(Failure)
400 //-------------------------------------------------------------------------------------------------
MApi_IPA_Pool_Init(struct IPA_Pool_Init_Param * Init_Param)401 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_Init(struct IPA_Pool_Init_Param * Init_Param)
402 {
403 struct IPA_Pool_Init_Args ipa_init_args;
404 MS_U64 u64PhyAddr = 0;
405 MS_BOOL ret = TRUE;
406 MS_U32 idx = 0;
407 int res = 0;
408 //VPRINTF("%s start\n",__FUNCTION__);
409 VPRINTF("%s heap_id %u\n",__FUNCTION__, Init_Param->space_id);
410 pthread_mutex_lock(&_IPA_POOL_Mutex);
411 if (_s32FdIPAPool <= 0)
412 {
413 if ((_s32FdIPAPool = open("/dev/ipapool", O_RDWR)) < 0)
414 {
415 VPRINTF("open /dev/ipapool fail\n");
416 ret = FALSE;
417 goto IPA_POOL_INIT_DONE;
418 }
419
420 memset(IPAPool_Info, 0, sizeof(IPAPOOL_INFO)*MAX_IPAPOOLSIZE);
421 }
422
423
424 //avoid mmap more than one time
425 ret = _findHeapId_InIPA_Pool_Table(Init_Param, &idx);
426 if(ret == TRUE)
427 {
428 //memcpy(Init_Param,IPAPool_Info[idx].Init_Param,sizeof(struct IPA_Pool_Init_Param));
429 Init_Param->space_id = IPAPool_Info[idx].Init_Param.heap_id;
430 Init_Param->pool_name = (char *)(intptr_t)IPAPool_Info[idx].Init_Param.pool_name;
431 Init_Param->offset_in_heap = IPAPool_Info[idx].Init_Param.offset_in_heap;
432 Init_Param->len = IPAPool_Info[idx].Init_Param.len;
433 Init_Param->pool_handle_id = IPAPool_Info[idx].Init_Param.pool_handle_id;
434 Init_Param->miu = IPAPool_Info[idx].Init_Param.miu;
435 Init_Param->space_type = IPAPool_Info[idx].Init_Param.heap_type;
436 Init_Param->error_code = IPAPool_Info[idx].Init_Param.error_code;
437 Init_Param->space_length = IPAPool_Info[idx].Init_Param.heap_length;
438 Init_Param->space_miu_start_offset = IPAPool_Info[idx].Init_Param.heap_miu_start_offset;
439
440 VPRINTF("pool_handle_id %u already init!\n", IPAPool_Info[idx].Init_Param.pool_handle_id);
441 goto IPA_POOL_INIT_DONE;
442 }
443
444 ipa_init_args.heap_id = Init_Param->space_id;
445 #if defined (__aarch64__)
446 strcpy((char *)ipa_init_args.pool_name , Init_Param->pool_name);
447 #else
448 strcpy((char *)ipa_init_args.pool_name ,Init_Param->pool_name);
449 #endif
450 ipa_init_args.offset_in_heap = Init_Param->offset_in_heap;
451 ipa_init_args.len = Init_Param->len;
452 res = ioctl(_s32FdIPAPool, IPA_POOL_IOC_INIT, &ipa_init_args);
453 if (res < 0 || ipa_init_args.error_code != IPAERROR_OK)
454 {
455 VPRINTF("ipa error: ipa init failed, heapid %u error_code %d\n", Init_Param->space_id, ipa_init_args.error_code);
456 ret = FALSE;
457 goto IPA_POOL_INIT_CLOSE;
458 }
459
460 VPRINTF("%s heap_id %u, pool_handle_id %u heap_length %llu\n",
461 __FUNCTION__,Init_Param->space_id, ipa_init_args.pool_handle_id, (long long unsigned int)ipa_init_args.heap_length);
462
463 Init_Param->pool_handle_id = ipa_init_args.pool_handle_id;
464 Init_Param->miu = ipa_init_args.miu;
465 Init_Param->space_type = ipa_init_args.heap_type;
466 Init_Param->error_code = ipa_init_args.error_code;
467 Init_Param->space_length = ipa_init_args.heap_length;
468 Init_Param->space_miu_start_offset = ipa_init_args.heap_miu_start_offset;
469 //VPRINTF("%s before _findEmpty_IPA_Pool_Entry\n",__FUNCTION__);
470 ret = _findEmpty_IPA_Pool_Entry(&idx);
471 //VPRINTF("%s after _findEmpty_IPA_Pool_Entry\n",__FUNCTION__);
472 if(ret == FALSE)
473 {
474 VPRINTF("ipa error: pool_handle_id %u init failed!\n", ipa_init_args.pool_handle_id);
475 goto IPA_POOL_INIT_DONE;
476 }
477 //VPRINTF("%s before _miu_offset_to_phy\n",__FUNCTION__);
478 _miu_offset_to_phy(ipa_init_args.miu, ipa_init_args.heap_miu_start_offset, u64PhyAddr); // get miu base addr
479 //VPRINTF("%s after _miu_offset_to_phy idx=%d ",__FUNCTION__,idx);
480
481
482 #if defined (__aarch64__)//make sure when build no warning.
483 VPRINTF("sizeof(struct IPA_Pool_Init_Param)=%lu\n",sizeof(struct IPA_Pool_Init_Param));
484 #else
485 VPRINTF("sizeof(struct IPA_Pool_Init_Param)=%u\n",sizeof(struct IPA_Pool_Init_Param));
486 #endif
487
488 /* IPA Pool setting*/
489 //VPRINTF("%s before memcpy\n",__FUNCTION__);
490 //memcpy(IPAPool_Info[idx].Init_Param,Init_Param,sizeof(struct IPA_Pool_Init_Param));
491 #if 1
492 //VPRINTF("%s before heap_id\n",__FUNCTION__);
493 IPAPool_Info[idx].Init_Param.heap_id = Init_Param->space_id;
494
495 //VPRINTF("%s before pool_name \n",__FUNCTION__);
496 #if defined (__aarch64__)
497 IPAPool_Info[idx].Init_Param.pool_name = (MS_U64)Init_Param->pool_name;
498 #else
499 IPAPool_Info[idx].Init_Param.pool_name = (MS_U32)Init_Param->pool_name;
500 #endif
501 //VPRINTF("%s before offset \n",__FUNCTION__);
502 IPAPool_Info[idx].Init_Param.offset_in_heap =Init_Param->offset_in_heap;
503 //VPRINTF("%s before len \n",__FUNCTION__);
504 IPAPool_Info[idx].Init_Param.len =Init_Param->len;
505 //VPRINTF("%s before pool_handle_id \n",__FUNCTION__);
506 IPAPool_Info[idx].Init_Param.pool_handle_id =Init_Param->pool_handle_id;
507 //VPRINTF("%s before miu \n",__FUNCTION__);
508 IPAPool_Info[idx].Init_Param.miu =Init_Param->miu;
509 //VPRINTF("%s before heap_type \n",__FUNCTION__);
510 IPAPool_Info[idx].Init_Param.heap_type =Init_Param->space_type;
511 //VPRINTF("%s before error_code \n",__FUNCTION__);
512 IPAPool_Info[idx].Init_Param.error_code =Init_Param->error_code;
513 //VPRINTF("%s before heap_length \n",__FUNCTION__);
514 IPAPool_Info[idx].Init_Param.heap_length =Init_Param->space_length;
515 //VPRINTF("%s before heap_miu_start_offset \n",__FUNCTION__);
516 IPAPool_Info[idx].Init_Param.heap_miu_start_offset =Init_Param->space_miu_start_offset;
517 #endif
518
519 //VPRINTF("%s after memcpy\n",__FUNCTION__);
520 IPAPool_Info[idx].bIsUsed = TRUE;
521 IPAPool_Info[idx].pthIPAPollingId = -1;//in init,no polling id yet.
522 IPAPool_Info[idx].polling_thread_delete_task_flag = 0;
523
524 VPRINTF("%s heap_id %u pool_handle_id %u miu %u offset 0x%lx len 0x%lx idx=%u\n",__FUNCTION__,
525 Init_Param->space_id, Init_Param->pool_handle_id, Init_Param->miu, (unsigned long)Init_Param->offset_in_heap, (unsigned long)Init_Param->len,idx);
526 pthread_mutex_unlock(&_IPA_POOL_Mutex);
527 //VPRINTF("%s before return %d\n",__FUNCTION__,ret);
528 return ret;
529
530 IPA_POOL_INIT_CLOSE:
531 //VPRINTF("%s before close\n",__FUNCTION__);
532 close(_s32FdIPAPool);
533 //VPRINTF("%s after close\n",__FUNCTION__);
534 IPA_POOL_INIT_DONE:
535 //VPRINTF("%s after IPA_POOL_INIT_DONE ret=%d\n",__FUNCTION__,ret);
536 pthread_mutex_unlock(&_IPA_POOL_Mutex);
537
538 return ret;
539 }
540
541 //MS_U32 u32flag. Special Flag for customer mem allocation
MApi_IPA_Pool_GetMem(struct IPA_Pool_GetMem_Param * get_param)542 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_GetMem(struct IPA_Pool_GetMem_Param * get_param)
543 {
544 MS_BOOL ret = TRUE;
545 struct IPA_Pool_Alloc_Args ipa_alloc_args;
546 int res = 0;
547
548 //VPRINTF("%s handle_id 0x%x length 0x%lx\n",__FUNCTION__,
549 // get_param->pool_handle_id, (unsigned long)get_param->length);
550
551 pthread_mutex_lock(&_IPA_POOL_Mutex);
552 if (_s32FdIPAPool < 0)
553 {
554 ret = FALSE;
555 goto IPA_POOL_GETMEM_DONE;
556 }
557
558 ipa_alloc_args.pool_handle_id = get_param->pool_handle_id;
559 ipa_alloc_args.offset_in_pool = get_param->offset_in_pool;
560 ipa_alloc_args.length = get_param->length;
561 ipa_alloc_args.timeout = 0;// 0 means if fail ,will not try again
562 VPRINTF("%s %d pool_handle_id 0x%x [offset_in_pool ,length]=[0x%lx,0x%lx]\n",__FUNCTION__,__LINE__,
563 ipa_alloc_args.pool_handle_id,(unsigned long)ipa_alloc_args.offset_in_pool, (unsigned long)ipa_alloc_args.length);
564 res = ioctl(_s32FdIPAPool, IPA_POOL_IOC_ALLOC, &ipa_alloc_args);
565 if (res < 0 || ipa_alloc_args.error_code != IPAERROR_OK)
566 {
567 VPRINTF("%s fail: pool_handle_id %u, offset 0x%lx, len 0x%lx ipa_alloc_args.error_code=0x%x res=%d\n",__FUNCTION__, get_param->pool_handle_id,
568 (unsigned long)get_param->offset_in_pool, (unsigned long)get_param->length,ipa_alloc_args.error_code,res);
569 ret = FALSE;
570 goto IPA_POOL_GETMEM_DONE;
571 }
572
573 get_param->error_code = ipa_alloc_args.error_code;
574
575 IPA_POOL_GETMEM_DONE:
576 pthread_mutex_unlock(&_IPA_POOL_Mutex);
577
578 return ret;
579 }
580
MApi_IPA_Pool_PutMem(struct IPA_Pool_PutMem_Param * put_param)581 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_PutMem(struct IPA_Pool_PutMem_Param * put_param)
582 {
583 MS_BOOL ret = TRUE;
584 struct IPA_Pool_free_Args ipa_free_args;
585
586 pthread_mutex_lock(&_IPA_POOL_Mutex);
587 if(_s32FdIPAPool < 0)
588 {
589 ret = FALSE;
590 goto IPA_POOL_PUTMEM_DONE;
591 }
592
593 ipa_free_args.pool_handle_id = put_param->pool_handle_id;
594 ipa_free_args.offset_in_pool = put_param->offset_in_pool;
595 ipa_free_args.length = put_param->length;
596 VPRINTF("%s %d pool_handle_id 0x%x [offset_in_pool,length]=[0x%lx,0x%lx]\n", __FUNCTION__,__LINE__,
597 ipa_free_args.pool_handle_id, (unsigned long)ipa_free_args.offset_in_pool, (unsigned long)ipa_free_args.length);
598
599 if(ioctl(_s32FdIPAPool, IPA_POOL_IOC_FREE, &ipa_free_args))
600 {
601 VPRINTF("%s fail: pool_handle_id 0x%x, offset 0x%lx, len 0x%lx\n",__FUNCTION__,
602 put_param->pool_handle_id, (unsigned long)put_param->offset_in_pool,(unsigned long)put_param->length);
603 ret = FALSE;
604 goto IPA_POOL_PUTMEM_DONE;
605 }
606
607 IPA_POOL_PUTMEM_DONE:
608 pthread_mutex_unlock(&_IPA_POOL_Mutex);
609
610 return ret;
611 }
612
MApi_IPA_Pool_Release(MS_U32 pool_handle_id)613 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_Release(MS_U32 pool_handle_id)
614 {
615 MS_BOOL ret = TRUE;
616 struct IPA_Pool_Deinit_Args deinit_args;
617 struct IPA_Pool_Unmap_Args unmap_args;
618
619 MS_U32 idx = 0;
620 int res = 0,i=0;
621
622 VPRINTF("%s handle_id %u\n",__FUNCTION__, pool_handle_id);
623 pthread_mutex_lock(&_IPA_POOL_Mutex);
624 if (_s32FdIPAPool < 0)
625 {
626 ret = FALSE;
627 goto IPA_POOL_RELEASE_DONE;
628 }
629
630 ret = _findPoolHandleId_InIPA_Pool_Table(pool_handle_id, &idx);
631 if(ret == FALSE)
632 {
633 VPRINTF("pool_handle_id %u _findPoolHandleId_InIPA_Pool_Table fail\n", pool_handle_id);
634 goto IPA_POOL_RELEASE_DONE;
635 }
636
637 for(i=0;i<MAX_CLIENT_MAP_NUM;i++)
638 {
639 // tmp_map_info
640 if((0 !=IPAPool_Info[idx].map_info[i].virt_addr)
641 && (0 != IPAPool_Info[idx].map_info[i].length))
642 {
643 unmap_args.virt_addr = IPAPool_Info[idx].map_info[i].virt_addr;
644 unmap_args.length = IPAPool_Info[idx].map_info[i].length;
645
646 MsOS_MPool_Remove_PA2VARange(IPAPool_Info[idx].map_info[i].Physaddr, IPAPool_Info[idx].map_info[i].virt_addr, IPAPool_Info[idx].map_info[i].length, IPAPool_Info[idx].map_info[i].bNonCache);
647 res = ioctl(_s32FdIPAPool, IPA_POOL_IOC_UNMAP, &unmap_args);
648 if (res < 0)
649 {
650 //give printf,but not end.
651 VPRINTF("error: pool_handle_id %u unmap failed\n", pool_handle_id);
652 }
653
654 IPAPool_Info[idx].map_info[i].virt_addr = 0;
655 IPAPool_Info[idx].map_info[i].length = 0;
656 }
657 }
658
659 IPAPool_Info[idx].bIsUsed = FALSE;
660 IPAPool_Info[idx].Init_Param.pool_handle_id = 0;
661
662 IPAPool_Info[idx].polling_thread_delete_task_flag = 2; //request thread to exit
663 deinit_args.pool_handle_id = pool_handle_id;
664
665 if (ioctl(_s32FdIPAPool, IPA_POOL_IOC_DEINIT, &deinit_args))
666 {
667 VPRINTF("pool_handle_id %u deinit fail\n", pool_handle_id);
668 ret = FALSE;
669 goto IPA_POOL_RELEASE_DONE;
670 }
671 ret = TRUE; //not find the pool hand id
672
673 //after deinit, if have polling thread,should delete task
674 if(IPAPool_Info[idx].pthIPAPollingId != -1)
675 {
676 #if 0//no need this while,for later pthread_join + pthread_cancel will wait for set delete_task_flag.
677 while(1)
678 {
679 if(1 == IPAPool_Info[idx].polling_thread_delete_task_flag)
680 break;
681 }
682 #endif
683
684 //N.B. here we do not directly use MsOS_DeleteTask but use pthread_join + pthread_cancel,
685 //For in MsOS_DeleteTask,first use pthread_cancel and then use pthread_join and that will
686 //cause hang.
687 //MsOS_DeleteTask (IPAPool_Info[idx].pthIPAPollingId);//delete polling task
688 pthread_join(IPAPool_Info[idx].pthIPAPollingId, NULL);
689
690 #if 0
691 //build SN lib can find pthread_cancel,
692 //but build AN lib,can not find pthread_cancel,
693 //in fact only need pthread_join,no need pthread_cancel.
694 pthread_cancel(IPAPool_Info[idx].pthIPAPollingId);//delete polling task
695 #endif
696
697 if(1 != IPAPool_Info[idx].polling_thread_delete_task_flag)
698 {
699 VPRINTF("error !!!!!! after pthread_join polling_thread_delete_task_flag is not 1!!! idx=%u IPAPool_Info[%d].polling_thread_delete_task_flag=%u\n",idx,idx,IPAPool_Info[idx].polling_thread_delete_task_flag);
700 ret = FALSE;
701 }
702
703 }
704
705
706 IPA_POOL_RELEASE_DONE:
707 pthread_mutex_unlock(&_IPA_POOL_Mutex);
708 return ret;
709 }
710
711 //allow a same input [pool_handle_id, offset_in_pool, length, cache_type] map for more than once,
712 //and get different result output [virt_addr]
MApi_IPA_Pool_MapUserVA(struct IPA_Pool_Map_Param * map_param)713 static MS_BOOL MApi_IPA_Pool_MapUserVA(struct IPA_Pool_Map_Param * map_param)
714 {
715 MS_BOOL ret = TRUE;
716 int res = 0;
717 struct IPA_Pool_Map_Args map_args;
718 MS_U32 idx = 0;
719 VPRINTF("%s pool_handle_id %u, offset_in_pool 0x%lx, len 0x%lx, cache_type %u\n",__FUNCTION__, map_param->pool_handle_id,
720 (unsigned long)map_param->offset_in_pool, (unsigned long)map_param->length,map_param->cache_type);
721 pthread_mutex_lock(&_IPA_POOL_Mutex);
722 if (_s32FdIPAPool < 0)
723 {
724 ret = FALSE;
725 goto IPA_POOL_MapUserVA_DONE;
726 }
727
728 if(0 == map_param->length)
729 {
730 VPRINTF("%s error, len 0x%lx is invalid\n",__FUNCTION__, (unsigned long)map_param->length);
731 ret = FALSE;
732 goto IPA_POOL_MapUserVA_DONE;
733 }
734
735 map_args.pool_handle_id = map_param->pool_handle_id;
736 map_args.offset_in_pool = map_param->offset_in_pool;
737 map_args.length = map_param->length;
738 map_args.map_va_type = map_param->cache_type;
739
740 res = ioctl(_s32FdIPAPool, IPA_POOL_IOC_MAP, &map_args);
741 //VPRINTF("MApi_IPA_Pool_MapUserVA after ioctl\n");
742 if (res < 0 || map_args.error_code != IPAERROR_OK)
743 {
744 VPRINTF("%s fail: pool_handle_id %u, offset_in_pool 0x%lx, len 0x%lx, cache_type %u\n",__FUNCTION__, map_param->pool_handle_id,
745 (unsigned long)map_param->offset_in_pool, (unsigned long)map_param->length,map_param->cache_type);
746 ret = FALSE;
747 goto IPA_POOL_MapUserVA_DONE;
748 }
749 //VPRINTF("MApi_IPA_Pool_MapUserVA before virt_addr\n");
750 map_param->virt_addr = map_args.virt_addr;
751 map_param->error_code = map_args.error_code;
752 //VPRINTF("MApi_IPA_Pool_MapUserVA before _findPoolHandleId_InIPA_Pool_Table\n");
753
754 ret = _findPoolHandleId_InIPA_Pool_Table(map_param->pool_handle_id, &idx);
755 //VPRINTF("MApi_IPA_Pool_MapUserVA after _findPoolHandleId_InIPA_Pool_Table\n");
756 if(ret == TRUE)
757 {
758 int i=0;
759 //VPRINTF("MApi_IPA_Pool_MapUserVA before for\n");
760 for(i=0;i<MAX_CLIENT_MAP_NUM;i++)
761 {
762 //VPRINTF("MApi_IPA_Pool_MapUserVA before if\n");
763 if((0 == IPAPool_Info[idx].map_info[i].virt_addr)
764 || (0 == IPAPool_Info[idx].map_info[i].length))
765 {
766 //VPRINTF("MApi_IPA_Pool_MapUserVA inside if\n");
767 IPAPool_Info[idx].map_info[i].virt_addr = map_args.virt_addr;
768 IPAPool_Info[idx].map_info[i].length = map_args.length;
769 //VPRINTF("MApi_IPA_Pool_MapUserVA before _miu_offset_to_phy\n");
770 _miu_offset_to_phy(IPAPool_Info[idx].Init_Param.miu, IPAPool_Info[idx].Init_Param.offset_in_heap + map_param->offset_in_pool, IPAPool_Info[idx].map_info[i].Physaddr); // get miu base addr
771 if(IPA_VA_CACHE_NONE_CACHE_Param == map_param->cache_type)
772 IPAPool_Info[idx].map_info[i].bNonCache = TRUE;
773 else
774 IPAPool_Info[idx].map_info[i].bNonCache = FALSE;
775 //VPRINTF("MApi_IPA_Pool_MapUserVA before MsOS_MPool_Add_PA2VARange\n");
776 MsOS_MPool_Add_PA2VARange(IPAPool_Info[idx].map_info[i].Physaddr, IPAPool_Info[idx].map_info[i].virt_addr, IPAPool_Info[idx].map_info[i].length, IPAPool_Info[idx].map_info[i].bNonCache);
777 break;
778 }
779 }
780 //VPRINTF("MApi_IPA_Pool_MapUserVA after for\n");
781 if(MAX_CLIENT_MAP_NUM == i)
782 {
783 VPRINTF("print important log for 3 times :a same client mapped %lu times,unable map once more!!!!\n", MAX_CLIENT_MAP_NUM);
784 VPRINTF("print important log for 3 times :a same client mapped %lu times,unable map once more!!!!\n", MAX_CLIENT_MAP_NUM);
785 VPRINTF("print important log for 3 times :a same client mapped %lu times,unable map once more!!!!\n", MAX_CLIENT_MAP_NUM);
786 //here later can add code for dump map info
787 ret = FALSE;
788 goto IPA_POOL_MapUserVA_DONE;
789 }
790 }
791 //VPRINTF("MApi_IPA_Pool_MapUserVA before IPA_POOL_MapUserVA_DONE\n");
792
793 IPA_POOL_MapUserVA_DONE:
794 //VPRINTF("MApi_IPA_Pool_MapUserVA after IPA_POOL_MapUserVA_DONE\n");
795 pthread_mutex_unlock(&_IPA_POOL_Mutex);
796 return ret;
797 }
798
MApi_IPA_Pool_MapVA(struct IPA_Pool_Map_Param * map_param)799 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_MapVA(struct IPA_Pool_Map_Param * map_param)
800 {
801 return MApi_IPA_Pool_MapUserVA(map_param);
802 }
803
MApi_IPA_Pool_UnmapUserVA(struct IPA_Pool_Unmap_Param * unmap_param)804 static void MApi_IPA_Pool_UnmapUserVA(struct IPA_Pool_Unmap_Param * unmap_param)
805 {
806 MS_BOOL ret = TRUE;
807 int res = 0;
808 int i=0,idx=0,find_virt_info_i=-1,find_virt_info_idx=-1;
809 MS_BOOL find_virt_info = FALSE;
810 struct IPA_Pool_Unmap_Args unmap_args;
811 VPRINTF("%s virt_addr 0x%lx, len 0x%lx \n",__FUNCTION__,
812 (unsigned long)unmap_param->virt_addr, (unsigned long)unmap_param->length);
813 pthread_mutex_lock(&_IPA_POOL_Mutex);
814 if (_s32FdIPAPool < 0)
815 {
816 ret = FALSE;
817 goto IPA_POOL_UnmapUserVA_DONE;
818 }
819 for(idx=0;idx < MAX_IPAPOOLSIZE;idx++)
820 {
821 if(TRUE == IPAPool_Info[idx].bIsUsed)
822 {
823 for(i=0;i<MAX_CLIENT_MAP_NUM;i++)
824 {
825 if((unmap_param->virt_addr == IPAPool_Info[idx].map_info[i].virt_addr)
826 && (unmap_param->length == IPAPool_Info[idx].map_info[i].length))
827 {
828 find_virt_info = TRUE;
829 find_virt_info_idx = idx;
830 find_virt_info_i = i;
831 }
832 }
833 }
834 }
835 if(FALSE == find_virt_info)
836 {
837 VPRINTF("print important log for 3 times :map and unmap area should be strict equal !!!! virt_addr=0x%lx,length=0x%lx\n", (unsigned long)unmap_param->virt_addr,(unsigned long)unmap_param->length);
838 VPRINTF("print important log for 3 times :map and unmap area should be strict equal !!!! virt_addr=0x%lx,length=0x%lx\n", (unsigned long)unmap_param->virt_addr,(unsigned long)unmap_param->length);
839 VPRINTF("print important log for 3 times :map and unmap area should be strict equal !!!! virt_addr=0x%lx,length=0x%lx\n", (unsigned long)unmap_param->virt_addr,(unsigned long)unmap_param->length);
840 //later will add some debug code
841 ret = FALSE;
842 goto IPA_POOL_UnmapUserVA_DONE;
843 }
844 unmap_args.virt_addr = unmap_param->virt_addr;
845 unmap_args.length = unmap_param->length;
846 MsOS_MPool_Remove_PA2VARange(IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].Physaddr, IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].virt_addr, IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].length, IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].bNonCache);
847 res = ioctl(_s32FdIPAPool,IPA_POOL_IOC_UNMAP,&unmap_args);
848 if (res < 0)
849 {
850 VPRINTF("%s fail: virt_addr 0x%lx, len 0x%lx \n",__FUNCTION__,
851 (unsigned long)unmap_param->virt_addr, (unsigned long)unmap_param->length);
852 ret = FALSE;
853 goto IPA_POOL_UnmapUserVA_DONE;
854 }
855 IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].virt_addr = 0;
856 IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].length = 0;
857
858 IPA_POOL_UnmapUserVA_DONE:
859 pthread_mutex_unlock(&_IPA_POOL_Mutex);
860
861 return;
862 }
863
MApi_IPA_Pool_UnmapVA(struct IPA_Pool_Unmap_Param * unmap_param)864 void __attribute__((weak)) MApi_IPA_Pool_UnmapVA(struct IPA_Pool_Unmap_Param * unmap_param)
865 {
866 return MApi_IPA_Pool_UnmapUserVA(unmap_param);
867 }
868
MApi_IPA_Pool_DCacheFlush(struct IPA_Pool_DCacheFlush_Param * dcache_flush_param)869 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_DCacheFlush(struct IPA_Pool_DCacheFlush_Param* dcache_flush_param)
870 {
871 MS_BOOL ret = TRUE;
872 int res = 0;
873 struct IPA_Pool_DCacheFlush_Args dcache_flush_args;
874 VPRINTF("%s virt_addr 0x%lx, length 0x%lx flush_type 0x%x\n",__FUNCTION__,
875 (unsigned long)dcache_flush_param->virt_addr, (unsigned long)dcache_flush_param->length, dcache_flush_param->flush_type);
876 pthread_mutex_lock(&_IPA_POOL_Mutex);
877 if (_s32FdIPAPool < 0)
878 {
879 ret = FALSE;
880 goto IPA_POOL_DCacheFlush_DONE;
881 }
882
883 dcache_flush_args.virt_addr = dcache_flush_param->virt_addr;
884 dcache_flush_args.length = dcache_flush_param->length;
885 dcache_flush_args.flush_type = dcache_flush_param->flush_type;
886 res = ioctl(_s32FdIPAPool,IPA_POOL_IOC_FLUSH,&dcache_flush_args);
887 if (res < 0)
888 {
889 VPRINTF("%s fail: virt_addr 0x%lx, length 0x%lx flush_type 0x%x\n",__FUNCTION__,
890 (unsigned long)dcache_flush_param->virt_addr, (unsigned long)dcache_flush_param->length, dcache_flush_param->flush_type);
891 ret = FALSE;
892 goto IPA_POOL_DCacheFlush_DONE;
893 }
894
895 IPA_POOL_DCacheFlush_DONE:
896 pthread_mutex_unlock(&_IPA_POOL_Mutex);
897 return ret;
898 }
899
MApi_IPA_Pool_HEAP_ATTR(struct IPA_Pool_Heap_Attr_Param * heap_attr_param)900 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_HEAP_ATTR(struct IPA_Pool_Heap_Attr_Param* heap_attr_param)
901 {
902 MS_BOOL ret = TRUE;
903 int res = 0;
904 struct IPA_Pool_Heap_Attr heap_attr_args;
905 VPRINTF("%s heap_id 0x%x\n",__FUNCTION__, heap_attr_param->heap_id);
906 pthread_mutex_lock(&_IPA_POOL_Mutex);
907 if (_s32FdIPAPool < 0)
908 {
909 ret = FALSE;
910 goto IPA_POOL_HEAP_ATTR_DONE;
911 }
912
913 heap_attr_args.heap_id = heap_attr_param->heap_id;
914 res = ioctl(_s32FdIPAPool,IPA_POOL_IOC_HEAP_ATTR,&heap_attr_args);
915 if (res < 0 || heap_attr_args.error_code != IPAERROR_OK)
916 {
917 VPRINTF("%s fail: heap_id 0x%x\n",__FUNCTION__,heap_attr_param->heap_id);
918 ret = FALSE;
919 goto IPA_POOL_HEAP_ATTR_DONE;
920 }
921 memcpy(heap_attr_param->name,heap_attr_args.name,IPAPOOL_HEAP_NAME_MAX_LEN);
922 heap_attr_param->heap_miu_start_offset = heap_attr_args.heap_miu_start_offset;
923 heap_attr_param->heap_length = heap_attr_args.heap_length;
924 heap_attr_param->miu = heap_attr_args.miu;
925 heap_attr_param->heap_type = heap_attr_args.heap_type;
926 heap_attr_param->error_code = heap_attr_args.error_code;
927
928 IPA_POOL_HEAP_ATTR_DONE:
929 pthread_mutex_unlock(&_IPA_POOL_Mutex);
930 return ret;
931 }
932
MApi_IPA_Pool_GETIPCHANDLE(struct IPA_Pool_GetIpcHandle_Param * getipchandle_param)933 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_GETIPCHANDLE(struct IPA_Pool_GetIpcHandle_Param* getipchandle_param)
934 {
935 MS_BOOL ret = TRUE;
936 int res = 0;
937 struct IPA_Pool_GetIpcHandle_Args getipchandle_args;
938 VPRINTF("%s pool_handle_id 0x%x\n",__FUNCTION__, getipchandle_param->pool_handle_id);
939 pthread_mutex_lock(&_IPA_POOL_Mutex);
940 if (_s32FdIPAPool < 0)
941 {
942 VPRINTF("MApi_IPA_Pool_GETIPCHANDLE fail pool_handle_id=0x%x, _s32FdIPAPool=%d \n", getipchandle_param->pool_handle_id,_s32FdIPAPool);
943 ret = FALSE;
944 goto IPA_POOL_GETIPCHANDLE_DONE;
945 }
946
947 getipchandle_args.pool_handle_id = getipchandle_param->pool_handle_id;
948 res = ioctl(_s32FdIPAPool,IPA_POOL_IOC_GETIPCHANDLE,&getipchandle_args);
949 if (res < 0 || getipchandle_args.error_code != IPAERROR_OK)
950 {
951 VPRINTF("%s fail: pool_handle_id 0x%x\n",__FUNCTION__,getipchandle_param->pool_handle_id);
952 ret = FALSE;
953 goto IPA_POOL_GETIPCHANDLE_DONE;
954 }
955 getipchandle_param->ipc_handle_id = getipchandle_args.ipc_handle_id;
956 getipchandle_param->error_code = getipchandle_args.error_code;
957
958 IPA_POOL_GETIPCHANDLE_DONE:
959 pthread_mutex_unlock(&_IPA_POOL_Mutex);
960 return ret;
961 }
962
MApi_IPA_Pool_InstallIpcHandle(struct IPA_Pool_InstallIpcHandle_Param * installipchandle_param)963 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_InstallIpcHandle(struct IPA_Pool_InstallIpcHandle_Param* installipchandle_param)
964 {
965 MS_BOOL ret = TRUE;
966 int res = 0;
967 struct IPA_Pool_InstallIpcHandle_Args installipchandle_args;
968 VPRINTF("%s ipc_handle_id 0x%x\n",__FUNCTION__, installipchandle_param->ipc_handle_id);
969 pthread_mutex_lock(&_IPA_POOL_Mutex);
970 if (_s32FdIPAPool < 0)
971 {
972 VPRINTF("%s ipc_handle_id=0x%x, _s32FdIPAPool=%d \n",__FUNCTION__, installipchandle_param->ipc_handle_id,_s32FdIPAPool);
973 //this process may not open ipapool yet,need we open for this process.
974 if ((_s32FdIPAPool = open("/dev/ipapool", O_RDWR)) < 0)
975 {
976 VPRINTF("open /dev/ipapool fail ipc_handle_id=0x%x, _s32FdIPAPool=%d\n", installipchandle_param->ipc_handle_id,_s32FdIPAPool);
977 ret = FALSE;
978 goto IPA_POOL_InstallIpcHandle_DONE;
979 }
980
981 memset(IPAPool_Info, 0, sizeof(IPAPOOL_INFO)*MAX_IPAPOOLSIZE);
982
983 }
984
985 installipchandle_args.ipc_handle_id = installipchandle_param->ipc_handle_id;
986 // VPRINTF("MApi_IPA_Pool_InstallIpcHandle ipc_handle_id=0x%x debug will ioctl\n", installipchandle_param->ipc_handle_id);
987 res = ioctl(_s32FdIPAPool,IPA_POOL_IOC_INSTALLIPCHANDLE,&installipchandle_args);
988 // VPRINTF("MApi_IPA_Pool_InstallIpcHandle ipc_handle_id=0x%x debug after ioctl res=%d\n", installipchandle_param->ipc_handle_id,res);
989
990 if (res < 0 || installipchandle_args.error_code != IPAERROR_OK)
991 {
992 VPRINTF("%s fail: heap_id 0x%x\n",__FUNCTION__,installipchandle_param->ipc_handle_id);
993 ret = FALSE;
994 goto IPA_POOL_InstallIpcHandle_DONE;
995 }
996 installipchandle_param->pool_handle_id = installipchandle_args.pool_handle_id;
997 installipchandle_param->error_code = installipchandle_args.error_code;
998
999 IPA_POOL_InstallIpcHandle_DONE:
1000 pthread_mutex_unlock(&_IPA_POOL_Mutex);
1001 return ret;
1002 }
1003
1004 //unit of timeout is millisecond.
MApi_IPA_Pool_GetMem_Timeout(struct IPA_Pool_GetMem_Param * get_param,MS_U32 timeout_ms)1005 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_GetMem_Timeout(struct IPA_Pool_GetMem_Param* get_param,MS_U32 timeout_ms)
1006 {
1007 MS_BOOL ret = TRUE;
1008 struct IPA_Pool_Alloc_Args ipa_alloc_args;
1009 int res = 0;
1010
1011 pthread_mutex_lock(&_IPA_POOL_Mutex);
1012 if (_s32FdIPAPool < 0)
1013 {
1014 ret = FALSE;
1015 goto IPA_POOL_GETMEM_DONE;
1016 }
1017
1018 ipa_alloc_args.pool_handle_id = get_param->pool_handle_id;
1019 ipa_alloc_args.offset_in_pool = get_param->offset_in_pool;
1020 ipa_alloc_args.length = get_param->length;
1021
1022 ipa_alloc_args.timeout = timeout_ms;
1023
1024 VPRINTF("%s %d pool_handle_id 0x%x [offset_in_pool,length]= [0x%lx,0x%lx] timeout 0x%x\n", __FUNCTION__,__LINE__,
1025 ipa_alloc_args.pool_handle_id, (unsigned long)ipa_alloc_args.offset_in_pool,(unsigned long)ipa_alloc_args.length,timeout_ms);
1026
1027 res = ioctl(_s32FdIPAPool, IPA_POOL_IOC_ALLOC, &ipa_alloc_args);
1028 if (res < 0 || ipa_alloc_args.error_code != IPAERROR_OK)
1029 {
1030 MS_U32 each_delay_ms = 50;//empirical value in our test.
1031 MS_U32 now_delay_ms=0;
1032 while(1)
1033 {
1034 // delay and try again
1035 pthread_mutex_unlock(&_IPA_POOL_Mutex);
1036
1037 VPRINTF("%s:%d each_delay_ms=%u, delay and try alloc again now_delay_ms=%u\n",__FUNCTION__,__LINE__,each_delay_ms,now_delay_ms);
1038
1039 ipa_alloc_args.timeout = 0;//into kernel will not consider timeout again
1040 MsOS_DelayTask(each_delay_ms);
1041 pthread_mutex_lock(&_IPA_POOL_Mutex);
1042 res = ioctl(_s32FdIPAPool, IPA_POOL_IOC_ALLOC, &ipa_alloc_args);
1043 if ((res == 0) && (ipa_alloc_args.error_code == IPAERROR_OK))
1044 break;
1045 now_delay_ms += each_delay_ms;
1046 if(now_delay_ms >= timeout_ms)
1047 break;
1048 }
1049 if (res < 0 || ipa_alloc_args.error_code != IPAERROR_OK)
1050 {
1051 VPRINTF("ipa pool get memory fail: pool_handle_id %u, offset 0x%lx, len 0x%lx ipa_alloc_args.error_code=0x%x ipa_alloc_args.timeout=%u res=%d\n", get_param->pool_handle_id,
1052 (unsigned long)get_param->offset_in_pool, (unsigned long)get_param->length,ipa_alloc_args.error_code,ipa_alloc_args.timeout,res);
1053 ret = FALSE;
1054 goto IPA_POOL_GETMEM_DONE;
1055 }
1056 }
1057
1058 get_param->error_code = ipa_alloc_args.error_code;
1059
1060 IPA_POOL_GETMEM_DONE:
1061 pthread_mutex_unlock(&_IPA_POOL_Mutex);
1062
1063 return ret;
1064
1065 }
1066
IPA_Pool_Polling_Task(void * argc)1067 void *__attribute__((weak)) IPA_Pool_Polling_Task(void *argc)
1068 {
1069 MS_BOOL ret = TRUE;
1070 MS_U32 idx = 0;
1071 struct IPA_Pool_Event_Args pool_event_args;
1072 MS_U32 pool_handle_id = (MS_U32)(intptr_t)(argc);
1073 VPRINTF("%s %d pool_handle_id=%u,argc=%p\n",__FUNCTION__,__LINE__,pool_handle_id,argc);
1074
1075 pthread_mutex_lock(&_IPA_POOL_Mutex);
1076 if (_s32FdIPAPool < 0)
1077 {
1078 VPRINTF("%s fail \n",__FUNCTION__);
1079 ret = FALSE;
1080 pthread_mutex_unlock(&_IPA_POOL_Mutex);
1081 return NULL;
1082 }
1083 pool_event_args.pool_handle_id = pool_handle_id;
1084 VPRINTF("%s %d pool_event_args.pool_handle_id=%u\n",__FUNCTION__,__LINE__,pool_event_args.pool_handle_id);
1085
1086 ret = _findPoolHandleId_InIPA_Pool_Table(pool_event_args.pool_handle_id, &idx);
1087
1088 pthread_mutex_unlock(&_IPA_POOL_Mutex);
1089
1090 if(ret == FALSE)
1091 {
1092 VPRINTF("%s fail not find in pool table\n",__FUNCTION__);
1093 return NULL;
1094 }
1095 IPAPool_Info[idx].polling_thread_delete_task_flag = 0;
1096 VPRINTF("%s %d set for idx=%u\n",__FUNCTION__,__LINE__,idx);
1097
1098 while(1)
1099 {
1100 struct pollfd fds;
1101 VPRINTF("%s %d\n",__FUNCTION__,__LINE__);
1102 if(IPAPool_Info[idx].polling_thread_delete_task_flag)
1103 {
1104 VPRINTF("%s %d\n",__FUNCTION__,__LINE__);
1105 break; //exit this thread
1106 }
1107 fds.fd = pool_handle_id;
1108 fds.events = POLLIN;
1109 VPRINTF("%s %d\n",__FUNCTION__,__LINE__);
1110 if ((ret=poll(&fds, 1, -1)) < 0)
1111 {
1112 VPRINTF("%s %d fail\n",__FUNCTION__,__LINE__);
1113 break;
1114 }
1115
1116 if(ret==0)
1117 {
1118 VPRINTF("%s %d\n",__FUNCTION__,__LINE__);
1119 continue;
1120 }
1121
1122 if (fds.revents&(POLLHUP | POLLERR |POLLNVAL))
1123 {
1124 VPRINTF("%s %d\n",__FUNCTION__,__LINE__);
1125 break;
1126 }
1127 if (fds.revents&POLLIN)
1128 {
1129 VPRINTF("%s %d\n",__FUNCTION__,__LINE__);
1130 memset(&pool_event_args,0,sizeof(struct IPA_Pool_Event_Args));
1131 pool_event_args.pool_handle_id = pool_handle_id;
1132 ret=read(fds.fd, &pool_event_args, sizeof(struct IPA_Pool_Event_Args));
1133 VPRINTF("%s %d\n",__FUNCTION__,__LINE__);
1134 if (sizeof(struct IPA_Pool_Event_Args)!=ret)
1135 {
1136 VPRINTF("%s %d\n",__FUNCTION__,__LINE__);
1137 continue;
1138 }
1139 if(IPA_EVENT_CONFLICT == pool_event_args.event)
1140 {
1141 //invoke callback corresponding to that pool event
1142 VPRINTF("%s %d pool_handle_id=%u start=0x%lx,length=0x%lx\n",__FUNCTION__,__LINE__,pool_event_args.pool_handle_id,(unsigned long)pool_event_args.start,(unsigned long)pool_event_args.length);
1143 //after read,may change pool_handle_id,so set pool_handle_id again.
1144 pool_event_args.pool_handle_id = pool_handle_id;
1145 VPRINTF("%s %d pool_handle_id=%u start=0x%lx,length=0x%lx\n",__FUNCTION__,__LINE__,pool_event_args.pool_handle_id,(unsigned long)pool_event_args.start,(unsigned long)pool_event_args.length);
1146 IPAPool_Info[idx].polling_callback(pool_event_args.pool_handle_id,
1147 pool_event_args.start,pool_event_args.length);
1148 VPRINTF("%s %d\n",__FUNCTION__,__LINE__);
1149 }
1150 }
1151 }
1152
1153 //before return ,set this flag.And this flag will be checked in MApi_IPA_Pool_Release.
1154 IPAPool_Info[idx].polling_thread_delete_task_flag = 1;
1155 VPRINTF("%s %d idx=%u\n",__FUNCTION__,__LINE__,idx);
1156 return NULL;
1157
1158 }
1159
1160 //suggest this API be invoked after MApi_IPA_Pool_Init.
MApi_IPA_Pool_Notify(struct IPA_Pool_Polling_Param * polling_param)1161 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_Notify(struct IPA_Pool_Polling_Param *polling_param)
1162 {
1163 MS_BOOL ret = TRUE;
1164 pthread_t pthIPAPollingId = -1;
1165 MS_U32 idx = 0;
1166 int pthread_res = -1;
1167
1168 VPRINTF("%s\n",__FUNCTION__);
1169 pthread_mutex_lock(&_IPA_POOL_Mutex);
1170 if(!polling_param->polling_callback)
1171 {
1172 VPRINTF("%u have no polling_callback function , %s return directly\n",polling_param->pool_handle_id,__FUNCTION__);
1173 pthread_mutex_unlock(&_IPA_POOL_Mutex);
1174 return TRUE;
1175 }
1176
1177 ret = _findPoolHandleId_InIPA_Pool_Table(polling_param->pool_handle_id, &idx);
1178
1179 if(ret == FALSE)//not find idx
1180 {
1181 VPRINTF(" %s ipa pool fail not find pool_handle_id %u in pool table\n",__FUNCTION__,polling_param->pool_handle_id);
1182 pthread_mutex_unlock(&_IPA_POOL_Mutex);
1183 return FALSE;
1184 }
1185 VPRINTF("%s polling_param->pool_handle_id=0x%x\n",__FUNCTION__,polling_param->pool_handle_id);
1186
1187 if(-1 == IPAPool_Info[idx].pthIPAPollingId) //no polling id refer to pool handle id
1188 {
1189
1190 //create polling thread
1191 pthread_res = pthread_create(&pthIPAPollingId,
1192 NULL,
1193 (void *)IPA_Pool_Polling_Task,
1194 (void*)(intptr_t)polling_param->pool_handle_id);
1195 //N.B. notice that first parameter of pthread_create is output parameter,which
1196 //equal with pthread_self() in new pthread,and not equal with getpid().
1197 //to judge whether pthread_create success,only need check pthread_create return value.
1198 if(pthread_res != 0)
1199 {
1200 printf("%s can't create thread pthread_res=%d 1111\n",__FUNCTION__,pthread_res);
1201 ret= FALSE;
1202 pthread_mutex_unlock(&_IPA_POOL_Mutex);
1203 return ret;
1204 }
1205
1206 //corresponding pthIPAPollingId to pool_handle_id
1207 IPAPool_Info[idx].pthIPAPollingId = pthIPAPollingId;
1208 IPAPool_Info[idx].polling_callback = polling_param->polling_callback;
1209 }
1210 else//already have polling id refer to pool handle id.
1211 {
1212 ret=FALSE;
1213 VPRINTF("pool handle id %u has its polling id %lu ,error,will not set callback again\n",polling_param->pool_handle_id,IPAPool_Info[idx].pthIPAPollingId);
1214 }
1215
1216 pthread_mutex_unlock(&_IPA_POOL_Mutex);
1217 return ret;
1218 }
1219 #endif
1220