1 /*
2 *
3 * Copyright 2013-2023 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
282 #ifndef OHOS_BUFFER_HANDLE
drm_fd_to_handle(int fd, int map_fd, RK_U32 *handle, RK_U32 flags)283 static int drm_fd_to_handle(int fd, int map_fd, RK_U32 *handle, RK_U32 flags)
284 {
285 int ret;
286 struct drm_prime_handle dph;
287
288 dph.fd = map_fd;
289 dph.flags = flags;
290
291 ret = drm_ioctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &dph);
292 if (ret < 0) {
293 return ret;
294 }
295
296 *handle = dph.handle;
297 return ret;
298 }
299 #endif
300 #endif
301
drm_map(int fd, RK_U32 handle, size_t length, int prot, int flags, unsigned char **ptr, int *map_fd)302 static int drm_map(int fd, RK_U32 handle, size_t length, int prot,
303 int flags, unsigned char **ptr, int *map_fd)
304 {
305 int ret;
306 struct drm_mode_map_dumb dmmd;
307 memset_s(&dmmd, sizeof(dmmd), 0, sizeof(dmmd));
308 dmmd.handle = handle;
309
310 if (map_fd == NULL) {
311 return -EINVAL;
312 }
313
314 if (ptr == NULL) {
315 return -EINVAL;
316 }
317
318 ret = drm_handle_to_fd(fd, handle, map_fd, 0);
319 omx_err("drm_map fd %d", *map_fd);
320 if (ret < 0) {
321 return ret;
322 }
323
324 ret = drm_ioctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &dmmd);
325 if (ret < 0) {
326 omx_err("drm_map FAIL");
327 close(*map_fd);
328 return ret;
329 }
330
331 omx_trace("dev fd %d length %d", fd, length);
332
333 *ptr = drm_mmap(fd, length, prot, flags, dmmd.offset);
334 if (*ptr == MAP_FAILED) {
335 close(*map_fd);
336 *map_fd = -1;
337 omx_err("mmap failed: %s\n", strerror(errno));
338 return -errno;
339 }
340
341 return ret;
342 }
343
drm_alloc(int fd, size_t len, size_t align, RK_U32 *handle, int flag)344 static int drm_alloc(int fd, size_t len, size_t align, RK_U32 *handle, int flag)
345 {
346 int ret;
347 struct drm_mode_create_dumb dmcb;
348
349 memset_s(&dmcb, sizeof(struct drm_mode_create_dumb), 0, sizeof(struct drm_mode_create_dumb));
350 dmcb.bpp = 8; // 8:value of dmcb.bpp
351 dmcb.width = (len + align - 1) & (~(align - 1));
352 dmcb.height = 1;
353 dmcb.size = dmcb.width * dmcb.bpp;
354 dmcb.flags = flag;
355
356 if (handle == NULL)
357 return -1;
358
359 ret = drm_ioctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &dmcb);
360 if (ret < 0) {
361 omx_err("drm_alloc fail: ret = %d", ret);
362 return ret;
363 }
364 *handle = dmcb.handle;
365
366 omx_trace("drm_alloc success: handle %d size %llu", *handle, dmcb.size);
367
368 return ret;
369 }
370
drm_free(int fd, RK_U32 handle)371 static int drm_free(int fd, RK_U32 handle)
372 {
373 struct drm_mode_destroy_dumb data = {
374 .handle = handle,
375 };
376 return drm_ioctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &data);
377 }
378
379 #ifdef AVS80
Rockchip_OSAL_SharedMemory_HandleToAddress(OMX_HANDLETYPE handle, OMX_HANDLETYPE handle_ptr)380 OMX_U32 Rockchip_OSAL_SharedMemory_HandleToAddress(OMX_HANDLETYPE handle, OMX_HANDLETYPE handle_ptr)
381 {
382 #ifndef OHOS_BUFFER_HANDLE
383 int map_fd = -1;
384 RK_S32 err = 0;
385 RK_S32 mClient = 0;
386 RK_U32 mHandle = 0;
387 (void)handle;
388 struct drm_rockchip_gem_phys phys_arg;
389 native_handle_t* pnative_handle_t = NULL;
390 pnative_handle_t = (native_handle_t*)handle_ptr;
391 map_fd = pnative_handle_t->data[0];
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 #endif
407 return -1;
408 }
409
Rockchip_OSAL_SharedMemory_HandleToSecureAddress(OMX_HANDLETYPE handle, OMX_HANDLETYPE handle_ptr, RK_S32 size)410 OMX_PTR Rockchip_OSAL_SharedMemory_HandleToSecureAddress(OMX_HANDLETYPE handle, OMX_HANDLETYPE handle_ptr, RK_S32 size)
411 {
412 RK_U8* pBuffer = NULL;
413 #ifndef OHOS_BUFFER_HANDLE
414 int map_fd = -1;
415 native_handle_t* pnative_handle_t = NULL;
416 RK_S32 err = 0;
417 RK_S32 mClient = 0;
418 RK_U32 mHandle = 0;
419 int ret;
420 struct drm_mode_map_dumb dmmd;
421 memset_s(&dmmd, sizeof(dmmd), 0, sizeof(dmmd));
422 (void)handle;
423
424 pnative_handle_t = (native_handle_t*)handle_ptr;
425 map_fd = pnative_handle_t->data[0];
426
427 mClient = open("/dev/dri/card0", O_RDWR);
428 if (mClient < 0) {
429 omx_err("Rockchip_OSAL_SharedMemory_HandleToAddress open drm fail");
430 return 0;
431 }
432 drm_fd_to_handle(mClient, (int32_t)map_fd, &mHandle, 0);
433 dmmd.handle = mHandle;
434
435 ret = drm_ioctl(mClient, DRM_IOCTL_MODE_MAP_DUMB, &dmmd);
436 if (ret < 0) {
437 close(mClient);
438 mClient = -1;
439 omx_err("drm_ioctl DRM_IOCTL_MODE_MAP_DUMB failed: %s\n", strerror(errno));
440 return ret;
441 }
442
443 pBuffer = (uint8_t*)drm_mmap(mClient, size, PROT_READ | PROT_WRITE, MAP_SHARED, dmmd.offset);
444 if (pBuffer == MAP_FAILED) {
445 close(mClient);
446 mClient = -1;
447 omx_err("mmap failed:fd = %d,length = %d, %s\n", mClient, size, strerror(errno));
448 return -errno;
449 }
450
451 close(mClient);
452 mClient = -1;
453 #endif
454 return pBuffer;
455 }
456 #endif
457
Rockchip_OSAL_SharedMemory_SecureUnmap(OMX_HANDLETYPE handle, OMX_HANDLETYPE handle_ptr, RK_S32 size)458 void Rockchip_OSAL_SharedMemory_SecureUnmap(OMX_HANDLETYPE handle, OMX_HANDLETYPE handle_ptr, RK_S32 size)
459 {
460 (void)handle;
461 if (munmap(handle_ptr, size)) {
462 omx_err("ion_unmap fail");
463 }
464 }
465
Rockchip_OSAL_SharedMemory_Opennull466 OMX_HANDLETYPE Rockchip_OSAL_SharedMemory_Open()
467 {
468 ROCKCHIP_SHARED_MEMORY *pHandle = NULL;
469 int SharedMemoryClient = 0;
470
471 pHandle = (ROCKCHIP_SHARED_MEMORY *)malloc(sizeof(ROCKCHIP_SHARED_MEMORY));
472 Rockchip_OSAL_Memset(pHandle, 0, sizeof(ROCKCHIP_SHARED_MEMORY));
473 if (pHandle == NULL) {
474 goto EXIT;
475 }
476 if (!access("/dev/dri/card0", F_OK)) {
477 SharedMemoryClient = open("/dev/dri/card0", O_RDWR);
478 mem_type = MEMORY_TYPE_DRM;
479 } else {
480 SharedMemoryClient = open("/dev/ion", O_RDWR);
481 mem_type = MEMORY_TYPE_ION;
482 }
483
484 if (SharedMemoryClient <= 0) {
485 omx_err("SharedMemoryClient create Error: %d", SharedMemoryClient);
486 Rockchip_OSAL_Free((void *)pHandle);
487 pHandle = NULL;
488 goto EXIT;
489 }
490
491 pHandle->fd = SharedMemoryClient;
492
493 Rockchip_OSAL_MutexCreate(&pHandle->hSMMutex);
494
495 EXIT:
496 return (OMX_HANDLETYPE)pHandle;
497 }
498
Rockchip_OSAL_SharedMemory_Close(OMX_HANDLETYPE handle, OMX_BOOL b_secure)499 void Rockchip_OSAL_SharedMemory_Close(OMX_HANDLETYPE handle, OMX_BOOL b_secure)
500 {
501 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
502 ROCKCHIP_SHAREDMEM_LIST *pSMList = NULL;
503 ROCKCHIP_SHAREDMEM_LIST *pCurrentElement = NULL;
504 ROCKCHIP_SHAREDMEM_LIST *pDeleteElement = NULL;
505
506 if (pHandle == NULL) {
507 goto EXIT;
508 }
509
510 Rockchip_OSAL_MutexLock(pHandle->hSMMutex);
511 pCurrentElement = pSMList = pHandle->pAllocMemory;
512
513 while (pCurrentElement != NULL) {
514 pDeleteElement = pCurrentElement;
515 pCurrentElement = pCurrentElement->pNextMemory;
516 if (b_secure) {
517 #ifdef AVS80
518 #ifndef OHOS_BUFFER_HANDLE
519 native_handle_t* pnative_handle_t = NULL;
520 int map_fd = 0;
521 void *pTrueAddree = NULL;
522 pnative_handle_t = (native_handle_t*)pDeleteElement->mapAddr;
523 map_fd = pnative_handle_t->data[0];
524 pTrueAddree = (void *)Rockchip_OSAL_SharedMemory_HandleToSecureAddress(handle,
525 pDeleteElement->mapAddr, pDeleteElement->allocSize);
526 pDeleteElement->mapAddr = pTrueAddree;
527 close(map_fd);
528 map_fd = -1;
529 #endif
530 #endif
531 }
532 if (munmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
533 omx_err("ion_unmap fail");
534 }
535 pDeleteElement->mapAddr = NULL;
536 pDeleteElement->allocSize = 0;
537
538 if (pDeleteElement->owner) {
539 if (mem_type == MEMORY_TYPE_ION) {
540 ion_free(pHandle->fd, pDeleteElement->ion_hdl);
541 } else {
542 drm_free(pHandle->fd, pDeleteElement->ion_hdl);
543 }
544 }
545 pDeleteElement->ion_hdl = -1;
546
547 Rockchip_OSAL_Free(pDeleteElement);
548
549 mem_cnt--;
550 omx_trace("SharedMemory free count: %d", mem_cnt);
551 }
552
553 pHandle->pAllocMemory = pSMList = NULL;
554 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
555
556 Rockchip_OSAL_MutexTerminate(pHandle->hSMMutex);
557 pHandle->hSMMutex = NULL;
558
559 close(pHandle->fd);
560
561 pHandle->fd = -1;
562
563 Rockchip_OSAL_Free(pHandle);
564
565 EXIT:
566 return;
567 }
568
ion_custom_op(int ion_client, int op, void *op_data)569 static int ion_custom_op(int ion_client, int op, void *op_data)
570 {
571 struct ion_custom_data data;
572 int err;
573 data.cmd = op;
574 data.arg = (unsigned long)op_data;
575 err = ioctl(ion_client, ION_IOC_CUSTOM, &data);
576 if (err < 0) {
577 omx_err("ION_IOC_CUSTOM (%d) failed with error - %s", op, strerror(errno));
578 return err;
579 }
580 return err;
581 }
582
Rockchip_OSAL_SharedMemory_Alloc(OMX_HANDLETYPE handle, OMX_U32 size, MEMORY_TYPE memoryType)583 OMX_PTR Rockchip_OSAL_SharedMemory_Alloc(OMX_HANDLETYPE handle, OMX_U32 size, MEMORY_TYPE memoryType)
584 {
585 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
586 ROCKCHIP_SHAREDMEM_LIST *pSMList = NULL;
587 ROCKCHIP_SHAREDMEM_LIST *pElement = NULL;
588 ROCKCHIP_SHAREDMEM_LIST *pCurrentElement = NULL;
589 OMX_U32 ion_hdl = 0;
590 OMX_PTR pBuffer = NULL;
591 unsigned int mask;
592 unsigned int flag = 0;
593 int err = 0;
594 int map_fd = -1;
595
596 if (pHandle == NULL) {
597 goto EXIT;
598 }
599
600 pElement = (ROCKCHIP_SHAREDMEM_LIST *)malloc(sizeof(ROCKCHIP_SHAREDMEM_LIST));
601 Rockchip_OSAL_Memset(pElement, 0, sizeof(ROCKCHIP_SHAREDMEM_LIST));
602 pElement->owner = OMX_TRUE;
603
604 switch (memoryType) {
605 case SECURE_MEMORY:
606 mask = ION_HEAP(ION_SECURE_HEAP_ID);
607 omx_info("pHandle->fd = %d,size = %lu, mem_type = %d", pHandle->fd, size, mem_type);
608 if (mem_type == MEMORY_TYPE_DRM) {
609 err = drm_alloc(pHandle->fd, size, 4096, (RK_U32 *)&ion_hdl, 0); // 4096:byte alignment
610 } else {
611 err = ion_alloc(pHandle->fd, size,
612 4096, mask, 0, (ion_user_handle_t *)&ion_hdl); // 4096:byte alignment
613 }
614 if (err) {
615 omx_err("ion_alloc failed with err (%d)", err);
616 goto EXIT;
617 }
618 if (err) {
619 omx_err("failed to get phy address: %s\n", strerror(errno));
620 goto EXIT;
621 }
622
623 pElement->allocSize = size;
624 pElement->ion_hdl = ion_hdl;
625 pElement->pNextMemory = NULL;
626
627 #ifdef AVS80
628 #ifndef OHOS_BUFFER_HANDLE
629 native_handle_t* pnative_handle_t = NULL;
630 pnative_handle_t = native_handle_create(1, 0);
631 err = drm_handle_to_fd(pHandle->fd, ion_hdl, &map_fd, 0);
632 if (err < 0) {
633 omx_err("failed to trans handle to fd: %s\n", strerror(errno));
634 goto EXIT;
635 }
636 omx_trace("pnative_handle_t = %p, map_fd = %d, handle = %d", pnative_handle_t, map_fd, ion_hdl);
637 pnative_handle_t->data[0] = map_fd;
638 pBuffer = (void *)pnative_handle_t;
639 if (mem_type == MEMORY_TYPE_DRM) {
640 pElement->mapAddr = (OMX_PTR)((__u64)pnative_handle_t);
641 } else {
642 pElement->mapAddr = (OMX_PTR)((__u64)pnative_handle_t);
643 }
644 // Add BufferHandle later
645 #endif
646 #endif
647 break;
648 case SYSTEM_MEMORY:
649 mask = ION_HEAP(ION_VMALLOC_HEAP_ID);
650 err = ion_alloc((int)pHandle->fd, size,
651 4096, mask, flag, (ion_user_handle_t *)&ion_hdl); // 4096:byte alignment
652 if (err < 0) {
653 omx_err("ion_alloc Error: %lu", ion_hdl);
654 Rockchip_OSAL_Free((OMX_PTR)pElement);
655 goto EXIT;
656 }
657
658 err = ion_map((int)pHandle->fd, ion_hdl, size, PROT_READ | PROT_WRITE,
659 MAP_SHARED, (off_t)0, (unsigned char**)&pBuffer, &map_fd);
660 if (err) {
661 omx_err("ion_map Error");
662 ion_free(pHandle->fd, ion_hdl);
663 Rockchip_OSAL_Free((OMX_PTR)pElement);
664 pBuffer = NULL;
665 goto EXIT;
666 }
667
668 pElement->ion_hdl = ion_hdl;
669 pElement->mapAddr = pBuffer;
670 pElement->allocSize = size;
671 pElement->pNextMemory = NULL;
672 break;
673 default:
674 pBuffer = NULL;
675 goto EXIT;
676 break;
677 }
678
679 Rockchip_OSAL_MutexLock(pHandle->hSMMutex);
680 pSMList = pHandle->pAllocMemory;
681 if (pSMList == NULL) {
682 pHandle->pAllocMemory = pSMList = pElement;
683 } else {
684 pCurrentElement = pSMList;
685 while (pCurrentElement->pNextMemory != NULL) {
686 pCurrentElement = pCurrentElement->pNextMemory;
687 }
688 pCurrentElement->pNextMemory = pElement;
689 }
690 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
691
692 mem_cnt++;
693 omx_trace("SharedMemory alloc count: %d", mem_cnt);
694
695 EXIT:
696 return pBuffer;
697 }
698
Rockchip_OSAL_SharedMemory_Free(OMX_HANDLETYPE handle, OMX_PTR pBuffer)699 void Rockchip_OSAL_SharedMemory_Free(OMX_HANDLETYPE handle, OMX_PTR pBuffer)
700 {
701 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
702 ROCKCHIP_SHAREDMEM_LIST *pSMList = NULL;
703 ROCKCHIP_SHAREDMEM_LIST *pCurrentElement = NULL;
704 ROCKCHIP_SHAREDMEM_LIST *pDeleteElement = NULL;
705
706 if (pHandle == NULL) {
707 goto EXIT;
708 }
709
710 Rockchip_OSAL_MutexLock(pHandle->hSMMutex);
711 pSMList = pHandle->pAllocMemory;
712 if (pSMList == NULL) {
713 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
714 goto EXIT;
715 }
716
717 pCurrentElement = pSMList;
718 if (pSMList->mapAddr == pBuffer) {
719 pDeleteElement = pSMList;
720 pHandle->pAllocMemory = pSMList = pSMList->pNextMemory;
721 } else {
722 while ((pCurrentElement != NULL) && (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
723 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr != pBuffer))
724 pCurrentElement = pCurrentElement->pNextMemory;
725
726 if ((((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
727 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr == pBuffer)) {
728 pDeleteElement = pCurrentElement->pNextMemory;
729 pCurrentElement->pNextMemory = pDeleteElement->pNextMemory;
730 } else {
731 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
732 omx_err("Can not find SharedMemory");
733 goto EXIT;
734 }
735 }
736 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
737 if (munmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
738 omx_err("ion_unmap fail");
739 goto EXIT;
740 }
741 pDeleteElement->mapAddr = NULL;
742 pDeleteElement->allocSize = 0;
743
744 if (pDeleteElement->owner) {
745 if (mem_cnt == MEMORY_TYPE_ION) {
746 ion_free(pHandle->fd, (ion_user_handle_t)pDeleteElement->ion_hdl);
747 } else {
748 drm_free(pHandle->fd, pDeleteElement->ion_hdl);
749 }
750 }
751 pDeleteElement->ion_hdl = -1;
752
753 Rockchip_OSAL_Free(pDeleteElement);
754
755 mem_cnt--;
756 omx_trace("SharedMemory free count: %d", mem_cnt);
757
758 EXIT:
759 return;
760 }
761
Rockchip_OSAL_SharedMemory_Map(OMX_HANDLETYPE handle, OMX_U32 size, int ion_hdl)762 OMX_PTR Rockchip_OSAL_SharedMemory_Map(OMX_HANDLETYPE handle, OMX_U32 size, int ion_hdl)
763 {
764 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
765 ROCKCHIP_SHAREDMEM_LIST *pSMList = NULL;
766 ROCKCHIP_SHAREDMEM_LIST *pElement = NULL;
767 ROCKCHIP_SHAREDMEM_LIST *pCurrentElement = NULL;
768 OMX_PTR pBuffer = NULL;
769 int err = 0;
770 int map_fd = -1;
771
772 if (pHandle == NULL) {
773 goto EXIT;
774 }
775
776 pElement = Rockchip_OSAL_Malloc(sizeof(ROCKCHIP_SHAREDMEM_LIST));
777 Rockchip_OSAL_Memset(pElement, 0, sizeof(ROCKCHIP_SHAREDMEM_LIST));
778
779 if (ion_hdl == -1) {
780 omx_err("ion_alloc Error: %d", ion_hdl);
781 Rockchip_OSAL_Free((void*)pElement);
782 goto EXIT;
783 }
784 if (mem_type == MEMORY_TYPE_ION) {
785 err = ion_map(pHandle->fd, (ion_user_handle_t)ion_hdl, size, PROT_READ | PROT_WRITE,
786 MAP_SHARED, (off_t)0, (unsigned char**)&pBuffer, &map_fd);
787 if (pBuffer == NULL) {
788 omx_err("ion_map Error");
789 ion_free(pHandle->fd, (ion_user_handle_t)ion_hdl);
790 Rockchip_OSAL_Free((void*)pElement);
791 goto EXIT;
792 }
793 } else {
794 err = drm_map(pHandle->fd, ion_hdl, size, PROT_READ | PROT_WRITE,
795 MAP_SHARED, (unsigned char**)&pBuffer, &map_fd);
796 if (pBuffer == NULL) {
797 omx_err("ion_map Error");
798 drm_free(pHandle->fd, ion_hdl);
799 Rockchip_OSAL_Free((void*)pElement);
800 goto EXIT;
801 }
802 }
803
804 pElement->ion_hdl = ion_hdl;
805 pElement->mapAddr = pBuffer;
806 pElement->allocSize = size;
807 pElement->pNextMemory = NULL;
808
809 Rockchip_OSAL_MutexLock(pHandle->hSMMutex);
810 pSMList = pHandle->pAllocMemory;
811 if (pSMList == NULL) {
812 pHandle->pAllocMemory = pSMList = pElement;
813 } else {
814 pCurrentElement = pSMList;
815 while (pCurrentElement->pNextMemory != NULL) {
816 pCurrentElement = pCurrentElement->pNextMemory;
817 }
818 pCurrentElement->pNextMemory = pElement;
819 }
820 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
821
822 mem_cnt++;
823 omx_trace("SharedMemory alloc count: %d", mem_cnt);
824
825 EXIT:
826 return pBuffer;
827 }
828
Rockchip_OSAL_SharedMemory_Unmap(OMX_HANDLETYPE handle, int ionfd)829 void Rockchip_OSAL_SharedMemory_Unmap(OMX_HANDLETYPE handle, int ionfd)
830 {
831 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
832 ROCKCHIP_SHAREDMEM_LIST *pSMList = NULL;
833 ROCKCHIP_SHAREDMEM_LIST *pCurrentElement = NULL;
834 ROCKCHIP_SHAREDMEM_LIST *pDeleteElement = NULL;
835
836 if (pHandle == NULL) {
837 goto EXIT;
838 }
839
840 Rockchip_OSAL_MutexLock(pHandle->hSMMutex);
841 pSMList = pHandle->pAllocMemory;
842 if (pSMList == NULL) {
843 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
844 goto EXIT;
845 }
846
847 pCurrentElement = pSMList;
848 if (pSMList->ion_hdl == (RK_U32)ionfd) {
849 pDeleteElement = pSMList;
850 pHandle->pAllocMemory = pSMList = pSMList->pNextMemory;
851 } else {
852 while ((pCurrentElement != NULL) && (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
853 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->ion_hdl != (RK_U32)ionfd))
854 pCurrentElement = pCurrentElement->pNextMemory;
855
856 if ((((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
857 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->ion_hdl == (RK_U32)ionfd)) {
858 pDeleteElement = pCurrentElement->pNextMemory;
859 pCurrentElement->pNextMemory = pDeleteElement->pNextMemory;
860 } else {
861 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
862 omx_err("Can not find SharedMemory");
863 goto EXIT;
864 }
865 }
866 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
867
868 if (munmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
869 omx_err("ion_unmap fail");
870 goto EXIT;
871 }
872 pDeleteElement->mapAddr = NULL;
873 pDeleteElement->allocSize = 0;
874 pDeleteElement->ion_hdl = -1;
875
876 Rockchip_OSAL_Free(pDeleteElement);
877
878 mem_cnt--;
879 omx_trace("SharedMemory free count: %d", mem_cnt);
880
881 EXIT:
882 return;
883 }
884
Rockchip_OSAL_SharedMemory_VirtToION(OMX_HANDLETYPE handle, OMX_PTR pBuffer)885 int Rockchip_OSAL_SharedMemory_VirtToION(OMX_HANDLETYPE handle, OMX_PTR pBuffer)
886 {
887 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
888 ROCKCHIP_SHAREDMEM_LIST *pSMList = NULL;
889 ROCKCHIP_SHAREDMEM_LIST *pCurrentElement = NULL;
890 ROCKCHIP_SHAREDMEM_LIST *pFindElement = NULL;
891 if (pHandle == NULL || pBuffer == NULL)
892 goto EXIT;
893
894 Rockchip_OSAL_MutexLock(pHandle->hSMMutex);
895 pSMList = pHandle->pAllocMemory;
896 if (pSMList == NULL) {
897 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
898 goto EXIT;
899 }
900
901 pCurrentElement = pSMList;
902 if (pSMList->mapAddr == pBuffer) {
903 pFindElement = pSMList;
904 } else {
905 while ((pCurrentElement != NULL) && (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
906 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr != pBuffer))
907 pCurrentElement = pCurrentElement->pNextMemory;
908
909 if ((((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
910 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr == pBuffer)) {
911 pFindElement = pCurrentElement->pNextMemory;
912 } else {
913 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
914 omx_warn("Can not find SharedMemory");
915 goto EXIT;
916 }
917 }
918 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
919
920 EXIT:
921 return pFindElement->ion_hdl;
922 }
923
Rockchip_OSAL_SharedMemory_IONToVirt(OMX_HANDLETYPE handle, int ion_fd)924 OMX_PTR Rockchip_OSAL_SharedMemory_IONToVirt(OMX_HANDLETYPE handle, int ion_fd)
925 {
926 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
927 ROCKCHIP_SHAREDMEM_LIST *pSMList = NULL;
928 ROCKCHIP_SHAREDMEM_LIST *pCurrentElement = NULL;
929 ROCKCHIP_SHAREDMEM_LIST *pFindElement = NULL;
930 OMX_PTR pBuffer = NULL;
931 if (pHandle == NULL || ion_fd == -1) {
932 goto EXIT;
933 }
934
935 Rockchip_OSAL_MutexLock(pHandle->hSMMutex);
936 pSMList = pHandle->pAllocMemory;
937 if (pSMList == NULL) {
938 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
939 goto EXIT;
940 }
941
942 pCurrentElement = pSMList;
943 if (pSMList->ion_hdl == (RK_U32)ion_fd) {
944 pFindElement = pSMList;
945 } else {
946 while ((pCurrentElement != NULL) && (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
947 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->ion_hdl != (RK_U32)ion_fd))
948 pCurrentElement = pCurrentElement->pNextMemory;
949
950 if ((((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
951 (((ROCKCHIP_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->ion_hdl == (RK_U32)ion_fd)) {
952 pFindElement = pCurrentElement->pNextMemory;
953 } else {
954 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
955 omx_warn("Can not find SharedMemory");
956 goto EXIT;
957 }
958 }
959 Rockchip_OSAL_MutexUnlock(pHandle->hSMMutex);
960
961 pBuffer = pFindElement->mapAddr;
962
963 EXIT:
964 return pBuffer;
965 }
check_used_heaps_typenull966 static OMX_S32 check_used_heaps_type()
967 {
968 #ifdef VPU
969 if (!VPUClientGetIOMMUStatus()) {
970 return ION_HEAP(ION_CMA_HEAP_ID);
971 } else {
972 omx_trace("USE ION_SYSTEM_HEAP");
973 return ION_HEAP(ION_VMALLOC_HEAP_ID);
974 }
975 #else
976 omx_trace("USE ION_SYSTEM_HEAP");
977 return ION_HEAP(ION_VMALLOC_HEAP_ID);
978 #endif
979 return 0;
980 }
Rockchip_OSAL_SharedMemory_getPhyAddress(OMX_HANDLETYPE handle, int share_fd, OMX_U32 *phyaddress)981 OMX_S32 Rockchip_OSAL_SharedMemory_getPhyAddress(OMX_HANDLETYPE handle, int share_fd, OMX_U32 *phyaddress)
982 {
983 ROCKCHIP_SHARED_MEMORY *pHandle = (ROCKCHIP_SHARED_MEMORY *)handle;
984 int err = 0;
985 ion_user_handle_t ion_handle = 0;
986 struct ion_phys_data phys_data;
987 if (check_used_heaps_type() == ION_HEAP(ION_CMA_HEAP_ID)) {
988 err = ion_import(pHandle->fd, share_fd, &ion_handle);
989 if (err) {
990 omx_err("ion import failed, share fd %d\n", share_fd);
991 return err;
992 }
993 phys_data.handle = ion_handle;
994 err = ion_custom_op(pHandle->fd, ION_IOC_GET_PHYS, &phys_data);
995 *phyaddress = phys_data.phys;
996 ion_free(pHandle->fd, ion_handle);
997 } else {
998 *phyaddress = share_fd;
999 }
1000 return 0;
1001 }
1002
1003 // stub function
VPUMemJudgeIommunull1004 RK_S32 VPUMemJudgeIommu()
1005 {
1006 return 0;
1007 }