3 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file Exynos_OSAL_SharedMemory.c
21 * @author SeungBeom Kim (sbcrux.kim@samsung.com)
22 * Taehwan Kim (t_h.kim@samsung.com)
34 #ifndef TIZEN_FEATURE_E3250 /* build env */
35 #include <cutils/log.h>
36 #include <cutils/atomic.h>
41 #include "Exynos_OSAL_Memory.h"
42 #include "Exynos_OSAL_SharedMemory.h"
43 #include "Exynos_OSAL_Mutex.h"
46 #define EXYNOS_LOG_OFF
47 #include "Exynos_OSAL_Log.h"
49 static int mem_cnt = 0;
51 struct EXYNOS_SHAREDMEM_LIST;
52 typedef struct _EXYNOS_SHAREDMEM_LIST
58 struct _EXYNOS_SHAREDMEM_LIST *pNextMemory;
59 } EXYNOS_SHAREDMEM_LIST;
61 typedef struct _EXYNOS_SHARED_MEMORY
63 OMX_HANDLETYPE hIONHandle;
64 EXYNOS_SHAREDMEM_LIST *pAllocMemory;
65 OMX_HANDLETYPE hSMMutex;
66 } EXYNOS_SHARED_MEMORY;
69 OMX_HANDLETYPE Exynos_OSAL_SharedMemory_Open()
71 EXYNOS_SHARED_MEMORY *pHandle = NULL;
72 ion_client IONClient = 0;
74 pHandle = (EXYNOS_SHARED_MEMORY *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHARED_MEMORY));
75 Exynos_OSAL_Memset(pHandle, 0, sizeof(EXYNOS_SHARED_MEMORY));
79 IONClient = (OMX_HANDLETYPE)ion_client_create();
81 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_client_create Error: %d", IONClient);
82 Exynos_OSAL_Free((void *)pHandle);
87 pHandle->hIONHandle = IONClient;
89 Exynos_OSAL_MutexCreate(&pHandle->hSMMutex);
92 return (OMX_HANDLETYPE)pHandle;
95 void Exynos_OSAL_SharedMemory_Close(OMX_HANDLETYPE handle)
97 EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
98 EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
99 EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
100 EXYNOS_SHAREDMEM_LIST *pDeleteElement = NULL;
105 Exynos_OSAL_MutexLock(pHandle->hSMMutex);
106 pCurrentElement = pSMList = pHandle->pAllocMemory;
108 while (pCurrentElement != NULL) {
109 pDeleteElement = pCurrentElement;
110 pCurrentElement = pCurrentElement->pNextMemory;
112 if (ion_unmap(pDeleteElement->mapAddr, pDeleteElement->allocSize))
113 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_unmap fail");
115 pDeleteElement->mapAddr = NULL;
116 pDeleteElement->allocSize = 0;
118 if (pDeleteElement->owner)
119 ion_free(pDeleteElement->IONBuffer);
120 pDeleteElement->IONBuffer = 0;
122 Exynos_OSAL_Free(pDeleteElement);
125 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory free count: %d", mem_cnt);
128 pHandle->pAllocMemory = pSMList = NULL;
129 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
131 Exynos_OSAL_MutexTerminate(pHandle->hSMMutex);
132 pHandle->hSMMutex = NULL;
134 ion_client_destroy((ion_client)pHandle->hIONHandle);
135 pHandle->hIONHandle = NULL;
137 Exynos_OSAL_Free(pHandle);
143 OMX_PTR Exynos_OSAL_SharedMemory_Alloc(OMX_HANDLETYPE handle, OMX_U32 size, MEMORY_TYPE memoryType)
145 EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
146 EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
147 EXYNOS_SHAREDMEM_LIST *pElement = NULL;
148 EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
149 ion_buffer IONBuffer = 0;
150 OMX_PTR pBuffer = NULL;
157 pElement = (EXYNOS_SHAREDMEM_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHAREDMEM_LIST));
158 Exynos_OSAL_Memset(pElement, 0, sizeof(EXYNOS_SHAREDMEM_LIST));
159 pElement->owner = true;
161 switch (memoryType) {
163 mask = ION_HEAP_EXYNOS_CONTIG_MASK;
164 flag = ION_EXYNOS_FIMD_VIDEO_MASK;
167 mask = ION_HEAP_EXYNOS_MASK;
171 mask = ION_HEAP_SYSTEM_MASK;
172 flag = ION_FLAG_CACHED;
180 IONBuffer = ion_alloc((ion_client)pHandle->hIONHandle, size, 0, mask, flag);
182 if (IONBuffer <= 0) {
183 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_alloc Error: %d", IONBuffer);
184 Exynos_OSAL_Free((OMX_PTR)pElement);
188 pBuffer = ion_map(IONBuffer, size, 0);
189 if (pBuffer == MAP_FAILED) {
190 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_map Error");
192 Exynos_OSAL_Free((OMX_PTR)pElement);
197 pElement->IONBuffer = IONBuffer;
198 pElement->mapAddr = pBuffer;
199 pElement->allocSize = size;
200 pElement->pNextMemory = NULL;
202 Exynos_OSAL_MutexLock(pHandle->hSMMutex);
203 pSMList = pHandle->pAllocMemory;
204 if (pSMList == NULL) {
205 pHandle->pAllocMemory = pSMList = pElement;
207 pCurrentElement = pSMList;
208 while (pCurrentElement->pNextMemory != NULL) {
209 pCurrentElement = pCurrentElement->pNextMemory;
211 pCurrentElement->pNextMemory = pElement;
213 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
216 #ifndef TIZEN_FEATURE_E3250
217 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory alloc count: %d", mem_cnt);
219 Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "SharedMemory alloc count: %d", mem_cnt);
226 void Exynos_OSAL_SharedMemory_Free(OMX_HANDLETYPE handle, OMX_PTR pBuffer)
228 EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
229 EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
230 EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
231 EXYNOS_SHAREDMEM_LIST *pDeleteElement = NULL;
236 Exynos_OSAL_MutexLock(pHandle->hSMMutex);
237 pSMList = pHandle->pAllocMemory;
238 if (pSMList == NULL) {
239 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
243 pCurrentElement = pSMList;
244 if (pSMList->mapAddr == pBuffer) {
245 pDeleteElement = pSMList;
246 pHandle->pAllocMemory = pSMList = pSMList->pNextMemory;
248 while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
249 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr != pBuffer))
250 pCurrentElement = pCurrentElement->pNextMemory;
252 if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
253 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr == pBuffer)) {
254 pDeleteElement = pCurrentElement->pNextMemory;
255 pCurrentElement->pNextMemory = pDeleteElement->pNextMemory;
257 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
258 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find SharedMemory");
262 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
264 if (ion_unmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
265 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_unmap fail");
268 pDeleteElement->mapAddr = NULL;
269 pDeleteElement->allocSize = 0;
271 if (pDeleteElement->owner)
272 ion_free(pDeleteElement->IONBuffer);
273 pDeleteElement->IONBuffer = 0;
275 Exynos_OSAL_Free(pDeleteElement);
278 #ifndef TIZEN_FEATURE_E3250
279 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory free count: %d", mem_cnt);
281 Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "SharedMemory free count: %d", mem_cnt);
289 OMX_PTR Exynos_OSAL_SharedMemory_Map(OMX_HANDLETYPE handle, OMX_U32 size, unsigned int ionfd)
291 EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
292 EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
293 EXYNOS_SHAREDMEM_LIST *pElement = NULL;
294 EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
295 ion_buffer IONBuffer = 0;
296 OMX_PTR pBuffer = NULL;
301 pElement = (EXYNOS_SHAREDMEM_LIST *)Exynos_OSAL_Malloc(sizeof(EXYNOS_SHAREDMEM_LIST));
302 Exynos_OSAL_Memset(pElement, 0, sizeof(EXYNOS_SHAREDMEM_LIST));
304 IONBuffer = (OMX_PTR)ionfd;
306 if (IONBuffer <= 0) {
307 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_alloc Error: %d", IONBuffer);
308 Exynos_OSAL_Free((void*)pElement);
312 pBuffer = ion_map(IONBuffer, size, 0);
313 if (pBuffer == NULL) {
314 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_map Error");
316 Exynos_OSAL_Free((void*)pElement);
320 pElement->IONBuffer = IONBuffer;
321 pElement->mapAddr = pBuffer;
322 pElement->allocSize = size;
323 pElement->pNextMemory = NULL;
325 Exynos_OSAL_MutexLock(pHandle->hSMMutex);
326 pSMList = pHandle->pAllocMemory;
327 if (pSMList == NULL) {
328 pHandle->pAllocMemory = pSMList = pElement;
330 pCurrentElement = pSMList;
331 while (pCurrentElement->pNextMemory != NULL) {
332 pCurrentElement = pCurrentElement->pNextMemory;
334 pCurrentElement->pNextMemory = pElement;
336 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
339 #ifndef TIZEN_FEATURE_E3250
340 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory alloc count: %d", mem_cnt);
342 Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "SharedMemory alloc count: %d", mem_cnt);
349 void Exynos_OSAL_SharedMemory_Unmap(OMX_HANDLETYPE handle, unsigned int ionfd)
351 EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
352 EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
353 EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
354 EXYNOS_SHAREDMEM_LIST *pDeleteElement = NULL;
359 Exynos_OSAL_MutexLock(pHandle->hSMMutex);
360 pSMList = pHandle->pAllocMemory;
361 if (pSMList == NULL) {
362 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
366 pCurrentElement = pSMList;
367 if (pSMList->IONBuffer == ionfd) {
368 pDeleteElement = pSMList;
369 pHandle->pAllocMemory = pSMList = pSMList->pNextMemory;
371 while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
372 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer != ionfd))
373 pCurrentElement = pCurrentElement->pNextMemory;
375 if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
376 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer == ionfd)) {
377 pDeleteElement = pCurrentElement->pNextMemory;
378 pCurrentElement->pNextMemory = pDeleteElement->pNextMemory;
380 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
381 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find SharedMemory");
385 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
387 if (ion_unmap(pDeleteElement->mapAddr, pDeleteElement->allocSize)) {
388 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "ion_unmap fail");
391 pDeleteElement->mapAddr = NULL;
392 pDeleteElement->allocSize = 0;
393 pDeleteElement->IONBuffer = 0;
395 Exynos_OSAL_Free(pDeleteElement);
398 #ifndef TIZEN_FEATURE_E3250
399 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SharedMemory free count: %d", mem_cnt);
401 Exynos_OSAL_Log(EXYNOS_LOG_VERVOSE, "SharedMemory free count: %d", mem_cnt);
409 int Exynos_OSAL_SharedMemory_VirtToION(OMX_HANDLETYPE handle, OMX_PTR pBuffer)
411 EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
412 EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
413 EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
414 EXYNOS_SHAREDMEM_LIST *pFindElement = NULL;
416 if (pHandle == NULL || pBuffer == NULL)
419 Exynos_OSAL_MutexLock(pHandle->hSMMutex);
420 pSMList = pHandle->pAllocMemory;
421 if (pSMList == NULL) {
422 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
426 pCurrentElement = pSMList;
427 if (pSMList->mapAddr == pBuffer) {
428 pFindElement = pSMList;
430 while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
431 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr != pBuffer))
432 pCurrentElement = pCurrentElement->pNextMemory;
434 if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
435 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->mapAddr == pBuffer)) {
436 pFindElement = pCurrentElement->pNextMemory;
438 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
439 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find SharedMemory");
443 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
445 ion_addr = pFindElement->IONBuffer;
451 OMX_PTR Exynos_OSAL_SharedMemory_IONToVirt(OMX_HANDLETYPE handle, int ion_addr)
453 EXYNOS_SHARED_MEMORY *pHandle = (EXYNOS_SHARED_MEMORY *)handle;
454 EXYNOS_SHAREDMEM_LIST *pSMList = NULL;
455 EXYNOS_SHAREDMEM_LIST *pCurrentElement = NULL;
456 EXYNOS_SHAREDMEM_LIST *pFindElement = NULL;
457 OMX_PTR pBuffer = NULL;
458 if (pHandle == NULL || ion_addr == 0)
461 Exynos_OSAL_MutexLock(pHandle->hSMMutex);
462 pSMList = pHandle->pAllocMemory;
463 if (pSMList == NULL) {
464 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
468 pCurrentElement = pSMList;
469 if (pSMList->IONBuffer == ion_addr) {
470 pFindElement = pSMList;
472 while ((pCurrentElement != NULL) && (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
473 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer != ion_addr))
474 pCurrentElement = pCurrentElement->pNextMemory;
476 if ((((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory)) != NULL) &&
477 (((EXYNOS_SHAREDMEM_LIST *)(pCurrentElement->pNextMemory))->IONBuffer == ion_addr)) {
478 pFindElement = pCurrentElement->pNextMemory;
480 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
481 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find SharedMemory");
485 Exynos_OSAL_MutexUnlock(pHandle->hSMMutex);
487 pBuffer = pFindElement->mapAddr;