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 }