1 /*
2 *
3 * Copyright 2013 Rockchip Electronics Co., LTD.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /*
19 * @file Rockchip_OSAL_SharedMemory.c
20 * @brief
21 * @author csy(csy@rock-chips.com)
22 * @version 1.0.0
23 * @history
24 * 2013.11.26 : Create
25 */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <securec.h>
32 #include <pthread.h>
33 #include <unistd.h>
34 #ifndef OHOS
35 #include <cutils/log.h>
36 #include <cutils/atomic.h>
37 #include <cutils/native_handle.h>
38 #endif
39 #include <fcntl.h>
40 #include <sys/ioctl.h>
41 #include <sys/mman.h>
42
43 #include "vpu.h"
44
45 #include <dlfcn.h>
46 #include "drm_mode.h"
47 #include "drm.h"
48 #include "Rockchip_OSAL_Mutex.h"
49 #include "Rockchip_OSAL_SharedMemory.h"
50 #define ROCKCHIP_LOG_OFF
51 #include "Rockchip_OSAL_Log.h"
52
53 #ifndef ION_SECURE_HEAP_ID
54 #define ION_SECURE_HEAP_ID ION_CMA_HEAP_ID
55 #endif
56
57 static int mem_cnt = 0;
58 static int mem_type = MEMORY_TYPE_ION;
59
60 struct ROCKCHIP_SHAREDMEM_LIST;
61 typedef struct _ROCKCHIP_SHAREDMEM_LIST {
62 RK_U32 ion_hdl;
63 OMX_PTR mapAddr;
64 OMX_U32 allocSize;
65 OMX_BOOL owner;
66 struct _ROCKCHIP_SHAREDMEM_LIST *pNextMemory;
67 } ROCKCHIP_SHAREDMEM_LIST;
68
69 typedef struct _ROCKCHIP_SHARED_MEMORY {
70 int fd;
71 ROCKCHIP_SHAREDMEM_LIST *pAllocMemory;
72 OMX_HANDLETYPE hSMMutex;
73 } ROCKCHIP_SHARED_MEMORY;
74
75 #define ION_FUNCTION (0x00000001)
76 #define ION_DEVICE (0x00000002)
77 #define ION_CLINET (0x00000004)
78 #define ION_IOCTL (0x00000008)
79
ion_ioctl(int fd,int req,void * arg)80 static int ion_ioctl(int fd, int req, void *arg)
81 {
82 int ret = ioctl(fd, req, arg);
83 if (ret < 0) {
84 omx_err("ion_ioctl %x failed with code %d: %s\n", req,
85 ret, strerror(errno));
86 return -errno;
87 }
88 return ret;
89 }
90
ion_alloc(int fd,size_t len,size_t align,unsigned int heap_mask,unsigned int flags,ion_user_handle_t * handle)91 static int ion_alloc(int fd, size_t len, size_t align, unsigned int heap_mask,
92 unsigned int flags, ion_user_handle_t *handle)
93 {
94 int ret;
95 struct ion_allocation_data data = {
96 .len = len,
97 .align = align,
98 .heap_id_mask = heap_mask,
99 .flags = flags,
100 };
101
102 if (handle == NULL) {
103 return -EINVAL;
104 }
105
106 ret = ion_ioctl(fd, ION_IOC_ALLOC, &data);
107 if (ret < 0) {
108 return ret;
109 }
110
111 *handle = data.handle;
112 return ret;
113 }
114
ion_free(int fd,ion_user_handle_t handle)115 static int ion_free(int fd, ion_user_handle_t handle)
116 {
117 struct ion_handle_data data = {
118 .handle = handle,
119 };
120 return ion_ioctl(fd, ION_IOC_FREE, &data);
121 }
122
ion_map(int fd,ion_user_handle_t handle,size_t length,int prot,int flags,off_t offset,unsigned char ** ptr,int * map_fd)123 static int ion_map(int fd, ion_user_handle_t handle, size_t length, int prot,
124 int flags, off_t offset, unsigned char **ptr, int *map_fd)
125 {
126 int ret;
127 struct ion_fd_data data = {
128 .handle = handle,
129 };
130
131 if (map_fd == NULL) {
132 return -EINVAL;
133 }
134
135 if (ptr == NULL) {
136 return -EINVAL;
137 }
138
139 ret = ion_ioctl(fd, ION_IOC_MAP, &data);
140 if (ret < 0) {
141 return ret;
142 }
143
144 *map_fd = data.fd;
145 if (*map_fd < 0) {
146 omx_err("map ioctl returned negative fd\n");
147 return -EINVAL;
148 }
149 *ptr = mmap(NULL, length, prot, flags, *map_fd, offset);
150 if (*ptr == MAP_FAILED) {
151 omx_err("mmap failed: %s\n", strerror(errno));
152 return -errno;
153 }
154 return ret;
155 }
156
ion_import(int fd,int share_fd,ion_user_handle_t * handle)157 int ion_import(int fd, int share_fd, ion_user_handle_t *handle)
158 {
159 int ret;
160 struct ion_fd_data data = {
161 .fd = share_fd,
162 };
163
164 if (handle == NULL) {
165 return -EINVAL;
166 }
167
168 ret = ion_ioctl(fd, ION_IOC_IMPORT, &data);
169 if (ret < 0) {
170 return ret;
171 }
172
173 *handle = data.handle;
174 return ret;
175 }
176
ion_get_phys(int fd,ion_user_handle_t handle,unsigned long * phys)177 int ion_get_phys(int fd, ion_user_handle_t handle, unsigned long *phys)
178 {
179 struct ion_phys_data phys_data;
180 struct ion_custom_data data;
181
182 phys_data.handle = handle;
183 phys_data.phys = 0;
184
185 data.cmd = ION_IOC_GET_PHYS;
186 data.arg = (unsigned long)&phys_data;
187
188 int ret = ion_ioctl(fd, ION_IOC_CUSTOM, &data);
189 omx_err("ion_get_phys:phys_data.phys = ox%lx", phys_data.phys);
190 omx_err("ion_get_phys:phys_data.size = %ld", phys_data.size);
191 if (ret < 0) {
192 return ret;
193 }
194
195 *phys = phys_data.phys;
196
197 return 0;
198 }
199
drm_ioctl(int fd,int req,void * arg)200 static int drm_ioctl(int fd, int req, void *arg)
201 {
202 int ret;
203
204 do {
205 ret = ioctl(fd, req, arg);
206 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
207
208 return ret;
209 }
210
211
212 typedef void *(*func_mmap64)(void* addr, size_t length, int prot, int flags,
213 int fd, off_t offset);
214 static func_mmap64 mpp_rt_mmap64 = NULL;
215
mpp_rt_get_mmap64(void)216 func_mmap64 mpp_rt_get_mmap64(void)
217 {
218 static RK_U32 once = 1;
219
220 if (once) {
221 void *libc_hdl = dlopen("libc", RTLD_LAZY);
222 if (libc_hdl) {
223 mpp_rt_mmap64 = (func_mmap64)dlsym(libc_hdl, "mmap64");
224 dlclose(libc_hdl);
225 }
226
227 once = 0;
228 }
229
230 return mpp_rt_mmap64;
231 }
232
drm_mmap(int fd,size_t len,int prot,int flags,loff_t offset)233 static void* drm_mmap(int fd, size_t len, int prot, int flags, loff_t offset)
234 {
235 static unsigned long pagesize_mask = 0;
236
237 if (fd < 0) {
238 return NULL;
239 }
240
241 if (!pagesize_mask) {
242 pagesize_mask = sysconf(_SC_PAGESIZE) - 1;
243 }
244
245 len = (len + pagesize_mask) & ~pagesize_mask;
246
247 if (offset & 4095) { // 4095:byte alignment
248 return NULL;
249 }
250
251 return mmap64(NULL, len, prot, flags, fd, offset);
252 }
253
drm_handle_to_fd(int fd,RK_U32 handle,int * map_fd,RK_U32 flags)254 static int drm_handle_to_fd(int fd, RK_U32 handle, int *map_fd, RK_U32 flags)
255 {
256 int ret;
257 struct drm_prime_handle dph;
258 memset_s(&dph, sizeof(struct drm_prime_handle), 0, sizeof(struct drm_prime_handle));
259 dph.handle = handle;
260 dph.fd = -1;
261 dph.flags = flags;
262
263 if (map_fd == NULL) {
264 return -EINVAL;
265 }
266
267 ret = drm_ioctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &dph);
268 if (ret < 0) {
269 return ret;
270 }
271
272 *map_fd = dph.fd;
273 if (*map_fd < 0) {
274 omx_err("map ioctl returned negative fd\n");
275 return -EINVAL;
276 }
277
278 return ret;
279 }
280
281 #ifdef AVS80
drm_fd_to_handle(int fd,int map_fd,RK_U32 * handle,RK_U32 flags)282 static int drm_fd_to_handle(int fd, int map_fd, RK_U32 *handle, RK_U32 flags)
283 {
284 int ret;
285 struct drm_prime_handle dph;
286
287 dph.fd = map_fd;
288 dph.flags = flags;
289
290 ret = drm_ioctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &dph);
291 if (ret < 0) {
292 return ret;
293 }
294
295 *handle = dph.handle;
296 return ret;
297 }
298 #endif
299
drm_map(int fd,RK_U32 handle,size_t length,int prot,int flags,unsigned char ** ptr,int * map_fd)300 static int drm_map(int fd, RK_U32 handle, size_t length, int prot,
301 int flags, unsigned char **ptr, int *map_fd)
302 {
303 int ret;
304 struct drm_mode_map_dumb dmmd;
305 memset_s(&dmmd, sizeof(dmmd), 0, sizeof(dmmd));
306 dmmd.handle = handle;
307
308 if (map_fd == NULL) {
309 return -EINVAL;
310 }
311
312 if (ptr == NULL) {
313 return -EINVAL;
314 }
315
316 ret = drm_handle_to_fd(fd, handle, map_fd, 0);
317 omx_err("drm_map fd %d", *map_fd);
318 if (ret < 0) {
319 return ret;
320 }
321
322 ret = drm_ioctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &dmmd);
323 if (ret < 0) {
324 omx_err("drm_map FAIL");
325 close(*map_fd);
326 return ret;
327 }
328
329 omx_trace("dev fd %d length %d", fd, length);
330
331 *ptr = drm_mmap(fd, length, prot, flags, dmmd.offset);
332 if (*ptr == MAP_FAILED) {
333 close(*map_fd);
334 *map_fd = -1;
335 omx_err("mmap failed: %s\n", strerror(errno));
336 return -errno;
337 }
338
339 return ret;
340 }
341
drm_alloc(int fd,size_t len,size_t align,RK_U32 * handle,int flag)342 static int drm_alloc(int fd, size_t len, size_t align, RK_U32 *handle, int flag)
343 {
344 int ret;
345 struct drm_mode_create_dumb dmcb;
346
347 memset_s(&dmcb, sizeof(struct drm_mode_create_dumb), 0, sizeof(struct drm_mode_create_dumb));
348 dmcb.bpp = 8; // 8:value of dmcb.bpp
349 dmcb.width = (len + align - 1) & (~(align - 1));
350 dmcb.height = 1;
351 dmcb.size = dmcb.width * dmcb.bpp;
352 dmcb.flags = flag;
353
354 if (handle == NULL)
355 return -1;
356
357 ret = drm_ioctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &dmcb);
358 if (ret < 0) {
359 omx_err("drm_alloc fail: ret = %d", ret);
360 return ret;
361 }
362 *handle = dmcb.handle;
363
364 omx_trace("drm_alloc success: handle %d size %llu", *handle, dmcb.size);
365
366 return ret;
367 }
368
drm_free(int fd,RK_U32 handle)369 static int drm_free(int fd, RK_U32 handle)
370 {
371 struct drm_mode_destroy_dumb data = {
372 .handle = handle,
373 };
374 return drm_ioctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &data);
375 }
376
377 #ifdef AVS80
Rockchip_OSAL_SharedMemory_HandleToAddress(OMX_HANDLETYPE handle,OMX_HANDLETYPE handle_ptr)378 OMX_U32 Rockchip_OSAL_SharedMemory_HandleToAddress(OMX_HANDLETYPE handle, OMX_HANDLETYPE handle_ptr)
379 {
380 int map_fd = -1;
381 native_handle_t* pnative_handle_t = NULL;
382 RK_S32 err = 0;
383 RK_S32 mClient = 0;
384 RK_U32 mHandle = 0;
385 struct drm_rockchip_gem_phys phys_arg;
386
387 (void)handle;
388
389 pnative_handle_t = (native_handle_t*)handle_ptr;
390 map_fd = pnative_handle_t->data[0];
391
392 mClient = open("/dev/dri/card0", O_RDWR);
393 if (mClient < 0) {
394 omx_err("Rockchip_OSAL_SharedMemory_HandleToAddress open drm fail");
395 return 0;
396 }
397 drm_fd_to_handle(mClient, (int32_t)map_fd, &mHandle, 0);
398 phys_arg.handle = mHandle;
399 err = drm_ioctl(mClient, DRM_IOCTL_ROCKCHIP_GEM_GET_PHYS, &phys_arg);
400 if (err)
401 omx_err("failed to get phy address: %s\n", strerror(errno));
402
403 close(mClient);
404 mClient = -1;
405 return (OMX_U32)phys_arg.phy_addr;
406 }
407
Rockchip_OSAL_SharedMemory_HandleToSecureAddress(OMX_HANDLETYPE handle,OMX_HANDLETYPE handle_ptr,RK_S32 size)408 OMX_U32 Rockchip_OSAL_SharedMemory_HandleToSecureAddress(OMX_HANDLETYPE handle, OMX_HANDLETYPE handle_ptr, RK_S32 size)
409 {
410 int map_fd = -1;
411 native_handle_t* pnative_handle_t = NULL;
412 RK_S32 err = 0;
413 RK_S32 mClient = 0;
414 RK_U32 mHandle = 0;
415 RK_U8* pBuffer = NULL;
416 int ret;
417 struct drm_mode_map_dumb dmmd;
418 memset_s(&dmmd, sizeof(dmmd), 0, sizeof(dmmd));
419 (void)handle;
420
421 pnative_handle_t = (native_handle_t*)handle_ptr;
422 map_fd = pnative_handle_t->data[0];
423
424 mClient = open("/dev/dri/card0", O_RDWR);
425 if (mClient < 0) {
426 omx_err("Rockchip_OSAL_SharedMemory_HandleToAddress open drm fail");
427 return 0;
428 }
429 drm_fd_to_handle(mClient, (int32_t)map_fd, &mHandle, 0);
430 dmmd.handle = mHandle;
431
432 ret = drm_ioctl(mClient, DRM_IOCTL_MODE_MAP_DUMB, &dmmd);
433 if (ret < 0) {
434 close(mClient);
435 mClient = -1;
436 omx_err("drm_ioctl DRM_IOCTL_MODE_MAP_DUMB failed: %s\n", strerror(errno));
437 return ret;
438 }
439
440 pBuffer = (uint8_t*)drm_mmap(mClient, size, PROT_READ | PROT_WRITE, MAP_SHARED, dmmd.offset);
441 if (pBuffer == MAP_FAILED) {
442 close(mClient);
443 mClient = -1;
444 omx_err("mmap failed:fd = %d,length = %d, %s\n", mClient, size, strerror(errno));
445 return -errno;
446 }
447
448 close(mClient);
449 mClient = -1;
450 return (OMX_U32)pBuffer;
451 }
452 #endif
453
Rockchip_OSAL_SharedMemory_SecureUnmap(OMX_HANDLETYPE handle,OMX_HANDLETYPE handle_ptr,RK_S32 size)454 void Rockchip_OSAL_SharedMemory_SecureUnmap(OMX_HANDLETYPE handle, OMX_HANDLETYPE handle_ptr, RK_S32 size)
455 {
456 (void)handle;
457 if (munmap(handle_ptr, size)) {
458 omx_err("ion_unmap fail");
459 }
460 }
461
Rockchip_OSAL_SharedMemory_Open()462 OMX_HANDLETYPE Rockchip_OSAL_SharedMemory_Open()
463 {
464 ROCKCHIP_SHARED_MEMORY *pHandle = NULL;
465 int SharedMemoryClient = 0;
466
467 pHandle = (ROCKCHIP_SHARED_MEMORY *)malloc(sizeof(ROCKCHIP_SHARED_MEMORY));
468 Rockchip_OSAL_Memset(pHandle, 0, sizeof(ROCKCHIP_SHARED_MEMORY));
469 if (pHandle == NULL) {
470 goto EXIT;
471 }
472 if (!access("/dev/dri/card0", F_OK)) {
473 SharedMemoryClient = open("/dev/dri/card0", O_RDWR);
474 mem_type = MEMORY_TYPE_DRM;
475 } else {
476 SharedMemoryClient = open("/dev/ion", O_RDWR);
477 mem_type = MEMORY_TYPE_ION;
478 }
479
480 if (SharedMemoryClient <= 0) {
481 omx_err("SharedMemoryClient create Error: %d", SharedMemoryClient);
482 Rockchip_OSAL_Free((void *)pHandle);
483 pHandle = NULL;
484 goto EXIT;
485 }
486
487 pHandle->fd = SharedMemoryClient;
488
489 Rockchip_OSAL_MutexCreate(&pHandle->hSMMutex);
490
491 EXIT:
492 return (OMX_HANDLETYPE)pHandle;
493 }
494
Rockchip_OSAL_SharedMemory_Close(OMX_HANDLETYPE handle,OMX_BOOL b_secure)495 void Rockchip_OSAL_SharedMemory_Close(OMX_HANDLETYPE handle, OMX_BOOL b_secure)
496 {
497 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
498 ROCKCHIP_SHAREDMEM_LIST *pSMList = NULL;
499 ROCKCHIP_SHAREDMEM_LIST *pCurrentElement = NULL;
500 ROCKCHIP_SHAREDMEM_LIST *pDeleteElement = NULL;
501
502 if (pHandle == NULL) {
503 goto EXIT;
504 }
505
506 Rockchip_OSAL_MutexLock(pHandle->hSMMutex);
507 pCurrentElement = pSMList = pHandle->pAllocMemory;
508
509 while (pCurrentElement != NULL) {
510 pDeleteElement = pCurrentElement;
511 pCurrentElement = pCurrentElement->pNextMemory;
512 if (b_secure) {
513 #ifdef AVS80
514 native_handle_t* pnative_handle_t = NULL;
515 int map_fd = 0;
516 void *pTrueAddree = NULL;
517 pnative_handle_t = (native_handle_t*)pDeleteElement->mapAddr;
518 map_fd = pnative_handle_t->data[0];
519 pTrueAddree = (void *)Rockchip_OSAL_SharedMemory_HandleToSecureAddress(handle,
520 pDeleteElement->mapAddr, pDeleteElement->allocSize);
521 pDeleteElement->mapAddr = pTrueAddree;
522 close(map_fd);
523 map_fd = -1;
524 #endif
525 }
526 if (munmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
527 omx_err("ion_unmap fail");
528 }
529 pDeleteElement->mapAddr = NULL;
530 pDeleteElement->allocSize = 0;
531
532 if (pDeleteElement->owner) {
533 if (mem_type == MEMORY_TYPE_ION) {
534 ion_free(pHandle->fd, pDeleteElement->ion_hdl);
535 } else {
536 drm_free(pHandle->fd, pDeleteElement->ion_hdl);
537 }
538 }
539 pDeleteElement->ion_hdl = -1;
540
541 Rockchip_OSAL_Free(pDeleteElement);
542
543 mem_cnt--;
544 omx_trace("SharedMemory free count: %d", mem_cnt);
545 }
546
547 pHandle->pAllocMemory = pSMList = NULL;
548 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
549
550 Rockchip_OSAL_MutexTerminate(pHandle->hSMMutex);
551 pHandle->hSMMutex = NULL;
552
553 close(pHandle->fd);
554
555 pHandle->fd = -1;
556
557 Rockchip_OSAL_Free(pHandle);
558
559 EXIT:
560 return;
561 }
562
ion_custom_op(int ion_client,int op,void * op_data)563 static int ion_custom_op(int ion_client, int op, void *op_data)
564 {
565 struct ion_custom_data data;
566 int err;
567 data.cmd = op;
568 data.arg = (unsigned long)op_data;
569 err = ioctl(ion_client, ION_IOC_CUSTOM, &data);
570 if (err < 0) {
571 omx_err("ION_IOC_CUSTOM (%d) failed with error - %s", op, strerror(errno));
572 return err;
573 }
574 return err;
575 }
576
Rockchip_OSAL_SharedMemory_Alloc(OMX_HANDLETYPE handle,OMX_U32 size,MEMORY_TYPE memoryType)577 OMX_PTR Rockchip_OSAL_SharedMemory_Alloc(OMX_HANDLETYPE handle, OMX_U32 size, MEMORY_TYPE memoryType)
578 {
579 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
580 ROCKCHIP_SHAREDMEM_LIST *pSMList = NULL;
581 ROCKCHIP_SHAREDMEM_LIST *pElement = NULL;
582 ROCKCHIP_SHAREDMEM_LIST *pCurrentElement = NULL;
583 OMX_U32 ion_hdl = 0;
584 OMX_PTR pBuffer = NULL;
585 unsigned int mask;
586 unsigned int flag = 0;
587 int err = 0;
588 int map_fd = -1;
589
590 if (pHandle == NULL) {
591 goto EXIT;
592 }
593
594 pElement = (ROCKCHIP_SHAREDMEM_LIST *)malloc(sizeof(ROCKCHIP_SHAREDMEM_LIST));
595 Rockchip_OSAL_Memset(pElement, 0, sizeof(ROCKCHIP_SHAREDMEM_LIST));
596 pElement->owner = OMX_TRUE;
597
598 switch (memoryType) {
599 case SECURE_MEMORY:
600 mask = ION_HEAP(ION_SECURE_HEAP_ID);
601 omx_info("pHandle->fd = %d,size = %lu, mem_type = %d", pHandle->fd, size, mem_type);
602 if (mem_type == MEMORY_TYPE_DRM) {
603 err = drm_alloc(pHandle->fd, size, 4096, (RK_U32 *)&ion_hdl, 0); // 40966:byte alignment
604 } else {
605 err = ion_alloc(pHandle->fd, size,
606 4096, mask, 0, (ion_user_handle_t *)&ion_hdl); // 4096:byte alignment
607 }
608 if (err) {
609 omx_err("ion_alloc failed with err (%d)", err);
610 goto EXIT;
611 }
612 if (err) {
613 omx_err("failed to get phy address: %s\n", strerror(errno));
614 goto EXIT;
615 }
616
617 pElement->allocSize = size;
618 pElement->ion_hdl = ion_hdl;
619 pElement->pNextMemory = NULL;
620
621 #ifdef AVS80
622 native_handle_t* pnative_handle_t = NULL;
623 pnative_handle_t = native_handle_create(1, 0);
624 err = drm_handle_to_fd(pHandle->fd, ion_hdl, &map_fd, 0);
625 if (err < 0) {
626 omx_err("failed to trans handle to fd: %s\n", strerror(errno));
627 goto EXIT;
628 }
629 omx_trace("pnative_handle_t = %p, map_fd = %d, handle = %d", pnative_handle_t, map_fd, ion_hdl);
630 pnative_handle_t->data[0] = map_fd;
631 pBuffer = (void *)pnative_handle_t;
632 if (mem_type == MEMORY_TYPE_DRM) {
633 pElement->mapAddr = (OMX_PTR)((__u64)pnative_handle_t);
634 } else {
635 pElement->mapAddr = (OMX_PTR)((__u64)pnative_handle_t);
636 }
637 #endif
638 break;
639 case SYSTEM_MEMORY:
640 mask = ION_HEAP(ION_VMALLOC_HEAP_ID);
641 err = ion_alloc((int)pHandle->fd, size,
642 4096, mask, flag, (ion_user_handle_t *)&ion_hdl); // 4096:byte alignment
643 if (err < 0) {
644 omx_err("ion_alloc Error: %lu", ion_hdl);
645 Rockchip_OSAL_Free((OMX_PTR)pElement);
646 goto EXIT;
647 }
648
649 err = ion_map((int)pHandle->fd, ion_hdl, size, PROT_READ | PROT_WRITE,
650 MAP_SHARED, (off_t)0, (unsigned char**)&pBuffer, &map_fd);
651 if (err) {
652 omx_err("ion_map Error");
653 ion_free(pHandle->fd, ion_hdl);
654 Rockchip_OSAL_Free((OMX_PTR)pElement);
655 pBuffer = NULL;
656 goto EXIT;
657 }
658
659 pElement->ion_hdl = ion_hdl;
660 pElement->mapAddr = pBuffer;
661 pElement->allocSize = size;
662 pElement->pNextMemory = NULL;
663 break;
664 default:
665 pBuffer = NULL;
666 goto EXIT;
667 break;
668 }
669
670 Rockchip_OSAL_MutexLock(pHandle->hSMMutex);
671 pSMList = pHandle->pAllocMemory;
672 if (pSMList == NULL) {
673 pHandle->pAllocMemory = pSMList = pElement;
674 } else {
675 pCurrentElement = pSMList;
676 while (pCurrentElement->pNextMemory != NULL) {
677 pCurrentElement = pCurrentElement->pNextMemory;
678 }
679 pCurrentElement->pNextMemory = pElement;
680 }
681 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
682
683 mem_cnt++;
684 omx_trace("SharedMemory alloc count: %d", mem_cnt);
685
686 EXIT:
687 return pBuffer;
688 }
689
Rockchip_OSAL_SharedMemory_Free(OMX_HANDLETYPE handle,OMX_PTR pBuffer)690 void Rockchip_OSAL_SharedMemory_Free(OMX_HANDLETYPE handle, OMX_PTR pBuffer)
691 {
692 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
693 ROCKCHIP_SHAREDMEM_LIST *pSMList = NULL;
694 ROCKCHIP_SHAREDMEM_LIST *pCurrentElement = NULL;
695 ROCKCHIP_SHAREDMEM_LIST *pDeleteElement = NULL;
696
697 if (pHandle == NULL) {
698 goto EXIT;
699 }
700
701 Rockchip_OSAL_MutexLock(pHandle->hSMMutex);
702 pSMList = pHandle->pAllocMemory;
703 if (pSMList == NULL) {
704 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
705 goto EXIT;
706 }
707
708 pCurrentElement = pSMList;
709 if (pSMList->mapAddr == pBuffer) {
710 pDeleteElement = pSMList;
711 pHandle->pAllocMemory = pSMList = pSMList->pNextMemory;
712 } else {
713 while ((pCurrentElement != NULL) && (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
714 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr != pBuffer))
715 pCurrentElement = pCurrentElement->pNextMemory;
716
717 if ((((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
718 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr == pBuffer)) {
719 pDeleteElement = pCurrentElement->pNextMemory;
720 pCurrentElement->pNextMemory = pDeleteElement->pNextMemory;
721 } else {
722 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
723 omx_err("Can not find SharedMemory");
724 goto EXIT;
725 }
726 }
727 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
728 if (munmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
729 omx_err("ion_unmap fail");
730 goto EXIT;
731 }
732 pDeleteElement->mapAddr = NULL;
733 pDeleteElement->allocSize = 0;
734
735 if (pDeleteElement->owner) {
736 if (mem_cnt == MEMORY_TYPE_ION) {
737 ion_free(pHandle->fd, (ion_user_handle_t)pDeleteElement->ion_hdl);
738 } else {
739 drm_free(pHandle->fd, pDeleteElement->ion_hdl);
740 }
741 }
742 pDeleteElement->ion_hdl = -1;
743
744 Rockchip_OSAL_Free(pDeleteElement);
745
746 mem_cnt--;
747 omx_trace("SharedMemory free count: %d", mem_cnt);
748
749 EXIT:
750 return;
751 }
752
Rockchip_OSAL_SharedMemory_Map(OMX_HANDLETYPE handle,OMX_U32 size,int ion_hdl)753 OMX_PTR Rockchip_OSAL_SharedMemory_Map(OMX_HANDLETYPE handle, OMX_U32 size, int ion_hdl)
754 {
755 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
756 ROCKCHIP_SHAREDMEM_LIST *pSMList = NULL;
757 ROCKCHIP_SHAREDMEM_LIST *pElement = NULL;
758 ROCKCHIP_SHAREDMEM_LIST *pCurrentElement = NULL;
759 OMX_PTR pBuffer = NULL;
760 int err = 0;
761 int map_fd = -1;
762
763 if (pHandle == NULL) {
764 goto EXIT;
765 }
766
767 pElement = Rockchip_OSAL_Malloc(sizeof(ROCKCHIP_SHAREDMEM_LIST));
768 Rockchip_OSAL_Memset(pElement, 0, sizeof(ROCKCHIP_SHAREDMEM_LIST));
769
770 if (ion_hdl == -1) {
771 omx_err("ion_alloc Error: %d", ion_hdl);
772 Rockchip_OSAL_Free((void*)pElement);
773 goto EXIT;
774 }
775 if (mem_type == MEMORY_TYPE_ION) {
776 err = ion_map(pHandle->fd, (ion_user_handle_t)ion_hdl, size, PROT_READ | PROT_WRITE,
777 MAP_SHARED, (off_t)0, (unsigned char**)&pBuffer, &map_fd);
778 if (pBuffer == NULL) {
779 omx_err("ion_map Error");
780 ion_free(pHandle->fd, (ion_user_handle_t)ion_hdl);
781 Rockchip_OSAL_Free((void*)pElement);
782 goto EXIT;
783 }
784 } else {
785 err = drm_map(pHandle->fd, ion_hdl, size, PROT_READ | PROT_WRITE,
786 MAP_SHARED, (unsigned char**)&pBuffer, &map_fd);
787 if (pBuffer == NULL) {
788 omx_err("ion_map Error");
789 drm_free(pHandle->fd, ion_hdl);
790 Rockchip_OSAL_Free((void*)pElement);
791 goto EXIT;
792 }
793 }
794
795 pElement->ion_hdl = ion_hdl;
796 pElement->mapAddr = pBuffer;
797 pElement->allocSize = size;
798 pElement->pNextMemory = NULL;
799
800 Rockchip_OSAL_MutexLock(pHandle->hSMMutex);
801 pSMList = pHandle->pAllocMemory;
802 if (pSMList == NULL) {
803 pHandle->pAllocMemory = pSMList = pElement;
804 } else {
805 pCurrentElement = pSMList;
806 while (pCurrentElement->pNextMemory != NULL) {
807 pCurrentElement = pCurrentElement->pNextMemory;
808 }
809 pCurrentElement->pNextMemory = pElement;
810 }
811 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
812
813 mem_cnt++;
814 omx_trace("SharedMemory alloc count: %d", mem_cnt);
815
816 EXIT:
817 return pBuffer;
818 }
819
Rockchip_OSAL_SharedMemory_Unmap(OMX_HANDLETYPE handle,int ionfd)820 void Rockchip_OSAL_SharedMemory_Unmap(OMX_HANDLETYPE handle, int ionfd)
821 {
822 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
823 ROCKCHIP_SHAREDMEM_LIST *pSMList = NULL;
824 ROCKCHIP_SHAREDMEM_LIST *pCurrentElement = NULL;
825 ROCKCHIP_SHAREDMEM_LIST *pDeleteElement = NULL;
826
827 if (pHandle == NULL) {
828 goto EXIT;
829 }
830
831 Rockchip_OSAL_MutexLock(pHandle->hSMMutex);
832 pSMList = pHandle->pAllocMemory;
833 if (pSMList == NULL) {
834 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
835 goto EXIT;
836 }
837
838 pCurrentElement = pSMList;
839 if (pSMList->ion_hdl == (RK_U32)ionfd) {
840 pDeleteElement = pSMList;
841 pHandle->pAllocMemory = pSMList = pSMList->pNextMemory;
842 } else {
843 while ((pCurrentElement != NULL) && (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
844 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->ion_hdl != (RK_U32)ionfd))
845 pCurrentElement = pCurrentElement->pNextMemory;
846
847 if ((((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
848 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->ion_hdl == (RK_U32)ionfd)) {
849 pDeleteElement = pCurrentElement->pNextMemory;
850 pCurrentElement->pNextMemory = pDeleteElement->pNextMemory;
851 } else {
852 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
853 omx_err("Can not find SharedMemory");
854 goto EXIT;
855 }
856 }
857 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
858
859 if (munmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
860 omx_err("ion_unmap fail");
861 goto EXIT;
862 }
863 pDeleteElement->mapAddr = NULL;
864 pDeleteElement->allocSize = 0;
865 pDeleteElement->ion_hdl = -1;
866
867 Rockchip_OSAL_Free(pDeleteElement);
868
869 mem_cnt--;
870 omx_trace("SharedMemory free count: %d", mem_cnt);
871
872 EXIT:
873 return;
874 }
875
Rockchip_OSAL_SharedMemory_VirtToION(OMX_HANDLETYPE handle,OMX_PTR pBuffer)876 int Rockchip_OSAL_SharedMemory_VirtToION(OMX_HANDLETYPE handle, OMX_PTR pBuffer)
877 {
878 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
879 ROCKCHIP_SHAREDMEM_LIST *pSMList = NULL;
880 ROCKCHIP_SHAREDMEM_LIST *pCurrentElement = NULL;
881 ROCKCHIP_SHAREDMEM_LIST *pFindElement = NULL;
882 if (pHandle == NULL || pBuffer == NULL)
883 goto EXIT;
884
885 Rockchip_OSAL_MutexLock(pHandle->hSMMutex);
886 pSMList = pHandle->pAllocMemory;
887 if (pSMList == NULL) {
888 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
889 goto EXIT;
890 }
891
892 pCurrentElement = pSMList;
893 if (pSMList->mapAddr == pBuffer) {
894 pFindElement = pSMList;
895 } else {
896 while ((pCurrentElement != NULL) && (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
897 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr != pBuffer))
898 pCurrentElement = pCurrentElement->pNextMemory;
899
900 if ((((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
901 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr == pBuffer)) {
902 pFindElement = pCurrentElement->pNextMemory;
903 } else {
904 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
905 omx_warn("Can not find SharedMemory");
906 goto EXIT;
907 }
908 }
909 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
910
911 EXIT:
912 return pFindElement->ion_hdl;
913 }
914
Rockchip_OSAL_SharedMemory_IONToVirt(OMX_HANDLETYPE handle,int ion_fd)915 OMX_PTR Rockchip_OSAL_SharedMemory_IONToVirt(OMX_HANDLETYPE handle, int ion_fd)
916 {
917 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
918 ROCKCHIP_SHAREDMEM_LIST *pSMList = NULL;
919 ROCKCHIP_SHAREDMEM_LIST *pCurrentElement = NULL;
920 ROCKCHIP_SHAREDMEM_LIST *pFindElement = NULL;
921 OMX_PTR pBuffer = NULL;
922 if (pHandle == NULL || ion_fd == -1) {
923 goto EXIT;
924 }
925
926 Rockchip_OSAL_MutexLock(pHandle->hSMMutex);
927 pSMList = pHandle->pAllocMemory;
928 if (pSMList == NULL) {
929 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
930 goto EXIT;
931 }
932
933 pCurrentElement = pSMList;
934 if (pSMList->ion_hdl == (RK_U32)ion_fd) {
935 pFindElement = pSMList;
936 } else {
937 while ((pCurrentElement != NULL) && (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
938 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->ion_hdl != (RK_U32)ion_fd))
939 pCurrentElement = pCurrentElement->pNextMemory;
940
941 if ((((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
942 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->ion_hdl == (RK_U32)ion_fd)) {
943 pFindElement = pCurrentElement->pNextMemory;
944 } else {
945 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
946 omx_warn("Can not find SharedMemory");
947 goto EXIT;
948 }
949 }
950 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
951
952 pBuffer = pFindElement->mapAddr;
953
954 EXIT:
955 return pBuffer;
956 }
check_used_heaps_type()957 static OMX_S32 check_used_heaps_type()
958 {
959 #ifdef VPU
960 if (!VPUClientGetIOMMUStatus()) {
961 return ION_HEAP(ION_CMA_HEAP_ID);
962 } else {
963 omx_trace("USE ION_SYSTEM_HEAP");
964 return ION_HEAP(ION_VMALLOC_HEAP_ID);
965 }
966 #else
967 omx_trace("USE ION_SYSTEM_HEAP");
968 return ION_HEAP(ION_VMALLOC_HEAP_ID);
969 #endif
970 return 0;
971 }
Rockchip_OSAL_SharedMemory_getPhyAddress(OMX_HANDLETYPE handle,int share_fd,OMX_U32 * phyaddress)972 OMX_S32 Rockchip_OSAL_SharedMemory_getPhyAddress(OMX_HANDLETYPE handle, int share_fd, OMX_U32 *phyaddress)
973 {
974 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
975 int err = 0;
976 ion_user_handle_t ion_handle = 0;
977 struct ion_phys_data phys_data;
978 if (check_used_heaps_type() == ION_HEAP(ION_CMA_HEAP_ID)) {
979 err = ion_import(pHandle->fd, share_fd, &ion_handle);
980 if (err) {
981 omx_err("ion import failed, share fd %d\n", share_fd);
982 return err;
983 }
984 phys_data.handle = ion_handle;
985 err = ion_custom_op(pHandle->fd, ION_IOC_GET_PHYS, &phys_data);
986 *phyaddress = phys_data.phys;
987 ion_free(pHandle->fd, ion_handle);
988 } else {
989 *phyaddress = share_fd;
990 }
991 return 0;
992 }
993
994 // stub function
VPUMemJudgeIommu()995 RK_S32 VPUMemJudgeIommu()
996 {
997 return 0;
998 }