• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }