mirror of
https://github.com/Evolution-X-Devices/hardware_samsung_slsi-linaro_openmax
synced 2026-01-27 11:13:30 +00:00
Change-Id: I79380bc91acf57ca5f3e56fb64af76f4c45f6566 Signed-off-by: Sam Protsenko <joe.skb7@gmail.com>
547 lines
18 KiB
C
547 lines
18 KiB
C
/*
|
|
*
|
|
* Copyright 2012 Samsung Electronics S.LSI Co. LTD
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/*
|
|
* @file Exynos_OSAL_SharedMemory.c
|
|
* @brief
|
|
* @author SeungBeom Kim (sbcrux.kim@samsung.com)
|
|
* Jinsung Yang (jsgood.yang@samsung.com)
|
|
* Taehwan Kim (t_h.kim@samsung.com)
|
|
* @version 2.0.0
|
|
* @history
|
|
* 2012.02.20 : Create
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <pthread.h>
|
|
#include <unistd.h>
|
|
#ifdef USE_ANDROID
|
|
#include <log/log.h>
|
|
#include <cutils/atomic.h>
|
|
#endif
|
|
#include <fcntl.h>
|
|
#include <sys/mman.h>
|
|
|
|
#include <hardware/exynos/ion.h>
|
|
|
|
#include "Exynos_OSAL_Mutex.h"
|
|
#include "Exynos_OSAL_Memory.h"
|
|
#include "Exynos_OSAL_SharedMemory.h"
|
|
|
|
#include "Exynos_OSAL_ETC.h"
|
|
|
|
//#define EXYNOS_LOG_OFF
|
|
#include "Exynos_OSAL_Log.h"
|
|
|
|
|
|
static int mem_cnt = 0;
|
|
static int map_cnt = 0;
|
|
|
|
struct EXYNOS_SHAREDMEM_LIST;
|
|
typedef struct _EXYNOS_SHAREDMEM_LIST
|
|
{
|
|
unsigned long IONBuffer;
|
|
OMX_PTR mapAddr;
|
|
OMX_U32 allocSize;
|
|
OMX_BOOL owner;
|
|
struct _EXYNOS_SHAREDMEM_LIST *pNextMemory;
|
|
} EXYNOS_SHAREDMEM_LIST;
|
|
|
|
typedef struct _EXYNOS_SHARED_MEMORY
|
|
{
|
|
unsigned long hIONHandle;
|
|
EXYNOS_SHAREDMEM_LIST *pAllocMemory;
|
|
OMX_HANDLETYPE hSMMutex;
|
|
} EXYNOS_SHARED_MEMORY;
|
|
|
|
|
|
OMX_HANDLETYPE Exynos_OSAL_SharedMemory_Open()
|
|
{
|
|
EXYNOS_SHARED_MEMORY *pHandle = NULL;
|
|
long IONClient = -1;
|
|
|
|
pHandle = (EXYNOS_SHARED_MEMORY *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHARED_MEMORY));
|
|
if (pHandle == NULL)
|
|
goto EXIT;
|
|
Exynos_OSAL_Memset(pHandle, 0, sizeof(EXYNOS_SHARED_MEMORY));
|
|
|
|
IONClient = (long)exynos_ion_open();
|
|
if (IONClient < 0) {
|
|
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_open is failed: %d", IONClient);
|
|
Exynos_OSAL_Free((void *)pHandle);
|
|
pHandle = NULL;
|
|
goto EXIT;
|
|
}
|
|
|
|
pHandle->hIONHandle = (unsigned long)IONClient;
|
|
|
|
if (OMX_ErrorNone != Exynos_OSAL_MutexCreate(&pHandle->hSMMutex)) {
|
|
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_MutexCreate", __FUNCTION__);
|
|
/* free a ion_client */
|
|
exynos_ion_close(pHandle->hIONHandle);
|
|
pHandle->hIONHandle = 0;
|
|
|
|
Exynos_OSAL_Free((void *)pHandle);
|
|
pHandle = NULL;
|
|
}
|
|
|
|
EXIT:
|
|
return (OMX_HANDLETYPE)pHandle;
|
|
}
|
|
|
|
void Exynos_OSAL_SharedMemory_Close(OMX_HANDLETYPE handle)
|
|
{
|
|
EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
|
|
EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
|
|
EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
|
|
EXYNOS_SHAREDMEM_LIST *pDeleteElement = NULL;
|
|
|
|
if (pHandle == NULL)
|
|
goto EXIT;
|
|
|
|
Exynos_OSAL_MutexLock(pHandle->hSMMutex);
|
|
pCurrentElement = pSMList = pHandle->pAllocMemory;
|
|
|
|
while (pCurrentElement != NULL) {
|
|
pDeleteElement = pCurrentElement;
|
|
pCurrentElement = pCurrentElement->pNextMemory;
|
|
|
|
/* if mmap was not called, mapAddr is same as IONBuffer */
|
|
if (pDeleteElement->mapAddr != (void *)pDeleteElement->IONBuffer) {
|
|
if (Exynos_OSAL_Munmap(pDeleteElement->mapAddr, pDeleteElement->allocSize))
|
|
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Munmap", __FUNCTION__);
|
|
}
|
|
|
|
pDeleteElement->mapAddr = NULL;
|
|
pDeleteElement->allocSize = 0;
|
|
|
|
if (pDeleteElement->owner) {
|
|
/* free a ion_buffer */
|
|
close(pDeleteElement->IONBuffer);
|
|
mem_cnt--;
|
|
}
|
|
pDeleteElement->IONBuffer = 0;
|
|
|
|
Exynos_OSAL_Free(pDeleteElement);
|
|
|
|
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] count: %d", __FUNCTION__, mem_cnt);
|
|
}
|
|
|
|
pHandle->pAllocMemory = pSMList = NULL;
|
|
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
|
|
|
|
Exynos_OSAL_MutexTerminate(pHandle->hSMMutex);
|
|
pHandle->hSMMutex = NULL;
|
|
|
|
/* free a ion_client */
|
|
exynos_ion_close(pHandle->hIONHandle);
|
|
pHandle->hIONHandle = 0;
|
|
|
|
Exynos_OSAL_Free(pHandle);
|
|
|
|
EXIT:
|
|
return;
|
|
}
|
|
|
|
OMX_PTR Exynos_OSAL_SharedMemory_Alloc(OMX_HANDLETYPE handle, OMX_U32 size, MEMORY_TYPE memoryType)
|
|
{
|
|
EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
|
|
EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
|
|
EXYNOS_SHAREDMEM_LIST *pElement = NULL;
|
|
EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
|
|
long IONBuffer = -1;
|
|
OMX_PTR pBuffer = NULL;
|
|
unsigned int mask;
|
|
unsigned int flag;
|
|
|
|
if (pHandle == NULL)
|
|
goto EXIT;
|
|
|
|
pElement = (EXYNOS_SHAREDMEM_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHAREDMEM_LIST));
|
|
if (pElement == NULL)
|
|
goto EXIT;
|
|
Exynos_OSAL_Memset(pElement, 0, sizeof(EXYNOS_SHAREDMEM_LIST));
|
|
pElement->owner = OMX_TRUE;
|
|
|
|
/* priority is like as EXT > SECURE > CONTIG > CACHED > NORMAL */
|
|
switch ((int)memoryType) {
|
|
case (EXT_MEMORY | SECURE_MEMORY | CONTIG_MEMORY | CACHED_MEMORY): /* EXTRA */
|
|
case (EXT_MEMORY | SECURE_MEMORY | CONTIG_MEMORY):
|
|
case (EXT_MEMORY | SECURE_MEMORY | CACHED_MEMORY):
|
|
case (EXT_MEMORY | SECURE_MEMORY):
|
|
mask = EXYNOS_ION_HEAP_VIDEO_STREAM_MASK;
|
|
flag = ION_FLAG_PROTECTED;
|
|
break;
|
|
case (EXT_MEMORY | CONTIG_MEMORY | CACHED_MEMORY):
|
|
case (EXT_MEMORY | CONTIG_MEMORY):
|
|
case (EXT_MEMORY | CACHED_MEMORY):
|
|
case EXT_MEMORY:
|
|
mask = EXYNOS_ION_HEAP_VIDEO_STREAM_MASK;
|
|
flag = 0;
|
|
break;
|
|
case (SECURE_MEMORY | CONTIG_MEMORY | CACHED_MEMORY): /* SECURE */
|
|
case (SECURE_MEMORY | CONTIG_MEMORY):
|
|
case (SECURE_MEMORY | CACHED_MEMORY):
|
|
case SECURE_MEMORY:
|
|
mask = EXYNOS_ION_HEAP_VIDEO_STREAM_MASK;
|
|
flag = ION_FLAG_PROTECTED;
|
|
break;
|
|
case (CONTIG_MEMORY | CACHED_MEMORY): /* CONTIG */
|
|
case CONTIG_MEMORY:
|
|
mask = EXYNOS_ION_HEAP_VIDEO_STREAM_MASK;
|
|
flag = 0;
|
|
break;
|
|
case CACHED_MEMORY: /* CACHED */
|
|
mask = EXYNOS_ION_HEAP_SYSTEM_MASK;
|
|
flag = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
|
|
break;
|
|
default: /* NORMAL */
|
|
// NOTE: cached?
|
|
mask = EXYNOS_ION_HEAP_SYSTEM_MASK;
|
|
flag = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
|
|
break;
|
|
}
|
|
|
|
if (flag & ION_FLAG_CACHED) /* use improved cache oprs */
|
|
flag |= ION_FLAG_CACHED_NEEDS_SYNC;
|
|
|
|
if ((IONBuffer = exynos_ion_alloc(pHandle->hIONHandle, size, mask, flag)) < 0) {
|
|
Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%s] Failed to exynos_ion_alloc(mask:%x, flag:%x)", __FUNCTION__, mask, flag);
|
|
if (memoryType == CONTIG_MEMORY) {
|
|
/* retry at normal area */
|
|
flag = 0;
|
|
if ((IONBuffer = exynos_ion_alloc(pHandle->hIONHandle, size, mask, flag)) < 0) {
|
|
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] retry: Failed to exynos_ion_alloc(mask:%x, flag:%x)", __FUNCTION__, mask, flag);
|
|
Exynos_OSAL_Free((OMX_PTR)pElement);
|
|
goto EXIT;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (flag & ION_FLAG_PROTECTED) {
|
|
/* in case of DRM, do not call mmap. so set a fd instead of vaddr */
|
|
pBuffer = (OMX_PTR)IONBuffer;
|
|
} else {
|
|
pBuffer = Exynos_OSAL_Mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, IONBuffer, 0);
|
|
if (pBuffer == MAP_FAILED) {
|
|
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Mmap(size:%d)", __FUNCTION__, size);
|
|
/* free a ion_buffer */
|
|
close(IONBuffer); // NOTE: argument to exynos_ion_close/ion_close() should be allocated by ion_open/exynos_ion_open
|
|
Exynos_OSAL_Free((OMX_PTR)pElement);
|
|
pBuffer = NULL;
|
|
goto EXIT;
|
|
}
|
|
}
|
|
|
|
pElement->IONBuffer = (unsigned long)IONBuffer;
|
|
pElement->mapAddr = pBuffer;
|
|
pElement->allocSize = size;
|
|
pElement->pNextMemory = NULL;
|
|
|
|
Exynos_OSAL_MutexLock(pHandle->hSMMutex);
|
|
pSMList = pHandle->pAllocMemory;
|
|
if (pSMList == NULL) {
|
|
pHandle->pAllocMemory = pSMList = pElement;
|
|
} else {
|
|
pCurrentElement = pSMList;
|
|
while (pCurrentElement->pNextMemory != NULL) {
|
|
pCurrentElement = pCurrentElement->pNextMemory;
|
|
}
|
|
pCurrentElement->pNextMemory = pElement;
|
|
}
|
|
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
|
|
|
|
mem_cnt++;
|
|
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] count: %d", __FUNCTION__, mem_cnt);
|
|
|
|
EXIT:
|
|
return pBuffer;
|
|
}
|
|
|
|
void Exynos_OSAL_SharedMemory_Free(OMX_HANDLETYPE handle, OMX_PTR pBuffer)
|
|
{
|
|
EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
|
|
EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
|
|
EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
|
|
EXYNOS_SHAREDMEM_LIST *pDeleteElement = NULL;
|
|
|
|
if (pHandle == NULL)
|
|
goto EXIT;
|
|
|
|
Exynos_OSAL_MutexLock(pHandle->hSMMutex);
|
|
pSMList = pHandle->pAllocMemory;
|
|
if (pSMList == NULL) {
|
|
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
|
|
goto EXIT;
|
|
}
|
|
|
|
pCurrentElement = pSMList;
|
|
if (pSMList->mapAddr == pBuffer) {
|
|
pDeleteElement = pSMList;
|
|
pHandle->pAllocMemory = pSMList = pSMList->pNextMemory;
|
|
} else {
|
|
while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
|
|
(((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr != pBuffer))
|
|
pCurrentElement = pCurrentElement->pNextMemory;
|
|
|
|
if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
|
|
(((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr == pBuffer)) {
|
|
pDeleteElement = pCurrentElement->pNextMemory;
|
|
pCurrentElement->pNextMemory = pDeleteElement->pNextMemory;
|
|
} else {
|
|
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
|
|
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] can't find a buffer(%p) in list", __FUNCTION__, pBuffer);
|
|
goto EXIT;
|
|
}
|
|
}
|
|
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
|
|
|
|
if (pDeleteElement->mapAddr != (void *)pDeleteElement->IONBuffer) {
|
|
if (Exynos_OSAL_Munmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
|
|
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Munmap", __FUNCTION__);
|
|
goto EXIT;
|
|
}
|
|
}
|
|
|
|
pDeleteElement->mapAddr = NULL;
|
|
pDeleteElement->allocSize = 0;
|
|
|
|
if (pDeleteElement->owner) {
|
|
/* free a ion_buffer */
|
|
close(pDeleteElement->IONBuffer);
|
|
mem_cnt--;
|
|
}
|
|
pDeleteElement->IONBuffer = 0;
|
|
|
|
Exynos_OSAL_Free(pDeleteElement);
|
|
|
|
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] count: %d", __FUNCTION__, mem_cnt);
|
|
|
|
EXIT:
|
|
return;
|
|
}
|
|
|
|
OMX_PTR Exynos_OSAL_SharedMemory_Map(OMX_HANDLETYPE handle, OMX_U32 size, unsigned long ionfd)
|
|
{
|
|
EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
|
|
EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
|
|
EXYNOS_SHAREDMEM_LIST *pElement = NULL;
|
|
EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
|
|
OMX_S32 IONBuffer = 0;
|
|
OMX_PTR pBuffer = NULL;
|
|
|
|
if (pHandle == NULL) {
|
|
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] invalid parameter", __FUNCTION__);
|
|
goto EXIT;
|
|
}
|
|
|
|
pElement = (EXYNOS_SHAREDMEM_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHAREDMEM_LIST));
|
|
if (pElement == NULL) {
|
|
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Malloc()", __FUNCTION__);
|
|
goto EXIT;
|
|
}
|
|
|
|
Exynos_OSAL_Memset(pElement, 0, sizeof(EXYNOS_SHAREDMEM_LIST));
|
|
|
|
IONBuffer = (OMX_S32)ionfd;
|
|
|
|
if (IONBuffer < 0) {
|
|
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] FD(%u) is wrong", __FUNCTION__, IONBuffer);
|
|
Exynos_OSAL_Free((void*)pElement);
|
|
goto EXIT;
|
|
}
|
|
|
|
pBuffer = Exynos_OSAL_Mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, IONBuffer, 0);
|
|
if (pBuffer == NULL) {
|
|
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Mmap(size:%d)", __FUNCTION__, size);
|
|
/* free a ion_buffer */
|
|
close(IONBuffer);
|
|
Exynos_OSAL_Free((void*)pElement);
|
|
goto EXIT;
|
|
}
|
|
|
|
pElement->IONBuffer = IONBuffer;
|
|
pElement->mapAddr = pBuffer;
|
|
pElement->allocSize = size;
|
|
pElement->pNextMemory = NULL;
|
|
|
|
Exynos_OSAL_MutexLock(pHandle->hSMMutex);
|
|
pSMList = pHandle->pAllocMemory;
|
|
if (pSMList == NULL) {
|
|
pHandle->pAllocMemory = pSMList = pElement;
|
|
} else {
|
|
pCurrentElement = pSMList;
|
|
while (pCurrentElement->pNextMemory != NULL) {
|
|
pCurrentElement = pCurrentElement->pNextMemory;
|
|
}
|
|
pCurrentElement->pNextMemory = pElement;
|
|
}
|
|
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
|
|
|
|
map_cnt++;
|
|
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] count: %d", __FUNCTION__, map_cnt);
|
|
|
|
EXIT:
|
|
return pBuffer;
|
|
}
|
|
|
|
void Exynos_OSAL_SharedMemory_Unmap(OMX_HANDLETYPE handle, unsigned long ionfd)
|
|
{
|
|
EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
|
|
EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
|
|
EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
|
|
EXYNOS_SHAREDMEM_LIST *pDeleteElement = NULL;
|
|
|
|
if (pHandle == NULL)
|
|
goto EXIT;
|
|
|
|
Exynos_OSAL_MutexLock(pHandle->hSMMutex);
|
|
pSMList = pHandle->pAllocMemory;
|
|
if (pSMList == NULL) {
|
|
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
|
|
goto EXIT;
|
|
}
|
|
|
|
pCurrentElement = pSMList;
|
|
if (pSMList->IONBuffer == ionfd) {
|
|
pDeleteElement = pSMList;
|
|
pHandle->pAllocMemory = pSMList = pSMList->pNextMemory;
|
|
} else {
|
|
while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
|
|
(((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer != ionfd))
|
|
pCurrentElement = pCurrentElement->pNextMemory;
|
|
|
|
if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
|
|
(((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer == ionfd)) {
|
|
pDeleteElement = pCurrentElement->pNextMemory;
|
|
pCurrentElement->pNextMemory = pDeleteElement->pNextMemory;
|
|
} else {
|
|
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
|
|
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] can't find a buffer(%u) in list", __FUNCTION__, ionfd);
|
|
goto EXIT;
|
|
}
|
|
}
|
|
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
|
|
|
|
if (Exynos_OSAL_Munmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
|
|
Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%s] Failed to Exynos_OSAL_Munmap", __FUNCTION__);
|
|
goto EXIT;
|
|
}
|
|
pDeleteElement->mapAddr = NULL;
|
|
pDeleteElement->allocSize = 0;
|
|
pDeleteElement->IONBuffer = 0;
|
|
|
|
Exynos_OSAL_Free(pDeleteElement);
|
|
|
|
map_cnt--;
|
|
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] count: %d", __FUNCTION__, map_cnt);
|
|
|
|
EXIT:
|
|
return;
|
|
}
|
|
|
|
unsigned long Exynos_OSAL_SharedMemory_VirtToION(OMX_HANDLETYPE handle, OMX_PTR pBuffer)
|
|
{
|
|
EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
|
|
EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
|
|
EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
|
|
EXYNOS_SHAREDMEM_LIST *pFindElement = NULL;
|
|
|
|
unsigned long ion_addr = 0;
|
|
|
|
if (pHandle == NULL || pBuffer == NULL)
|
|
goto EXIT;
|
|
|
|
Exynos_OSAL_MutexLock(pHandle->hSMMutex);
|
|
pSMList = pHandle->pAllocMemory;
|
|
if (pSMList == NULL) {
|
|
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
|
|
goto EXIT;
|
|
}
|
|
|
|
pCurrentElement = pSMList;
|
|
if (pSMList->mapAddr == pBuffer) {
|
|
pFindElement = pSMList;
|
|
} else {
|
|
while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
|
|
(((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr != pBuffer))
|
|
pCurrentElement = pCurrentElement->pNextMemory;
|
|
|
|
if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
|
|
(((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr == pBuffer)) {
|
|
pFindElement = pCurrentElement->pNextMemory;
|
|
} else {
|
|
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
|
|
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] can't find a buffer(%p) in list", __FUNCTION__, pBuffer);
|
|
goto EXIT;
|
|
}
|
|
}
|
|
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
|
|
|
|
ion_addr = pFindElement->IONBuffer;
|
|
|
|
EXIT:
|
|
return ion_addr;
|
|
}
|
|
|
|
OMX_PTR Exynos_OSAL_SharedMemory_IONToVirt(OMX_HANDLETYPE handle, unsigned long ionfd)
|
|
{
|
|
EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
|
|
EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
|
|
EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
|
|
EXYNOS_SHAREDMEM_LIST *pFindElement = NULL;
|
|
|
|
OMX_PTR pBuffer = NULL;
|
|
|
|
if ((pHandle == NULL) || ((long)ionfd < 0))
|
|
goto EXIT;
|
|
|
|
Exynos_OSAL_MutexLock(pHandle->hSMMutex);
|
|
pSMList = pHandle->pAllocMemory;
|
|
if (pSMList == NULL) {
|
|
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
|
|
goto EXIT;
|
|
}
|
|
|
|
pCurrentElement = pSMList;
|
|
if (pSMList->IONBuffer == ionfd) {
|
|
pFindElement = pSMList;
|
|
} else {
|
|
while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
|
|
(((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer != ionfd))
|
|
pCurrentElement = pCurrentElement->pNextMemory;
|
|
|
|
if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
|
|
(((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer == ionfd)) {
|
|
pFindElement = pCurrentElement->pNextMemory;
|
|
} else {
|
|
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
|
|
Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%s] can't find a buffer(%u) in list", __FUNCTION__, ionfd);
|
|
goto EXIT;
|
|
}
|
|
}
|
|
Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
|
|
|
|
pBuffer = pFindElement->mapAddr;
|
|
|
|
EXIT:
|
|
return pBuffer;
|
|
}
|