xref: /utopia/UTPA2-700.0.x/modules/msos/msos/linux/drvIPAPool.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
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