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 (CONFIG_MSTAR_IPAPOOL)
107
108 //TEST_USE_SELF_KO_MAKEFILE is
109 //only test code use,p4 code not use!!!!
110 //never set this macro in p4 with 1.any question ,contact with samson.huang
111 //though test code,please do not delete this test code.
112 #define TEST_USE_SELF_KO_MAKEFILE 0
113
114 #if TEST_USE_SELF_KO_MAKEFILE
115 #include <linux/module.h>
116 #else
117 #include "MsCommon.h"
118 #include "halCHIP.h"
119 #include "halMPool.h"
120 #endif
121 #include <linux/slab.h>
122
123 #include <linux/kthread.h>
124
125 #if defined(CONFIG_COMPAT)
126 #include <linux/compat.h>
127 #endif
128
129 #include "../../include/drvIPAPool.h"
130 #include "../mstar2/drv/ipa_pool/mdrv_ipa_pool_uapi.h"
131
132 #include <linux/sched.h>
133 #include <linux/fs.h>
134 #include <linux/uaccess.h>//for get_fs() /set_fs() use.
135
136 #include <linux/version.h>
137 #if (LINUX_VERSION_CODE == KERNEL_VERSION(3,10,40))
138 #include <linux/hardirq.h>
139 #endif
140
141
142 //debug macro,can not enable in p4.
143 #define DEBUG_IPA_KERNEL_MODE 1
144
145 //-------------------------------------------------------------------------------------------------
146 // Local Defines
147 //-------------------------------------------------------------------------------------------------
148 #define MAX_IPAPOOLSIZE 16UL
149
150 //
151 //
152 //for example:
153 //area 1 map 2 times,area 2 map 2times,area 3 map 1 times,total map 2+2+1=5
154 //
155 // map 2t map 2t map 1t
156 // ------ ----
157 // ------ ---- ---
158 // 1 2 3
159 // ------ ---- ------
160 //-----------------------------same client
161 #define MAX_CLIENT_MAP_NUM 8UL
162 //-------------------------------------------------------------------------------------------------
163 // Local Structurs
164 //-------------------------------------------------------------------------------------------------
165
166 struct VIRT_MAP_INFO
167 {
168 MS_U64 virt_addr;
169 MS_U64 length;
170 MS_BOOL bNonCache;
171 MS_U64 Physaddr;
172 };
173 struct IPA_Pool_Init_Param_No_P
174 {
175 MS_U32 heap_id; //in: heap id the pool will be created in
176 MS_U64 pool_name;//in: global identify name for pool to shared between multiple process
177
178 MS_U64 offset_in_heap; //in: pool location in heap
179 MS_U64 len; //in: pool length in heap
180
181 MS_U32 pool_handle_id; //out: generate pool id based on heap specified by heap_id
182 MS_U32 miu; //out: miu id this heap belongs, index from 0.
183 enum IPA_SPACE_TYPE heap_type;//out: return heap type to application
184 MS_S32 error_code; // error code when pool init failed
185
186 MS_U64 heap_length; //out: heap leagth
187 MS_U64 heap_miu_start_offset; //out: heap start offset in miu
188 };
189
190 typedef struct
191 {
192 struct IPA_Pool_Init_Param_No_P Init_Param;
193 MS_BOOL bIsUsed;
194 struct VIRT_MAP_INFO map_info[MAX_CLIENT_MAP_NUM];
195 volatile MS_BOOL polling_thread_delete_task_flag;
196 pid_t pthIPAPollingId;
197 void (*polling_callback)(MS_U32 pool_handle_id,MS_U64 start,MS_U64 length);
198 } IPAPOOL_INFO;
199
200 //-------------------------------------------------------------------------------------------------
201 // Global Variables
202 //-------------------------------------------------------------------------------------------------
203 static struct file * _fileIPAPool = NULL;
204 static struct mutex _IPA_POOL_Mutex = __MUTEX_INITIALIZER(_IPA_POOL_Mutex);
205
206 #if TEST_USE_SELF_KO_MAKEFILE_TOTAL
207 IPAPOOL_INFO IPAPool_Info[MAX_IPAPOOLSIZE];
208 #else
209 static IPAPOOL_INFO IPAPool_Info[MAX_IPAPOOLSIZE];
210 #endif
211 //-------------------------------------------------------------------------------------------------
212 // Debug Functions
213 //-------------------------------------------------------------------------------------------------
214
215
216 //-------------------------------------------------------------------------------------------------
217 // Local Functions
218 //-------------------------------------------------------------------------------------------------
_findEmpty_IPA_Pool_Entry(MS_U32 * index)219 static MS_BOOL _findEmpty_IPA_Pool_Entry(MS_U32 *index)
220 {
221 MS_BOOL find = FALSE;
222 MS_U32 i;
223
224 *index = 0;
225 for (i = 0; i < MAX_IPAPOOLSIZE; i++)
226 {
227 if(IPAPool_Info[i].bIsUsed == FALSE)
228 {
229 find = TRUE;
230 *index = i;
231 break;
232 }
233 }
234
235 if(find == FALSE)
236 printk("%s:%d Not enough IPAPool, must increase MAX_IPAPOOLSIZE!!\n",__FUNCTION__,__LINE__);
237
238 return find;
239 }
240
_findPoolHandleId_InIPA_Pool_Table(MS_U32 pool_handle_id,MS_U32 * index)241 static MS_BOOL _findPoolHandleId_InIPA_Pool_Table(MS_U32 pool_handle_id, MS_U32 *index)
242 {
243 MS_BOOL find = FALSE;
244 MS_U32 i;
245
246 *index = 0;
247 for (i = 0; i < MAX_IPAPOOLSIZE; i++)
248 {
249 if((IPAPool_Info[i].bIsUsed == TRUE) && (IPAPool_Info[i].Init_Param.pool_handle_id == pool_handle_id))
250 {
251 find = TRUE;
252 *index = i;
253 break;
254 }
255 }
256
257 return find;
258 }
259
_findHeapId_InIPA_Pool_Table(struct IPA_Pool_Init_Param * Init_Param,MS_U32 * index)260 static MS_BOOL _findHeapId_InIPA_Pool_Table(struct IPA_Pool_Init_Param * Init_Param,MS_U32 *index)
261 {
262 MS_BOOL find = FALSE;
263 MS_U32 i;
264
265 *index = 0;
266 for (i = 0; i < MAX_IPAPOOLSIZE; i++)
267 {
268 if((IPAPool_Info[i].bIsUsed == TRUE)
269 && (IPAPool_Info[i].Init_Param.heap_id == Init_Param->space_id)
270 &&(!strncmp((char *)IPAPool_Info[i].Init_Param.pool_name, Init_Param->pool_name,strlen(Init_Param->pool_name)))
271 && (IPAPool_Info[i].Init_Param.offset_in_heap == Init_Param->offset_in_heap)
272 && (IPAPool_Info[i].Init_Param.len == Init_Param->len))
273 {
274 find = TRUE;
275 *index = i;
276 break;
277 }
278 }
279
280 return find;
281 }
282
283
284 //-------------------------------------------------------------------------------------------------
285 // Global Functions
286 //-------------------------------------------------------------------------------------------------
287
288 //-------------------------------------------------------------------------------------------------
289 /// System initialzation
290 /// @return TRUE(Success), FALSE(Failure)
291 //-------------------------------------------------------------------------------------------------
MApi_IPA_Pool_Init(struct IPA_Pool_Init_Param * Init_Param)292 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_Init(struct IPA_Pool_Init_Param * Init_Param)
293 {
294 if (in_interrupt() || (current->flags & PF_KTHREAD))
295 {
296 printk("should only use kernel mode utopia API %s in user process\n",__FUNCTION__);
297 return false;
298 }
299
300 struct IPA_Pool_Init_Args ipa_init_args;
301
302 MS_BOOL ret = TRUE;
303 MS_U32 idx = 0;
304 int res = 0;
305 mm_segment_t old_fs;
306 #if DEBUG_IPA_KERNEL_MODE
307 printk("%s:%d heap_id %u Init_Param->pool_name=%s\n",__FUNCTION__,__LINE__, Init_Param->space_id,Init_Param->pool_name);
308 #endif
309
310 #ifdef DEBUG_IPA_KERNEL_MODE
311 printk("%s:%d ,Init_Param=%p heap_id %u\n",__FUNCTION__,__LINE__,Init_Param, Init_Param->space_id);
312 printk("%s:%d Init_Param->pool_name=%s\n",__FUNCTION__,__LINE__,Init_Param->pool_name);
313 #endif
314
315
316 #if DEBUG_IPA_KERNEL_MODE
317 printk("%s:%d heap_id %u Init_Param->pool_name=%s\n",__FUNCTION__,__LINE__, Init_Param->space_id,Init_Param->pool_name);
318 #endif
319
320 mutex_lock(&_IPA_POOL_Mutex);
321 if (!_fileIPAPool)
322 {
323 int flags=O_RDWR;
324 #ifdef DEBUG_IPA_KERNEL_MODE
325 printk("%s:%d heap_id %u\n",__FUNCTION__,__LINE__, Init_Param->space_id);
326 #endif
327 _fileIPAPool = filp_open( "/dev/ipapool", flags, 0);
328 if (IS_ERR(_fileIPAPool) )
329 {
330 printk("%s:%d open /dev/ipapool fail\n",__FUNCTION__,__LINE__);
331 ret = FALSE;
332 goto IPA_POOL_INIT_DONE;
333 }
334
335 memset(IPAPool_Info, 0, sizeof(IPAPOOL_INFO)*MAX_IPAPOOLSIZE);
336 }
337
338 #ifdef DEBUG_IPA_KERNEL_MODE
339 printk("%s:%d heap_id %u\n",__FUNCTION__,__LINE__, Init_Param->space_id);
340 #endif
341
342 //avoid mmap more than one time
343 ret = _findHeapId_InIPA_Pool_Table(Init_Param, &idx);
344 #ifdef DEBUG_IPA_KERNEL_MODE
345 printk("%s:%d heap_id %u\n",__FUNCTION__,__LINE__, Init_Param->space_id);
346 #endif
347
348 if(ret == TRUE)
349 {
350 //memcpy(Init_Param,IPAPool_Info[idx].Init_Param,sizeof(struct IPA_Pool_Init_Param));
351 Init_Param->space_id = IPAPool_Info[idx].Init_Param.heap_id;
352 Init_Param->pool_name = (char *)IPAPool_Info[idx].Init_Param.pool_name;
353 Init_Param->offset_in_heap = IPAPool_Info[idx].Init_Param.offset_in_heap;
354 Init_Param->len = IPAPool_Info[idx].Init_Param.len;
355 Init_Param->pool_handle_id = IPAPool_Info[idx].Init_Param.pool_handle_id;
356 Init_Param->miu = IPAPool_Info[idx].Init_Param.miu;
357 Init_Param->space_type = IPAPool_Info[idx].Init_Param.heap_type;
358 Init_Param->error_code = IPAPool_Info[idx].Init_Param.error_code;
359 Init_Param->space_length = IPAPool_Info[idx].Init_Param.heap_length;
360 Init_Param->space_miu_start_offset = IPAPool_Info[idx].Init_Param.heap_miu_start_offset;
361
362 printk("%s:%d pool_handle_id %u already init!\n",__FUNCTION__,__LINE__, IPAPool_Info[idx].Init_Param.pool_handle_id);
363 goto IPA_POOL_INIT_DONE;
364 }
365 #ifdef DEBUG_IPA_KERNEL_MODE
366 printk("%s:%d , heap_id %u\n",__FUNCTION__,__LINE__, Init_Param->space_id);
367 #endif
368
369 ipa_init_args.heap_id = Init_Param->space_id;
370 #ifdef DEBUG_IPA_KERNEL_MODE
371 printk("%s:%d , heap_id %u\n",__FUNCTION__,__LINE__, Init_Param->space_id);
372 #endif
373
374 if(sizeof(Init_Param->pool_name) > IPAPOOL_NAME_MAX_LONG+1)
375 {
376 printk("%s:%d pool name %s is too long size is %lu\n",__FUNCTION__,__LINE__,Init_Param->pool_name,sizeof(Init_Param->pool_name));
377 BUG();
378 }
379
380 strcpy(ipa_init_args.pool_name,Init_Param->pool_name);
381
382 #ifdef DEBUG_IPA_KERNEL_MODE
383 printk("%s:%d , heap_id %u\n",__FUNCTION__,__LINE__, Init_Param->space_id);
384 #endif
385
386 ipa_init_args.offset_in_heap = Init_Param->offset_in_heap;
387 ipa_init_args.len = Init_Param->len;
388 #ifdef DEBUG_IPA_KERNEL_MODE
389 printk("%s:%d Init_Param heapid %u ,offset=0x%llx,len=0x%llx\n",__FUNCTION__,__LINE__, Init_Param->space_id,(long long unsigned int)Init_Param->offset_in_heap,(long long unsigned int)Init_Param->len);
390 printk("%s:%d Init_Param->pool_name=%s,ipa_init_args->pool_name=%s\n",__FUNCTION__,__LINE__,Init_Param->pool_name,ipa_init_args.pool_name);
391 #endif
392 old_fs = get_fs();
393 set_fs(KERNEL_DS);
394
395 res = file_ioctl(_fileIPAPool, IPA_POOL_IOC_INIT, (unsigned long )(&ipa_init_args));
396 set_fs(old_fs);
397 if (res < 0 || ipa_init_args.error_code != IPAERROR_OK)
398 {
399 printk("%s:%d error: ipa init failed, heapid %u error_code %d\n",__FUNCTION__,__LINE__, Init_Param->space_id, ipa_init_args.error_code);
400 ret = FALSE;
401 goto IPA_POOL_INIT_CLOSE;
402 }
403 #if DEBUG_IPA_KERNEL_MODE
404 printk("%s:%d heap_id %u, pool_handle_id %u heap_length %llu\n",__FUNCTION__,__LINE__,
405 Init_Param->space_id, ipa_init_args.pool_handle_id, (long long unsigned int)ipa_init_args.heap_length);
406 #endif
407 Init_Param->pool_handle_id = ipa_init_args.pool_handle_id;
408 Init_Param->miu = ipa_init_args.miu;
409 Init_Param->space_type = ipa_init_args.heap_type;
410 Init_Param->error_code = ipa_init_args.error_code;
411 Init_Param->space_length = ipa_init_args.heap_length;
412 Init_Param->space_miu_start_offset = ipa_init_args.heap_miu_start_offset;
413 ret = _findEmpty_IPA_Pool_Entry(&idx);
414 if(ret == FALSE)
415 {
416 printk("%s:%d error: pool_handle_id %u init failed!\n",__FUNCTION__,__LINE__, ipa_init_args.pool_handle_id);
417 goto IPA_POOL_INIT_DONE;
418 }
419 /* IPA Pool setting*/
420 IPAPool_Info[idx].Init_Param.heap_id = Init_Param->space_id;
421
422 #if defined (__aarch64__)
423 IPAPool_Info[idx].Init_Param.pool_name = (MS_U64)Init_Param->pool_name;
424 #else
425 IPAPool_Info[idx].Init_Param.pool_name = (MS_U32)Init_Param->pool_name;
426 #endif
427 IPAPool_Info[idx].Init_Param.offset_in_heap =Init_Param->offset_in_heap;
428 IPAPool_Info[idx].Init_Param.len =Init_Param->len;
429 IPAPool_Info[idx].Init_Param.pool_handle_id =Init_Param->pool_handle_id;
430 IPAPool_Info[idx].Init_Param.miu =Init_Param->miu;
431 IPAPool_Info[idx].Init_Param.heap_type =Init_Param->space_type;
432 IPAPool_Info[idx].Init_Param.error_code =Init_Param->error_code;
433 IPAPool_Info[idx].Init_Param.heap_length =Init_Param->space_length;
434 IPAPool_Info[idx].Init_Param.heap_miu_start_offset =Init_Param->space_miu_start_offset;
435 IPAPool_Info[idx].bIsUsed = TRUE;
436 IPAPool_Info[idx].pthIPAPollingId = -1;//in init,no polling id yet.
437 IPAPool_Info[idx].polling_thread_delete_task_flag = FALSE;
438
439 #if DEBUG_IPA_KERNEL_MODE
440 printk("%s:%d heap_id %u pool_handle_id %u miu %u offset 0x%llx len 0x%llx\n",__FUNCTION__,__LINE__,
441 Init_Param->space_id, Init_Param->pool_handle_id, Init_Param->miu, (long long unsigned int)Init_Param->offset_in_heap, (long long unsigned int)Init_Param->len);
442 #endif
443 mutex_unlock(&_IPA_POOL_Mutex);
444 #if DEBUG_IPA_KERNEL_MODE
445 printk("%s:%d return %d\n",__FUNCTION__,__LINE__,ret);
446 #endif
447
448 return ret;
449
450 IPA_POOL_INIT_CLOSE:
451 filp_close(_fileIPAPool,NULL);
452 IPA_POOL_INIT_DONE:
453 printk("%s:%d ret=%d\n",__FUNCTION__,__LINE__,ret);
454 mutex_unlock(&_IPA_POOL_Mutex);
455
456 return ret;
457 }
458
459 //MS_U32 u32flag. Special Flag for customer mem allocation
MApi_IPA_Pool_GetMem(struct IPA_Pool_GetMem_Param * get_param)460 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_GetMem(struct IPA_Pool_GetMem_Param * get_param)
461 {
462 MS_BOOL ret = TRUE;
463 struct IPA_Pool_Alloc_Args ipa_alloc_args;
464
465 int res = 0;
466 mm_segment_t old_fs;
467
468 if (in_interrupt() || (current->flags & PF_KTHREAD))
469 {
470 printk("should only use kernel mode utopia API %s in user process\n",__FUNCTION__);
471 return false;
472 }
473
474 #if DEBUG_IPA_KERNEL_MODE
475 printk("%s:%d handle_id 0x%x length 0x%llx\n",__FUNCTION__,__LINE__, get_param->pool_handle_id, (long long unsigned int)get_param->length);
476 #endif
477
478 mutex_lock(&_IPA_POOL_Mutex);
479 if (IS_ERR(_fileIPAPool))
480 {
481 ret = FALSE;
482 goto IPA_POOL_GETMEM_DONE;
483 }
484
485 ipa_alloc_args.pool_handle_id = get_param->pool_handle_id;
486 ipa_alloc_args.offset_in_pool = get_param->offset_in_pool;
487 ipa_alloc_args.length = get_param->length;
488 ipa_alloc_args.timeout = 0;// 0 means if fail ,will not try again
489 old_fs = get_fs();
490 set_fs(KERNEL_DS);
491 res = file_ioctl(_fileIPAPool, IPA_POOL_IOC_ALLOC, (unsigned long)(&ipa_alloc_args));
492 set_fs(old_fs);
493 if (res < 0 || ipa_alloc_args.error_code != IPAERROR_OK)
494 {
495 printk("%s:%d fail: pool_handle_id %u, offset 0x%llx, len 0x%llx ipa_alloc_args.error_code=0x%x res=%d\n",__FUNCTION__,__LINE__, get_param->pool_handle_id,
496 (long long unsigned int)get_param->offset_in_pool, (long long unsigned int)get_param->length,ipa_alloc_args.error_code,res);
497 ret = FALSE;
498 goto IPA_POOL_GETMEM_DONE;
499 }
500
501 get_param->error_code = ipa_alloc_args.error_code;
502
503 IPA_POOL_GETMEM_DONE:
504 mutex_unlock(&_IPA_POOL_Mutex);
505
506 return ret;
507 }
508
MApi_IPA_Pool_PutMem(struct IPA_Pool_PutMem_Param * put_param)509 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_PutMem(struct IPA_Pool_PutMem_Param * put_param)
510 {
511 MS_BOOL ret = TRUE;
512 struct IPA_Pool_free_Args ipa_free_args;
513 mm_segment_t old_fs;
514
515 if (in_interrupt() || (current->flags & PF_KTHREAD))
516 {
517 printk("should only use kernel mode utopia API %s in user process\n",__FUNCTION__);
518 return false;
519 }
520
521 #if DEBUG_IPA_KERNEL_MODE
522 printk("%s:%d handle_id 0x%x length 0x%llx offset 0x%llx\n",__FUNCTION__,__LINE__,
523 put_param->pool_handle_id, (long long unsigned int)put_param->length, (long long unsigned int)put_param->offset_in_pool);
524 #endif
525
526 mutex_lock(&_IPA_POOL_Mutex);
527 if(IS_ERR(_fileIPAPool) )
528 {
529 ret = FALSE;
530 goto IPA_POOL_PUTMEM_DONE;
531 }
532
533 ipa_free_args.pool_handle_id = put_param->pool_handle_id;
534 ipa_free_args.offset_in_pool = put_param->offset_in_pool;
535 ipa_free_args.length = put_param->length;
536 old_fs = get_fs();
537 set_fs(KERNEL_DS);
538 if(file_ioctl(_fileIPAPool, IPA_POOL_IOC_FREE, (unsigned long)(&ipa_free_args)))
539 {
540 set_fs(old_fs);
541 printk("%s:%d fail: pool_handle_id 0x%x, offset 0x%llx, len 0x%llx\n",__FUNCTION__,__LINE__,
542 put_param->pool_handle_id, (long long unsigned int)put_param->offset_in_pool, (long long unsigned int)put_param->length);
543 ret = FALSE;
544 goto IPA_POOL_PUTMEM_DONE;
545 }
546 set_fs(old_fs);
547
548 IPA_POOL_PUTMEM_DONE:
549 mutex_unlock(&_IPA_POOL_Mutex);
550
551 return ret;
552 }
553
MApi_IPA_Pool_Release(MS_U32 pool_handle_id)554 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_Release(MS_U32 pool_handle_id)
555 {
556 MS_BOOL ret = TRUE;
557
558 struct IPA_Pool_Deinit_Args deinit_args;
559 struct IPA_Pool_Unmap_Args unmap_args;
560
561 MS_U32 idx = 0;
562 int res = 0,i=0;
563 mm_segment_t old_fs;
564
565 if (in_interrupt() || (current->flags & PF_KTHREAD))
566 {
567 printk("should only use kernel mode utopia API %s in user process\n",__FUNCTION__);
568 return false;
569 }
570
571 #if DEBUG_IPA_KERNEL_MODE
572 printk("%s:%d handle_id %u\n",__FUNCTION__,__LINE__, pool_handle_id);
573 #endif
574
575 mutex_lock(&_IPA_POOL_Mutex);
576 if (IS_ERR(_fileIPAPool) )
577 {
578 ret = FALSE;
579 goto IPA_POOL_RELEASE_DONE;
580 }
581
582 ret = _findPoolHandleId_InIPA_Pool_Table(pool_handle_id, &idx);
583 if(ret == TRUE)
584 {
585 for(i=0;i<MAX_CLIENT_MAP_NUM;i++)
586 {
587 // tmp_map_info
588 if((0 !=IPAPool_Info[idx].map_info[i].virt_addr)
589 && (0 != IPAPool_Info[idx].map_info[i].length))
590 {
591 unmap_args.virt_addr = IPAPool_Info[idx].map_info[i].virt_addr;
592 unmap_args.length = IPAPool_Info[idx].map_info[i].length;
593 #if TEST_USE_SELF_KO_MAKEFILE
594 #else
595 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);
596 #endif
597 old_fs = get_fs();
598 set_fs(KERNEL_DS);
599 res = file_ioctl(_fileIPAPool, IPA_POOL_IOC_UNMAP, (unsigned long)(&unmap_args));
600 set_fs(old_fs);
601 if (res < 0)
602 {
603 printk("%s:%d error: pool_handle_id %u unmap failed\n",__FUNCTION__,__LINE__, pool_handle_id);
604 ret = FALSE;
605 goto IPA_POOL_RELEASE_DONE;
606 }
607 IPAPool_Info[idx].map_info[i].virt_addr = 0;
608 IPAPool_Info[idx].map_info[i].length = 0;
609 }
610 }
611
612 if(MAX_CLIENT_MAP_NUM == i)
613 {
614 // if same client all maps have been unmapped ,set IPAPool_Info[idx].bIsUsed be FALSE
615 IPAPool_Info[idx].bIsUsed = FALSE;
616 IPAPool_Info[idx].Init_Param.pool_handle_id = 0;
617 }
618 }
619
620 deinit_args.pool_handle_id = pool_handle_id;
621 old_fs = get_fs();
622 set_fs(KERNEL_DS);
623 if (file_ioctl(_fileIPAPool, IPA_POOL_IOC_DEINIT, (unsigned long)(&deinit_args)))
624 {
625 set_fs(old_fs);
626 printk("%s:%d pool_handle_id %u deinit fail\n",__FUNCTION__,__LINE__, pool_handle_id);
627 ret = FALSE;
628 goto IPA_POOL_RELEASE_DONE;
629 }
630 set_fs(old_fs);
631 ret = TRUE; //not find the pool hand id
632
633 //after deinit, if have polling thread,should delete task
634 if(IPAPool_Info[idx].pthIPAPollingId != -1)
635 {
636 #if 0//no need this while,for later pthread_join + pthread_cancel will wait for set delete_task_flag.
637 while(1)
638 {
639 if(TRUE == IPAPool_Info[idx].polling_thread_delete_task_flag)
640 break;
641 }
642 #endif
643
644 //should add some code about waitting polling thread to finish???
645 //free_task(find_task_by_vpid(IPAPool_Info[idx].pthIPAPollingId));
646 //mb();
647 //__put_task_struct(find_task_by_vpid(IPAPool_Info[idx].pthIPAPollingId));
648
649 if(TRUE != IPAPool_Info[idx].polling_thread_delete_task_flag)
650 {
651 printk("%s:%d error !!!!!! after free_task polling_thread_delete_task_flag is not TRUE!!!\n",__FUNCTION__,__LINE__);
652 ret = FALSE;
653 }
654
655 }
656
657 IPA_POOL_RELEASE_DONE:
658 mutex_unlock(&_IPA_POOL_Mutex);
659 return ret;
660 }
661
662 #if 0//in user mode,use MapUserVA and UnmapUserVA,but in kernel mode use MapKerVA and UnmapKerVA.
663 //allow a same input [pool_handle_id, offset_in_pool, length, cache_type] map for more than once,
664 //and get different result output [virt_addr]
665 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_MapUserVA(struct IPA_Pool_Map_User_Param * map_param)
666 {
667 MS_BOOL ret = TRUE;
668 int res = 0;
669
670 struct IPA_Pool_Map_Args map_args;
671
672 MS_U32 idx = 0;
673 mm_segment_t old_fs;
674
675 if (in_interrupt() || (current->flags & PF_KTHREAD))
676 {
677 printk("should only use kernel mode utopia API %s in user process\n",__FUNCTION__);
678 return false;
679 }
680
681 #if DEBUG_IPA_KERNEL_MODE
682 printk("%s:%d pool_handle_id %u, offset_in_pool 0x%llx, len 0x%llx, cache_type %u\n",__FUNCTION__,__LINE__, map_param->pool_handle_id,
683 (long long unsigned int)map_param->offset_in_pool, (long long unsigned int)map_param->length,map_param->cache_type);
684 #endif
685
686 mutex_lock(&_IPA_POOL_Mutex);
687 if (IS_ERR(_fileIPAPool) )
688 {
689 ret = FALSE;
690 goto IPA_POOL_MapUserVA_DONE;
691 }
692
693 if(0 == map_param->length)
694 {
695 printk("%s:%d error, len 0x%llx is invalid\n",__FUNCTION__,__LINE__, (long long unsigned int)map_param->length);
696 ret = FALSE;
697 goto IPA_POOL_MapUserVA_DONE;
698 }
699
700 map_args.pool_handle_id = map_param->pool_handle_id;
701 map_args.offset_in_pool = map_param->offset_in_pool;
702 map_args.length = map_param->length;
703 map_args.map_va_type = map_param->cache_type;
704
705 old_fs = get_fs();
706 set_fs(KERNEL_DS);
707 res = file_ioctl(_fileIPAPool, IPA_POOL_IOC_MAP, (unsigned long)(&map_args));
708 set_fs(old_fs);
709 if (res < 0 || map_args.error_code != IPAERROR_OK)
710 {
711 printk("%s:%d fail: pool_handle_id %u, offset_in_pool 0x%llx, len 0x%llx, cache_type %u\n",__FUNCTION__,__LINE__, map_param->pool_handle_id,
712 (long long unsigned int)map_param->offset_in_pool, (long long unsigned int)map_param->length,map_param->cache_type);
713 ret = FALSE;
714 goto IPA_POOL_MapUserVA_DONE;
715 }
716 map_param->virt_addr = map_args.virt_addr;
717 map_param->error_code = map_args.error_code;
718
719 ret = _findPoolHandleId_InIPA_Pool_Table(map_param->pool_handle_id, &idx);
720 if(ret == TRUE)
721 {
722 int i=0;
723 for(i=0;i<MAX_CLIENT_MAP_NUM;i++)
724 {
725 if((0 == IPAPool_Info[idx].map_info[i].virt_addr)
726 || (0 == IPAPool_Info[idx].map_info[i].length))
727 {
728 IPAPool_Info[idx].map_info[i].virt_addr = map_args.virt_addr;
729 IPAPool_Info[idx].map_info[i].length = map_args.length;
730 #if TEST_USE_SELF_KO_MAKEFILE
731 #else
732 _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
733 if(IPA_VA_CACHE_NONE_CACHE_Param == map_param->cache_type)
734 IPAPool_Info[idx].map_info[i].bNonCache = TRUE;
735 else
736 IPAPool_Info[idx].map_info[i].bNonCache = FALSE;
737
738 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);
739 #endif
740 break;
741 }
742 }
743
744 if(MAX_CLIENT_MAP_NUM == i)
745 {
746 printk("print important log for 3 times :a same client mapped %lu times,unable map once more!!!!\n", MAX_CLIENT_MAP_NUM);
747 printk("print important log for 3 times :a same client mapped %lu times,unable map once more!!!!\n", MAX_CLIENT_MAP_NUM);
748 printk("print important log for 3 times :a same client mapped %lu times,unable map once more!!!!\n", MAX_CLIENT_MAP_NUM);
749 //here later can add code for dump map info
750 ret = FALSE;
751 goto IPA_POOL_MapUserVA_DONE;
752 }
753 }
754
755 IPA_POOL_MapUserVA_DONE:
756 #if DEBUG_IPA_KERNEL_MODE
757 printk("%s:%d ret=%d\n",__FUNCTION__,__LINE__,ret);
758 #endif
759 mutex_unlock(&_IPA_POOL_Mutex);
760
761 return ret;
762 }
763
764 void __attribute__((weak)) MApi_IPA_Pool_UnmapUserVA(struct IPA_Pool_Unmap_User_Param * unmap_param)
765 {
766 MS_BOOL ret = TRUE;
767 int res = 0;
768 int i=0,idx=0,find_virt_info_i=-1,find_virt_info_idx=-1;
769 MS_BOOL find_virt_info = FALSE;
770
771 struct IPA_Pool_Unmap_Args unmap_args;
772 mm_segment_t old_fs;
773
774 if (in_interrupt() || (current->flags & PF_KTHREAD))
775 {
776 printk("should only use kernel mode utopia API %s in user process\n",__FUNCTION__);
777 return;
778 }
779 #if DEBUG_IPA_KERNEL_MODE
780 printk("%s:%d virt_addr 0x%llx, len 0x%llx \n",__FUNCTION__,__LINE__,(long long unsigned int)unmap_param->virt_addr, (long long unsigned int)unmap_param->length);
781 #endif
782
783 mutex_lock(&_IPA_POOL_Mutex);
784 if (IS_ERR(_fileIPAPool))
785 {
786 ret = FALSE;
787 goto IPA_POOL_UnmapUserVA_DONE;
788 }
789 for(idx=0;idx < MAX_IPAPOOLSIZE;idx++)
790 {
791 if(TRUE == IPAPool_Info[idx].bIsUsed)
792 {
793 for(i=0;i<MAX_CLIENT_MAP_NUM;i++)
794 {
795 if((unmap_param->virt_addr == IPAPool_Info[idx].map_info[i].virt_addr)
796 && (unmap_param->length == IPAPool_Info[idx].map_info[i].length))
797 {
798 find_virt_info = TRUE;
799 find_virt_info_idx = idx;
800 find_virt_info_i = i;
801 }
802 }
803 }
804 }
805 if(FALSE == find_virt_info)
806 {
807 printk("print important log for 3 times :map and unmap area should be strict equal !!!! virt_addr=0x%llx,length=0x%llx\n", (long long unsigned int)unmap_param->virt_addr,(long long unsigned int)unmap_param->length);
808 printk("print important log for 3 times :map and unmap area should be strict equal !!!! virt_addr=0x%llx,length=0x%llx\n", (long long unsigned int)unmap_param->virt_addr,(long long unsigned int)unmap_param->length);
809 printk("print important log for 3 times :map and unmap area should be strict equal !!!! virt_addr=0x%llx,length=0x%llx\n", (long long unsigned int)unmap_param->virt_addr,(long long unsigned int)unmap_param->length);
810 //later will add some debug code
811 ret = FALSE;
812 goto IPA_POOL_UnmapUserVA_DONE;
813 }
814
815 unmap_args.virt_addr = unmap_param->virt_addr;
816 unmap_args.length = unmap_param->length;
817 #if TEST_USE_SELF_KO_MAKEFILE
818 #else
819 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);
820 #endif
821 old_fs = get_fs();
822 set_fs(KERNEL_DS);
823
824 res = file_ioctl(_fileIPAPool,IPA_POOL_IOC_UNMAP,(unsigned long)(&unmap_args));
825 set_fs(old_fs);
826 if (res < 0)
827 {
828 printk("%s:%d fail: virt_addr 0x%llx, len 0x%llx \n",__FUNCTION__,__LINE__,
829 (long long unsigned int)unmap_param->virt_addr, (long long unsigned int)unmap_param->length);
830 ret = FALSE;
831 goto IPA_POOL_UnmapUserVA_DONE;
832 }
833 IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].virt_addr = 0;
834 IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].length = 0;
835
836 IPA_POOL_UnmapUserVA_DONE:
837 mutex_unlock(&_IPA_POOL_Mutex);
838
839 return;
840 }
841 #endif
MApi_IPA_Pool_MapKerVA(struct IPA_Pool_Map_Param * map_param)842 static MS_BOOL MApi_IPA_Pool_MapKerVA(struct IPA_Pool_Map_Param * map_param)
843 {
844 MS_BOOL ret = TRUE;
845 int res = 0;
846
847 struct IPA_Pool_Map_Args map_args;
848
849 MS_U32 idx = 0;
850 mm_segment_t old_fs;
851
852 if (in_interrupt() || (current->flags & PF_KTHREAD))
853 {
854 printk("should only use kernel mode utopia API %s in user process\n",__FUNCTION__);
855 return false;
856 }
857
858 #if DEBUG_IPA_KERNEL_MODE
859 printk("%s:%d pool_handle_id %u, offset_in_pool 0x%llx, len 0x%llx, cache_type %u\n",__FUNCTION__,__LINE__, map_param->pool_handle_id,
860 (long long unsigned int)map_param->offset_in_pool, (long long unsigned int)map_param->length,map_param->cache_type);
861 #endif
862
863 mutex_lock(&_IPA_POOL_Mutex);
864 if (IS_ERR(_fileIPAPool) )
865 {
866 ret = FALSE;
867 goto IPA_POOL_MapUserVA_DONE;
868 }
869
870 if(0 == map_param->length)
871 {
872 printk("%s:%d error, len 0x%llx is invalid\n",__FUNCTION__,__LINE__, (long long unsigned int)map_param->length);
873 ret = FALSE;
874 goto IPA_POOL_MapUserVA_DONE;
875 }
876
877 map_args.pool_handle_id = map_param->pool_handle_id;
878 map_args.offset_in_pool = map_param->offset_in_pool;
879 map_args.length = map_param->length;
880 map_args.map_va_type = map_param->cache_type;
881
882
883 old_fs = get_fs();
884 set_fs(KERNEL_DS);
885 res = file_ioctl(_fileIPAPool, IPA_POOL_IOC_KERNEL_MAP, (unsigned long)(&map_args));
886 set_fs(old_fs);
887
888 if (res < 0 || map_args.error_code != IPAERROR_OK)
889 {
890 printk("%s:%d fail: pool_handle_id %u, offset_in_pool 0x%llx, len 0x%llx, cache_type %u\n",__FUNCTION__,__LINE__, map_param->pool_handle_id,
891 (long long unsigned int)map_param->offset_in_pool, (long long unsigned int)map_param->length,map_param->cache_type);
892 ret = FALSE;
893 goto IPA_POOL_MapUserVA_DONE;
894 }
895 map_param->virt_addr = map_args.virt_addr;
896 map_param->error_code = map_args.error_code;
897
898 ret = _findPoolHandleId_InIPA_Pool_Table(map_param->pool_handle_id, &idx);
899 if(ret == TRUE)
900 {
901 int i=0;
902 for(i=0;i<MAX_CLIENT_MAP_NUM;i++)
903 {
904 if((0 == IPAPool_Info[idx].map_info[i].virt_addr)
905 || (0 == IPAPool_Info[idx].map_info[i].length))
906 {
907 IPAPool_Info[idx].map_info[i].virt_addr = map_args.virt_addr;
908 IPAPool_Info[idx].map_info[i].length = map_args.length;
909 #if TEST_USE_SELF_KO_MAKEFILE
910 #else
911 _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
912 if(IPA_VA_CACHE_NONE_CACHE_Param == map_param->cache_type)
913 IPAPool_Info[idx].map_info[i].bNonCache = TRUE;
914 else
915 IPAPool_Info[idx].map_info[i].bNonCache = FALSE;
916 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);
917 #endif
918 break;
919 }
920 }
921 if(MAX_CLIENT_MAP_NUM == i)
922 {
923 printk("print important log for 3 times :a same client mapped %lu times,unable map once more!!!!\n", MAX_CLIENT_MAP_NUM);
924 printk("print important log for 3 times :a same client mapped %lu times,unable map once more!!!!\n", MAX_CLIENT_MAP_NUM);
925 printk("print important log for 3 times :a same client mapped %lu times,unable map once more!!!!\n", MAX_CLIENT_MAP_NUM);
926 //here later can add code for dump map info
927 ret = FALSE;
928 goto IPA_POOL_MapUserVA_DONE;
929 }
930 }
931
932 IPA_POOL_MapUserVA_DONE:
933 printk("%s ret=%d\n",__FUNCTION__,ret);
934 mutex_unlock(&_IPA_POOL_Mutex);
935
936 return ret;
937 }
938
MApi_IPA_Pool_MapVA(struct IPA_Pool_Map_Param * map_param)939 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_MapVA(struct IPA_Pool_Map_Param * map_param)
940 {
941 return MApi_IPA_Pool_MapKerVA(map_param);
942 }
943
MApi_IPA_Pool_UnmapKerVA(struct IPA_Pool_Unmap_Param * unmap_param)944 static void MApi_IPA_Pool_UnmapKerVA(struct IPA_Pool_Unmap_Param * unmap_param)
945 {
946 MS_BOOL ret = TRUE;
947 int res = 0;
948 int i=0,idx=0,find_virt_info_i=-1,find_virt_info_idx=-1;
949 MS_BOOL find_virt_info = FALSE;
950
951 struct IPA_Pool_Unmap_Args unmap_args;
952 mm_segment_t old_fs;
953
954 if (in_interrupt() || (current->flags & PF_KTHREAD))
955 {
956 printk("should only use kernel mode utopia API %s in user process\n",__FUNCTION__);
957 return;
958 }
959
960 #if DEBUG_IPA_KERNEL_MODE
961 printk("%s:%d virt_addr 0x%llx \n",__FUNCTION__,__LINE__, (long long unsigned int)unmap_param->virt_addr);
962 #endif
963
964 mutex_lock(&_IPA_POOL_Mutex);
965 if (IS_ERR(_fileIPAPool))
966 {
967 ret = FALSE;
968 goto IPA_POOL_UnmapUserVA_DONE;
969 }
970 for(idx=0;idx < MAX_IPAPOOLSIZE;idx++)
971 {
972 if(TRUE == IPAPool_Info[idx].bIsUsed)
973 {
974 for(i=0;i<MAX_CLIENT_MAP_NUM;i++)
975 {
976 if(unmap_param->virt_addr == IPAPool_Info[idx].map_info[i].virt_addr)
977 {
978 find_virt_info = TRUE;
979 find_virt_info_idx = idx;
980 find_virt_info_i = i;
981 }
982 }
983 }
984 }
985 if(FALSE == find_virt_info)
986 {
987 printk("print important log for 3 times :map and unmap area should be strict equal !!!! virt_addr=0x%llx\n", (long long unsigned int)unmap_param->virt_addr);
988 printk("print important log for 3 times :map and unmap area should be strict equal !!!! virt_addr=0x%llx\n", (long long unsigned int)unmap_param->virt_addr);
989 printk("print important log for 3 times :map and unmap area should be strict equal !!!! virt_addr=0x%llx\n", (long long unsigned int)unmap_param->virt_addr);
990 //later will add some debug code
991 ret = FALSE;
992 goto IPA_POOL_UnmapUserVA_DONE;
993 }
994
995 unmap_args.virt_addr = unmap_param->virt_addr;
996 #if TEST_USE_SELF_KO_MAKEFILE
997 #else
998 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);
999 #endif
1000 old_fs = get_fs();
1001 set_fs(KERNEL_DS);
1002
1003 res = file_ioctl(_fileIPAPool,IPA_POOL_IOC_KERNEL_UNMAP,(unsigned long)(&unmap_args));
1004 set_fs(old_fs);
1005 if (res < 0)
1006 {
1007 printk("%s:%d fail: virt_addr 0x%llx\n",__FUNCTION__,__LINE__, (long long unsigned int)unmap_param->virt_addr);
1008 ret = FALSE;
1009 goto IPA_POOL_UnmapUserVA_DONE;
1010 }
1011 IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].virt_addr = 0;
1012 IPAPool_Info[find_virt_info_idx].map_info[find_virt_info_i].length = 0;
1013
1014 IPA_POOL_UnmapUserVA_DONE:
1015 mutex_unlock(&_IPA_POOL_Mutex);
1016
1017 return;
1018 }
1019
MApi_IPA_Pool_UnmapVA(struct IPA_Pool_Unmap_Param * unmap_param)1020 void __attribute__((weak)) MApi_IPA_Pool_UnmapVA(struct IPA_Pool_Unmap_Param * unmap_param)
1021 {
1022 return MApi_IPA_Pool_UnmapKerVA(unmap_param);
1023 }
1024
MApi_IPA_Pool_DCacheFlush(struct IPA_Pool_DCacheFlush_Param * dcache_flush_param)1025 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_DCacheFlush(struct IPA_Pool_DCacheFlush_Param* dcache_flush_param)
1026 {
1027 MS_BOOL ret = TRUE;
1028 int res = 0;
1029
1030 struct IPA_Pool_DCacheFlush_Args dcache_flush_args;
1031 mm_segment_t old_fs;
1032
1033 if (in_interrupt() || (current->flags & PF_KTHREAD))
1034 {
1035 printk("should only use kernel mode utopia API %s in user process\n",__FUNCTION__);
1036 return false;
1037 }
1038
1039 #if DEBUG_IPA_KERNEL_MODE
1040 printk("%s:%d virt_addr 0x%llx, length 0x%llx flush_type 0x%x\n",
1041 __FUNCTION__,__LINE__,(long long unsigned int)dcache_flush_param->virt_addr, (long long unsigned int)dcache_flush_param->length, dcache_flush_param->flush_type);
1042 #endif
1043
1044 mutex_lock(&_IPA_POOL_Mutex);
1045 if (IS_ERR(_fileIPAPool))
1046 {
1047 ret = FALSE;
1048 goto IPA_POOL_DCacheFlush_DONE;
1049 }
1050
1051 dcache_flush_args.virt_addr = dcache_flush_param->virt_addr;
1052 dcache_flush_args.length = dcache_flush_param->length;
1053 dcache_flush_args.flush_type = dcache_flush_param->flush_type;
1054 old_fs = get_fs();
1055 set_fs(KERNEL_DS);
1056 res = file_ioctl(_fileIPAPool,IPA_POOL_IOC_FLUSH,(unsigned long)(&dcache_flush_args));
1057 set_fs(old_fs);
1058 if (res < 0)
1059 {
1060 printk("%s:%d fail: virt_addr 0x%llx, length 0x%llx , flush_type 0x%x\n",
1061 __FUNCTION__,__LINE__,(long long unsigned int)dcache_flush_param->virt_addr, (long long unsigned int)dcache_flush_param->length, dcache_flush_param->flush_type);
1062 ret = FALSE;
1063 goto IPA_POOL_DCacheFlush_DONE;
1064 }
1065
1066 IPA_POOL_DCacheFlush_DONE:
1067 mutex_unlock(&_IPA_POOL_Mutex);
1068
1069 return ret;
1070 }
1071
MApi_IPA_Pool_HEAP_ATTR(struct IPA_Pool_Heap_Attr_Param * heap_attr_param)1072 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_HEAP_ATTR(struct IPA_Pool_Heap_Attr_Param* heap_attr_param)
1073 {
1074 MS_BOOL ret = TRUE;
1075 int res = 0;
1076
1077 struct IPA_Pool_Heap_Attr heap_attr_args;
1078 mm_segment_t old_fs;
1079
1080 if (in_interrupt() || (current->flags & PF_KTHREAD))
1081 {
1082 printk("should only use kernel mode utopia API %s in user process\n",__FUNCTION__);
1083 return false;
1084 }
1085
1086 #if DEBUG_IPA_KERNEL_MODE
1087 printk("%s:%d heap_id 0x%x\n",__FUNCTION__,__LINE__, heap_attr_param->heap_id);
1088 #endif
1089
1090 mutex_lock(&_IPA_POOL_Mutex);
1091 if (IS_ERR(_fileIPAPool ))
1092 {
1093 ret = FALSE;
1094 goto IPA_POOL_HEAP_ATTR_DONE;
1095 }
1096
1097 heap_attr_args.heap_id = heap_attr_param->heap_id;
1098
1099 old_fs = get_fs();
1100 set_fs(KERNEL_DS);
1101 res = file_ioctl(_fileIPAPool,IPA_POOL_IOC_HEAP_ATTR,(unsigned long)(&heap_attr_args));
1102 set_fs(old_fs);
1103 if (res < 0 || heap_attr_args.error_code != IPAERROR_OK)
1104 {
1105 printk("%s:%d fail: heap_id 0x%x\n",__FUNCTION__,__LINE__,heap_attr_param->heap_id);
1106 ret = FALSE;
1107 goto IPA_POOL_HEAP_ATTR_DONE;
1108 }
1109 memcpy(heap_attr_param->name,heap_attr_args.name,IPAPOOL_HEAP_NAME_MAX_LEN);
1110 heap_attr_param->heap_miu_start_offset = heap_attr_args.heap_miu_start_offset;
1111 heap_attr_param->heap_length = heap_attr_args.heap_length;
1112 heap_attr_param->miu = heap_attr_args.miu;
1113 heap_attr_param->heap_type = heap_attr_args.heap_type;
1114 heap_attr_param->error_code = heap_attr_args.error_code;
1115
1116 IPA_POOL_HEAP_ATTR_DONE:
1117 mutex_unlock(&_IPA_POOL_Mutex);
1118
1119 return ret;
1120 }
1121
MApi_IPA_Pool_GETIPCHANDLE(struct IPA_Pool_GetIpcHandle_Param * getipchandle_param)1122 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_GETIPCHANDLE(struct IPA_Pool_GetIpcHandle_Param* getipchandle_param)
1123 {
1124 MS_BOOL ret = TRUE;
1125 int res = 0;
1126
1127 struct IPA_Pool_GetIpcHandle_Args getipchandle_args;
1128 mm_segment_t old_fs;
1129
1130 if (in_interrupt() || (current->flags & PF_KTHREAD))
1131 {
1132 printk("should only use kernel mode utopia API %s in user process\n",__FUNCTION__);
1133 return false;
1134 }
1135
1136 #if DEBUG_IPA_KERNEL_MODE
1137 printk("%s:%d pool_handle_id 0x%x\n",__FUNCTION__,__LINE__, getipchandle_param->pool_handle_id);
1138 #endif
1139
1140 mutex_lock(&_IPA_POOL_Mutex);
1141 if (IS_ERR(_fileIPAPool))
1142 {
1143 printk("%s:%d fail pool_handle_id=0x%x, _fileIPAPool=%p \n",__FUNCTION__,__LINE__, getipchandle_param->pool_handle_id,_fileIPAPool);
1144 ret = FALSE;
1145 goto IPA_POOL_GETIPCHANDLE_DONE;
1146 }
1147
1148 getipchandle_args.pool_handle_id = getipchandle_param->pool_handle_id;
1149 old_fs = get_fs();
1150 set_fs(KERNEL_DS);
1151 res = file_ioctl(_fileIPAPool,IPA_POOL_IOC_GETIPCHANDLE,(unsigned long)(&getipchandle_args));
1152 set_fs(old_fs);
1153 if (res < 0 || getipchandle_args.error_code != IPAERROR_OK)
1154 {
1155 printk("%s:%d fail: pool_handle_id 0x%x\n",__FUNCTION__,__LINE__,getipchandle_param->pool_handle_id);
1156 ret = FALSE;
1157 goto IPA_POOL_GETIPCHANDLE_DONE;
1158 }
1159 getipchandle_param->ipc_handle_id = getipchandle_args.ipc_handle_id;
1160 getipchandle_param->error_code = getipchandle_args.error_code;
1161
1162 IPA_POOL_GETIPCHANDLE_DONE:
1163 mutex_unlock(&_IPA_POOL_Mutex);
1164
1165 return ret;
1166 }
1167
MApi_IPA_Pool_InstallIpcHandle(struct IPA_Pool_InstallIpcHandle_Param * installipchandle_param)1168 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_InstallIpcHandle(struct IPA_Pool_InstallIpcHandle_Param* installipchandle_param)
1169 {
1170 MS_BOOL ret = TRUE;
1171 int res = 0;
1172
1173 struct IPA_Pool_InstallIpcHandle_Args installipchandle_args;
1174 mm_segment_t old_fs;
1175
1176 if (in_interrupt() || (current->flags & PF_KTHREAD))
1177 {
1178 printk("should only use kernel mode utopia API %s in user process\n",__FUNCTION__);
1179 return false;
1180 }
1181
1182 #if DEBUG_IPA_KERNEL_MODE
1183 printk("%s:%d ipc_handle_id 0x%x\n",__FUNCTION__,__LINE__, installipchandle_param->ipc_handle_id);
1184 #endif
1185
1186 mutex_lock(&_IPA_POOL_Mutex);
1187 if ( !_fileIPAPool || IS_ERR(_fileIPAPool))
1188 {
1189 #if DEBUG_IPA_KERNEL_MODE
1190 printk("%s:%d ipc_handle_id=0x%x, _fileIPAPool=%p \n",__FUNCTION__,__LINE__, installipchandle_param->ipc_handle_id,_fileIPAPool);
1191 #endif
1192 //this process may not open ipapool yet,need we open for this process.
1193 int flags=O_RDWR;
1194 _fileIPAPool = filp_open( "/dev/ipapool", flags, 0);
1195 if (IS_ERR(_fileIPAPool) )
1196 {
1197 printk("%s:%d open /dev/ipapool fail ipc_handle_id=0x%x, _fileIPAPool=%p\n",__FUNCTION__,__LINE__, installipchandle_param->ipc_handle_id,_fileIPAPool);
1198 ret = FALSE;
1199 goto IPA_POOL_InstallIpcHandle_DONE;
1200 }
1201
1202 memset(IPAPool_Info, 0, sizeof(IPAPOOL_INFO)*MAX_IPAPOOLSIZE);
1203
1204 }
1205
1206 installipchandle_args.ipc_handle_id = installipchandle_param->ipc_handle_id;
1207
1208 old_fs = get_fs();
1209 set_fs(KERNEL_DS);
1210 res = file_ioctl(_fileIPAPool,IPA_POOL_IOC_INSTALLIPCHANDLE,(unsigned long)(&installipchandle_args));
1211 set_fs(old_fs);
1212
1213 if (res < 0 || installipchandle_args.error_code != IPAERROR_OK)
1214 {
1215 printk("%s:%d fail: heap_id 0x%x\n",__FUNCTION__,__LINE__,installipchandle_param->ipc_handle_id);
1216 ret = FALSE;
1217 goto IPA_POOL_InstallIpcHandle_DONE;
1218 }
1219 installipchandle_param->pool_handle_id = installipchandle_args.pool_handle_id;
1220 installipchandle_param->error_code = installipchandle_args.error_code;
1221
1222 IPA_POOL_InstallIpcHandle_DONE:
1223 mutex_unlock(&_IPA_POOL_Mutex);
1224
1225 return ret;
1226 }
1227
1228 //unit of timeout is millisecond.
MApi_IPA_Pool_GetMem_Timeout(struct IPA_Pool_GetMem_Param * get_param,MS_U32 timeout_ms)1229 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_GetMem_Timeout(struct IPA_Pool_GetMem_Param* get_param,MS_U32 timeout_ms)
1230 {
1231 MS_BOOL ret = TRUE;
1232
1233 struct IPA_Pool_Alloc_Args ipa_alloc_args;
1234
1235 int res = 0;
1236 mm_segment_t old_fs;
1237
1238 if (in_interrupt() || (current->flags & PF_KTHREAD))
1239 {
1240 printk("should only use kernel mode utopia API %s in user process\n",__FUNCTION__);
1241 return false;
1242 }
1243
1244 #if DEBUG_IPA_KERNEL_MODE
1245 printk("%s:%d handle_id 0x%x length 0x%llx timeout 0x%x\n",__FUNCTION__,__LINE__,
1246 get_param->pool_handle_id, (long long unsigned int)get_param->length,timeout_ms);
1247 #endif
1248
1249 mutex_lock(&_IPA_POOL_Mutex);
1250 if (IS_ERR(_fileIPAPool ))
1251 {
1252 ret = FALSE;
1253 goto IPA_POOL_GETMEM_DONE;
1254 }
1255
1256 ipa_alloc_args.pool_handle_id = get_param->pool_handle_id;
1257 ipa_alloc_args.offset_in_pool = get_param->offset_in_pool;
1258 ipa_alloc_args.length = get_param->length;
1259
1260 ipa_alloc_args.timeout = timeout_ms;
1261
1262 old_fs = get_fs();
1263 set_fs(KERNEL_DS);
1264 res = file_ioctl(_fileIPAPool, IPA_POOL_IOC_ALLOC, (unsigned long)(&ipa_alloc_args));
1265 set_fs(old_fs);
1266 if (res < 0 || ipa_alloc_args.error_code != IPAERROR_OK)
1267 {
1268 MS_U32 each_delay_ms = 50;//empirical value in our test.
1269 MS_U32 now_delay_ms=0;
1270 while(1)
1271 {
1272 // delay and try again
1273 mutex_unlock(&_IPA_POOL_Mutex);
1274
1275 #if DEBUG_IPA_KERNEL_MODE
1276 printk("%s:%d each_delay_ms=%u, delay and try alloc again now_delay_ms=%u\n",__FUNCTION__,__LINE__,each_delay_ms,now_delay_ms);
1277 #endif
1278
1279 ipa_alloc_args.timeout = 0;//into kernel will not consider timeout again
1280 #if TEST_USE_SELF_KO_MAKEFILE
1281 schedule_timeout_interruptible(msecs_to_jiffies(each_delay_ms));
1282 #else
1283 MsOS_DelayTask(each_delay_ms);
1284 #endif
1285 mutex_lock(&_IPA_POOL_Mutex);
1286
1287 old_fs = get_fs();
1288 set_fs(KERNEL_DS);
1289 res = file_ioctl(_fileIPAPool, IPA_POOL_IOC_ALLOC, (unsigned long)(&ipa_alloc_args));
1290 set_fs(old_fs);
1291 if ((res == 0) && (ipa_alloc_args.error_code == IPAERROR_OK))
1292 break;
1293 now_delay_ms += each_delay_ms;
1294 if(now_delay_ms >= timeout_ms)
1295 break;
1296 }
1297 if (res < 0 || ipa_alloc_args.error_code != IPAERROR_OK)
1298 {
1299 printk("%s:%d fail: pool_handle_id %u, offset 0x%llx, len 0x%llx ipa_alloc_args.error_code=0x%x ipa_alloc_args.timeout=%u res=%d\n",__FUNCTION__,__LINE__, get_param->pool_handle_id,
1300 (long long unsigned int)get_param->offset_in_pool, (long long unsigned int)get_param->length,ipa_alloc_args.error_code,ipa_alloc_args.timeout,res);
1301 ret = FALSE;
1302 goto IPA_POOL_GETMEM_DONE;
1303 }
1304 }
1305
1306 get_param->error_code = ipa_alloc_args.error_code;
1307
1308 IPA_POOL_GETMEM_DONE:
1309 mutex_unlock(&_IPA_POOL_Mutex);
1310
1311 return ret;
1312
1313 }
1314
IPA_Pool_Polling_Task(void * argc)1315 int __attribute__((weak)) IPA_Pool_Polling_Task(void *argc)
1316 {
1317 #if 1
1318 printk("%s:%d not realize yet!\n",__FUNCTION__,__LINE__);
1319 return -1;
1320 #else
1321 MS_BOOL ret = TRUE;
1322 int res=0;
1323 MS_U32 idx = 0;
1324 mm_segment_t old_fs;
1325
1326 struct IPA_Pool_Event_Args *pool_event_args =kmalloc(sizeof(struct IPA_Pool_Event_Args),GFP_KERNEL);
1327 if(!pool_event_args)
1328 {
1329 printk("%s:%d alloc fail \n",__FUNCTION__,__LINE__);
1330 return -1;
1331 }
1332
1333 memset(pool_event_args, 0, sizeof(struct IPA_Pool_Event_Args));
1334
1335 struct IPA_Pool_InstallIpcHandle_Param installipchandle_param;
1336 installipchandle_param.ipc_handle_id = (*(MS_U32 *)argc);
1337
1338 ret = MApi_IPA_Pool_InstallIpcHandle(&installipchandle_param);
1339 if(ret == FALSE || installipchandle_param.error_code != 0)
1340 {
1341 printk("%s:%d fail\n",__FUNCTION__,__LINE__);
1342 return -1;
1343 }
1344
1345 MS_U32 pool_handle_id = installipchandle_param.pool_handle_id;
1346
1347
1348 mutex_lock(&_IPA_POOL_Mutex);
1349 if (IS_ERR(_fileIPAPool))
1350 {
1351 printk("%s:%d fail \n",__FUNCTION__,__LINE__);
1352 ret = FALSE;
1353 mutex_unlock(&_IPA_POOL_Mutex);
1354 return -1;
1355 }
1356 pool_event_args->pool_handle_id = pool_handle_id;
1357
1358 ret = _findPoolHandleId_InIPA_Pool_Table(pool_event_args->pool_handle_id, &idx);
1359 mutex_unlock(&_IPA_POOL_Mutex);
1360 if(ret == FALSE)
1361 {
1362 printk("%s:%d fail not find in pool table\n",__FUNCTION__,__LINE__);
1363 return -1;
1364 }
1365 #ifdef DEBUG_IPA_KERNEL_MODE
1366 printk("%s:%d before while\n",__FUNCTION__,__LINE__);
1367 #endif
1368 old_fs = get_fs();
1369 set_fs(KERNEL_DS);
1370
1371 while(1)
1372 {
1373 //ioctl for event and after callback,shoud ioctl again.
1374 //before each ioctl,should clear invalid event value.
1375 memset(pool_event_args,0,sizeof(struct IPA_Pool_Event_Args));
1376 pool_event_args->pool_handle_id = pool_handle_id;
1377 res = file_ioctl(_fileIPAPool,IPA_POOL_IOC_POLL,(unsigned long)pool_event_args);
1378 if(res < 0)
1379 {
1380 printk("%s:%d fail\n",__FUNCTION__,__LINE__);
1381 ret = FALSE;
1382 goto IPA_POOL_POLLING_TASK_DONE;
1383 }
1384
1385 if(IPA_EVENT_NO_WAIT== pool_event_args->event )
1386 {
1387 #ifdef DEBUG_IPA_KERNEL_MODE
1388 printk("%s:%d break\n",__FUNCTION__,__LINE__);
1389 #endif
1390 break;
1391 }
1392 else if(IPA_EVENT_CONFLICT == pool_event_args->event )
1393 {
1394 //invoke callback corresponding to that pool event
1395 IPAPool_Info[idx].polling_callback(pool_event_args->pool_handle_id,pool_event_args->start,pool_event_args->length);//call callback
1396 }
1397 else
1398 {
1399 printk("%s error ,event %d is invalid !!! but continue while\n",__FUNCTION__,pool_event_args->event);
1400 }
1401 }
1402 #ifdef DEBUG_IPA_KERNEL_MODE
1403 printk("%s:%d after while\n",__FUNCTION__,__LINE__);
1404 #endif
1405
1406 IPA_POOL_POLLING_TASK_DONE:
1407
1408 //before return ,set this flag.And this flag will be checked in MApi_IPA_Pool_Release.
1409 IPAPool_Info[idx].polling_thread_delete_task_flag = TRUE;
1410 #ifdef DEBUG_IPA_KERNEL_MODE
1411 printk("%s:%d have set polling_thread_delete_task_flag\n",__FUNCTION__,__LINE__);
1412 #endif
1413 kfree(pool_event_args);
1414
1415 set_fs(old_fs);
1416
1417 #ifdef DEBUG_IPA_KERNEL_MODE
1418 printk("%s:%d \n",__FUNCTION__,__LINE__);
1419 #endif
1420 #endif
1421 return 0;
1422 }
1423
1424 //suggest this API be invoked after MApi_IPA_Pool_Init.
MApi_IPA_Pool_Notify(struct IPA_Pool_Polling_Param * polling_param)1425 MS_BOOL __attribute__((weak)) MApi_IPA_Pool_Notify(struct IPA_Pool_Polling_Param *polling_param)
1426 {
1427 #if 1
1428
1429 printk("[%s:%d]error message no need and can not realize %s for kernel mode utopia ,please use %s in user mode!!!! \n",__FUNCTION__,__LINE__,__FUNCTION__,__FUNCTION__);
1430 BUG();
1431 return false;
1432
1433 #else
1434
1435 MS_BOOL ret = TRUE;
1436 struct task_struct *IPAPolling_struct = NULL;
1437 MS_U32 idx = 0;
1438
1439 printk("%s\n",__FUNCTION__);
1440 mutex_lock(&_IPA_POOL_Mutex);
1441 if(!polling_param->polling_callback)
1442 {
1443 printk("%u have no polling_callback function , %s return directly\n",polling_param->pool_handle_id,__FUNCTION__);
1444 mutex_unlock(&_IPA_POOL_Mutex);
1445 return TRUE;
1446 }
1447
1448 ret = _findPoolHandleId_InIPA_Pool_Table(polling_param->pool_handle_id, &idx);
1449
1450 if(ret == FALSE)//not find idx
1451 {
1452 printk(" %s ipa pool fail not find pool_handle_id %u in pool table\n",__FUNCTION__,polling_param->pool_handle_id);
1453 mutex_unlock(&_IPA_POOL_Mutex);
1454 return FALSE;
1455 }
1456
1457 if(-1 == IPAPool_Info[idx].pthIPAPollingId) //no polling id refer to pool handle id
1458 {
1459
1460 struct IPA_Pool_GetIpcHandle_Param getipchandle_param;
1461 getipchandle_param.pool_handle_id = polling_param->pool_handle_id;
1462
1463 ret = MApi_IPA_Pool_GETIPCHANDLE(&getipchandle_param);
1464 if(ret == FALSE)
1465 {
1466 mutex_unlock(&_IPA_POOL_Mutex);
1467 return ret;
1468 }
1469
1470 //N.B. use kthread_create to create a thread,do not use kernel_thread.
1471 //For kernel_thread use in ko cause many issues in our test.samson.huang 20151105
1472 IPAPolling_struct = kthread_create(IPA_Pool_Polling_Task,(void *)(&(getipchandle_param.ipc_handle_id)),"iap_polling");
1473 if (!IS_ERR(IPAPolling_struct))
1474 {
1475 wake_up_process(IPAPolling_struct);
1476 printk("%s:%d tmp_struct=%p\n",__FUNCTION__,__LINE__,IPAPolling_struct);
1477 }
1478 else
1479 {
1480 printk("%s:%d fail\n",__FUNCTION__,__LINE__);
1481 }
1482 printk("%s:%d debug\n",__FUNCTION__,__LINE__);
1483
1484 if(IS_ERR(IPAPolling_struct))
1485 {
1486 printk("%s can't create thread \n",__FUNCTION__);
1487 ret= FALSE;
1488 mutex_unlock(&_IPA_POOL_Mutex);
1489 return ret;
1490 }
1491 else
1492 {
1493 //corresponding pthIPAPollingId to pool_handle_id
1494 IPAPool_Info[idx].pthIPAPollingId = get_task_pid(IPAPolling_struct, PIDTYPE_PID);
1495 IPAPool_Info[idx].polling_callback = polling_param->polling_callback;
1496 #ifdef DEBUG_IPA_KERNEL_MODE
1497 printk("%s:%d kernel_thread success pthIPAPollingId=%d\n",__FUNCTION__,__LINE__,IPAPool_Info[idx].pthIPAPollingId);
1498 #endif
1499 }
1500 }
1501 else//already have polling id refer to pool handle id.
1502 {
1503 ret=FALSE;
1504 printk("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);
1505 }
1506
1507 mutex_unlock(&_IPA_POOL_Mutex);
1508 #ifdef DEBUG_IPA_KERNEL_MODE
1509 printk("%s:%d success ret=%d\n",__FUNCTION__,__LINE__,ret);
1510 #endif
1511 return ret;
1512
1513 #endif
1514 }
1515
1516 #if (TEST_USE_SELF_KO_MAKEFILE || TEST_USE_SELF_KO_MAKEFILE_TOTAL)//these just test code!!!
1517 #define DFB_TEMP_HID 27
1518
1519 #define PAGE 4096
1520 #define MILLION (1<<20)
1521
1522 static char * Pool_Name1 = "DFB_TEMP";
1523 static char * Pool_Name1_2 = "DFB_TEMP_2";
1524 static char * Pool_Name1_3 = "DFB_TEMP_3";
1525
DFB_callback_id_1(MS_U32 pool_handle_id,MS_U64 start,MS_U64 length)1526 void *DFB_callback_id_1(MS_U32 pool_handle_id,MS_U64 start,MS_U64 length)
1527 {
1528 printk("inside %s ,pool_handle_id=%u\n",__FUNCTION__,pool_handle_id);
1529 }
1530
test_case_2()1531 int test_case_2()
1532 {
1533 bool err;
1534 MS_U32 timeout_ms = 2;
1535 printk("debug in %s \n",__FUNCTION__);
1536
1537 #if 1
1538 printk("[%s:%d] will MApi_IPA_Pool_Init\n",__FUNCTION__,__LINE__);
1539
1540 struct IPA_Pool_Init_Param Init_Param;
1541 Init_Param.heap_id= DFB_TEMP_HID;
1542 Init_Param.pool_name = Pool_Name1;
1543 printk("%s:%d Pool_Name1=%p,Init_Param.pool_name=%s\n",__FUNCTION__,__LINE__,Pool_Name1,Init_Param.pool_name);
1544 Init_Param.offset_in_heap = 6.5*MILLION;
1545 Init_Param.len = 8*MILLION;
1546
1547 #if DEBUG_IPA_KERNEL_MODE
1548 printk("[%s:%d]Init_Param->heap_id=%u,Init_Param->offset=0x%llx,Init_Param->len=0x%llx\n",__FUNCTION__,__LINE__,Init_Param.heap_id
1549 ,Init_Param.offset_in_heap,Init_Param.len);
1550 printk("%s:%d Init_Param.pool_name=%s\n",__FUNCTION__,__LINE__,Init_Param.pool_name);
1551 #endif
1552
1553 err = MApi_IPA_Pool_Init(&Init_Param);
1554 if(err ==FALSE)
1555 {
1556 printk("[%s:%d] ipa_init fail Init_Param->heap_id=%u,Init_Param->offset=0x%llx,Init_Param->len=0x%llx\n",__FUNCTION__,__LINE__,Init_Param.heap_id
1557 ,Init_Param.offset_in_heap,Init_Param.len);
1558 return -1;
1559 }
1560
1561 printk("[%s:%d] will ipa_alloc\n",__FUNCTION__,__LINE__);
1562 struct IPA_Pool_GetMem_Param get_param;
1563 get_param.pool_handle_id=Init_Param.pool_handle_id;
1564 get_param.offset_in_pool=0;
1565 get_param.length= PAGE;
1566 err = MApi_IPA_Pool_GetMem_Timeout(&get_param,timeout_ms);
1567 printk("[%s:%d] after ipa_alloc get_param.pool_handle_id=%u\n",__FUNCTION__,__LINE__,get_param.pool_handle_id);
1568 if(err ==FALSE)
1569 {
1570 printk("[%s:%d] err return\n",__FUNCTION__,__LINE__);
1571 return -1;
1572 }
1573 #endif
1574
1575 struct IPA_Pool_Polling_Param polling_param;
1576 polling_param.pool_handle_id = Init_Param.pool_handle_id;
1577 printk("[%s:%d] \n",__FUNCTION__,__LINE__);
1578 polling_param.polling_callback=DFB_callback_id_1;
1579 printk("[%s:%d] polling_param.pool_handle_id=%u\n",__FUNCTION__,__LINE__,polling_param.pool_handle_id);
1580 MApi_IPA_Pool_Notify(&polling_param);
1581 printk("[%s:%d] \n",__FUNCTION__,__LINE__);
1582
1583 //must delay before free to ensure polling having sleep��
1584 printk("before sleep\n");
1585
1586 #if 0
1587 while(1);
1588 #else
1589 schedule_timeout_interruptible(msecs_to_jiffies(1000));
1590 schedule_timeout_interruptible(msecs_to_jiffies(1000));
1591 /*schedule_timeout_interruptible(msecs_to_jiffies(1000));
1592 schedule_timeout_interruptible(msecs_to_jiffies(1000));
1593 schedule_timeout_interruptible(msecs_to_jiffies(1000));
1594 schedule_timeout_interruptible(msecs_to_jiffies(1000));
1595 schedule_timeout_interruptible(msecs_to_jiffies(1000));
1596 schedule_timeout_interruptible(msecs_to_jiffies(1000));
1597 schedule_timeout_interruptible(msecs_to_jiffies(1000));
1598 schedule_timeout_interruptible(msecs_to_jiffies(1000));
1599 schedule_timeout_interruptible(msecs_to_jiffies(1000));
1600 schedule_timeout_interruptible(msecs_to_jiffies(1000));
1601 schedule_timeout_interruptible(msecs_to_jiffies(1000));
1602 schedule_timeout_interruptible(msecs_to_jiffies(1000));
1603 schedule_timeout_interruptible(msecs_to_jiffies(1000)); */
1604
1605 printk("after sleep\n");
1606 printk("[%s:%d] before MApi_IPA_Pool_PutMem\n",__FUNCTION__,__LINE__);
1607 struct IPA_Pool_PutMem_Param put_param;
1608 put_param.length=PAGE;
1609 put_param.offset_in_pool=0;
1610 put_param.pool_handle_id =Init_Param.pool_handle_id;
1611 err = MApi_IPA_Pool_PutMem(&put_param);
1612 if(err ==FALSE)
1613 {
1614 printk("[%s:%d] err return\n",__FUNCTION__,__LINE__);
1615 return -1;
1616 }
1617
1618 #if 1
1619 printk(" %s before MApi_IPA_Pool_Release \n",__FUNCTION__);
1620 err = MApi_IPA_Pool_Release(Init_Param.pool_handle_id);
1621 printk(" %s after MApi_IPA_Pool_Release err=%d\n",__FUNCTION__,err);
1622 if(err == FALSE)
1623 {
1624 printk("[%s:%d] err return\n",__FUNCTION__,__LINE__);
1625 return -1;
1626 }
1627 #endif
1628
1629 #endif
1630
1631 return 0;
1632 }
1633
1634 #endif
1635 #if TEST_USE_SELF_KO_MAKEFILE
1636
drvIPAPool_init(void)1637 static int drvIPAPool_init(void)
1638 {
1639 printk(KERN_ERR"%s !!! \n",__FUNCTION__);
1640
1641 //test_case_2();
1642
1643 return 0;
1644 }
1645
drvIPAPool_exit(void)1646 static void drvIPAPool_exit(void)
1647 {
1648 printk(KERN_ERR"%s !!! \n",__FUNCTION__);
1649 }
1650
1651 module_init(drvIPAPool_init);
1652 module_exit(drvIPAPool_exit);
1653 MODULE_LICENSE("GPL");
1654 MODULE_AUTHOR("Mstar");
1655 MODULE_DESCRIPTION("A module used for drvIPAPool!");
1656 #endif
1657
1658
1659 #endif
1660