/*! ****************************************************************************** @Function VXDIO_GetMemSpaces ******************************************************************************/ IMG_RESULT VXDIO_GetMemSpacesHandles(IMG_UINT32 ui32CoreNum, VXD_eDevType eDeviceType, IMG_HANDLE ** ppahMemSpace ) { switch (eDeviceType) { #ifdef VDEC_USE_PVDEC case VXD_DEV_PVDEC: *ppahMemSpace = IMG_MALLOC(REGION_PVDEC_MAX * sizeof(IMG_HANDLE)); if (*ppahMemSpace == IMG_NULL) { return IMG_ERROR_MALLOC_FAILED; } IMG_MEMSET(*ppahMemSpace, 0, REGION_PVDEC_MAX * sizeof(IMG_HANDLE)); return PVDECIO_GetMemSpaces(ui32CoreNum, *ppahMemSpace); #endif /* VDEC_USE_PVDEC */ case VXD_DEV_MSVDX: default: return IMG_ERROR_NOT_SUPPORTED; } }
/*! ****************************************************************************** @Function POOL_PoolCreate ******************************************************************************/ IMG_RESULT POOL_PoolCreate( IMG_HANDLE * phPoolHandle ) { POOL_sResPool * psResPool; IMG_UINT32 ui32Result; IMG_ASSERT(gInitialised); /* Allocate a pool structure...*/ psResPool = IMG_MALLOC(sizeof(*psResPool)); IMG_ASSERT(psResPool != IMG_NULL); if (psResPool == IMG_NULL) { return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psResPool, 0, sizeof(*psResPool)); /* Initialise the pool info...*/ LST_init(&psResPool->sFreeResList); LST_init(&psResPool->sActResList); /* Create mutex...*/ ui32Result = SYSOSKM_CreateMutex(&psResPool->hMutexHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_create_mutex; } /* Create context for the Id generator...*/ ui32Result = IDGEN_CreateContext(POOL_IDGEN_MAX_ID, POOL_IDGEN_BLOCK_SIZE,IMG_FALSE, &psResPool->hIdGenHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_create_context; } /* Disable interrupts. */ SYSOSKM_DisableInt(); /* Add to list of pools...*/ LST_add(&gsPoolList, psResPool); /* Enable interrupts. */ SYSOSKM_EnableInt(); /* Return handle to pool...*/ *phPoolHandle = psResPool; return IMG_SUCCESS; /* Error handling. */ error_create_context: SYSOSKM_DestroyMutex(psResPool->hMutexHandle); error_create_mutex: IMG_FREE(psResPool); return ui32Result; }
/*! ****************************************************************************** @Function SYSDEVKM_OpenDevice ******************************************************************************/ IMG_RESULT SYSDEVKM_OpenDevice( IMG_CHAR * pszDeviceName, IMG_HANDLE * phSysDevHandle ) { IMG_UINT32 ui32Result; SYSDEVKM_sDevice * psDevice; /* Allocate a device structure...*/ psDevice = IMG_MALLOC(sizeof(*psDevice)); IMG_ASSERT(psDevice != IMG_NULL); if (psDevice == IMG_NULL) { return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psDevice, 0, sizeof(*psDevice)); /* Get the device id...*/ ui32Result = SYSDEVU_GetDeviceId(pszDeviceName, &psDevice->ui32DeviceId); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } /* Return the device handle...*/ *phSysDevHandle = psDevice; /* Update count...*/ SYSOSKM_DisableInt(); gsActiveOpenCnt++; SYSOSKM_EnableInt(); return IMG_SUCCESS; }
/*! ****************************************************************************** @Function RMAN_CreateBucket ******************************************************************************/ IMG_RESULT RMAN_CreateBucket( IMG_HANDLE * phResBHandle ) { RMAN_sBucket * psBucket; IMG_UINT32 i; IMG_RESULT i32Result; IMG_ASSERT(gInitialised); /* Allocate a bucket structure...*/ psBucket = IMG_MALLOC(sizeof(*psBucket)); IMG_ASSERT(psBucket != IMG_NULL); if (psBucket == IMG_NULL) { return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psBucket, 0, sizeof(*psBucket)); /* Intialise the resource list...*/ DQ_init(&psBucket->sResList); /* The start allocating resource ids at the first...*/ i32Result = IDGEN_CreateContext(RMAN_MAX_ID, RMAN_ID_BLOCKSIZE, IMG_FALSE, &psBucket->hIdGenerator); if(i32Result != IMG_SUCCESS) { IMG_FREE(psBucket); IMG_ASSERT(!"failed to create IDGEN context"); return i32Result; } /* Locate free bucket index within the table...*/ SYSOSKM_DisableInt(); for (i=0; i<RMAN_CRESID_MAX_BUCKET_INDEX; i++) { if (gapsBucket[i] == IMG_NULL) { break; } } if (i >= RMAN_CRESID_MAX_BUCKET_INDEX) { SYSOSKM_EnableInt(); IDGEN_DestroyContext(psBucket->hIdGenerator); IMG_FREE(psBucket); IMG_ASSERT(!"No free buckets left"); return IMG_ERROR_GENERIC_FAILURE; } /* Allocate bucket index...*/ psBucket->ui32BucketIndex = i; gapsBucket[i] = psBucket; SYSOSKM_EnableInt(); /* Return the bucket handle...*/ *phResBHandle = psBucket; return IMG_SUCCESS; }
/*! ****************************************************************************** @Function palloc_fnCompConnect ******************************************************************************/ static IMG_RESULT palloc_fnCompConnect ( IMG_HANDLE hAttachHandle, IMG_VOID ** ppvCompAttachmentData ) { PALLOC_sAttachContext * psAttachContext; IMG_UINT32 ui32Result; IMG_CHAR * pszDeviceName; /* Allocate attachment context structure...*/ psAttachContext = IMG_MALLOC(sizeof(*psAttachContext)); IMG_ASSERT(psAttachContext != IMG_NULL); if (psAttachContext == IMG_NULL) { return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psAttachContext, 0, sizeof(*psAttachContext)); /* Ensure the resource manager is initialised...*/ ui32Result = RMAN_Initialise(); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_rman_init; } /* Create a bucket for the resources...*/ ui32Result = RMAN_CreateBucket(&psAttachContext->hResBHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_rman_bucket; } /* Get device information...*/ psAttachContext->hDevHandle = DMANKM_GetDevHandleFromAttach(hAttachHandle); pszDeviceName = DMANKM_GetDeviceName(psAttachContext->hDevHandle); ui32Result = SYSDEVU_OpenDevice(pszDeviceName, &psAttachContext->hSysDevHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_sysdev_open; } /* Return attachment context...*/ *ppvCompAttachmentData = psAttachContext; /* Return success...*/ return IMG_SUCCESS; /* Error handling. */ error_sysdev_open: RMAN_DestroyBucket(psAttachContext->hResBHandle); error_rman_bucket: error_rman_init: IMG_FREE(psAttachContext); return ui32Result; }
IMG_RESULT SYSMEMKM_AddCarveoutMemory( IMG_UINTPTR vstart, IMG_PHYSADDR pstart, IMG_UINT32 size, SYS_eMemPool * peMemPool ) { IMG_RESULT ui32Result; struct priv_params *prv; struct gen_pool *pool = gen_pool_create(12, -1); prv = (struct priv_params *)IMG_MALLOC(sizeof(*prv)); IMG_ASSERT(prv != IMG_NULL); if(IMG_NULL == prv) { ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_priv_alloc; } IMG_MEMSET((void *)prv, 0, sizeof(*prv)); IMG_ASSERT(pool != IMG_NULL); IMG_ASSERT(size != 0); IMG_ASSERT((vstart & (HOST_MMU_PAGE_SIZE-1)) == 0); gen_pool_add_virt(pool, (unsigned long)vstart, (unsigned long)pstart, size, -1); prv->pool = pool; prv->pstart = pstart; prv->size = size; prv->vstart = vstart; ui32Result = SYSMEMU_AddMemoryHeap(&carveout_ops, IMG_TRUE, (IMG_VOID *)prv, peMemPool); IMG_ASSERT(IMG_SUCCESS == ui32Result); if(IMG_SUCCESS != ui32Result) { goto error_heap_add; } return IMG_SUCCESS; error_heap_add: IMG_FREE(prv); error_priv_alloc: gen_pool_destroy(pool); return ui32Result; }
/*! ****************************************************************************** @Function RMAN_Initialise ******************************************************************************/ IMG_RESULT RMAN_Initialise(IMG_VOID) { IMG_UINT32 ui32Result; /* If not initialised...*/ if (!gInitialised) { /* Initialise the active buckets list...*/ IMG_MEMSET(&gapsBucket[0], 0, sizeof(gapsBucket)); /* Create mutex...*/ ui32Result = SYSOSKM_CreateMutex(&ghSharedResMutexHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } /* Set initialised flag...*/ gInitialised = IMG_TRUE; /* Create the global resource bucket...*/ ui32Result = RMAN_CreateBucket((IMG_HANDLE *)&gpsGlobalResBucket); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } /* Create the shared resource bucket...*/ ui32Result = RMAN_CreateBucket((IMG_HANDLE *)&gpsSharedResBucket); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } SYSOSKM_CreateMutex(&globalMutext); } /* Return success...*/ return IMG_SUCCESS; }
static IMG_RESULT perflog_CreateBuffer(perflog_Buffer **ppsBuffer, IMG_SIZE stBuffSize) { perflog_Buffer *psBuffer = NULL; if(ppsBuffer == NULL || *ppsBuffer != NULL) { REPORT(REPORT_MODULE_PERFLOG, REPORT_ERR, "Performance logger cannot create buffer: invalid parameters"); return IMG_ERROR_INVALID_PARAMETERS; } //alloc buffer struct *ppsBuffer = (perflog_Buffer*) IMG_MALLOC(sizeof(perflog_Buffer)); IMG_ASSERT(*ppsBuffer != IMG_NULL); if(*ppsBuffer == IMG_NULL) { REPORT(REPORT_MODULE_PERFLOG, REPORT_ERR, "Performance logger cannot allocate memory for buffer struct"); return IMG_ERROR_MALLOC_FAILED; } psBuffer = *ppsBuffer; //alloc buffer itself psBuffer->pui64Buffer = (IMG_UINT64*) IMG_MALLOC(sizeof(IMG_UINT64) * stBuffSize); IMG_ASSERT(psBuffer->pui64Buffer != IMG_NULL); if(psBuffer->pui64Buffer == IMG_NULL) { IMG_FREE(psBuffer); REPORT(REPORT_MODULE_PERFLOG, REPORT_ERR, "Performance logger cannot allocate buffers"); return IMG_ERROR_MALLOC_FAILED; } IMG_MEMSET(psBuffer->pui64Buffer, 0,sizeof(IMG_UINT64) * stBuffSize); psBuffer->stIter = 0; psBuffer->stBufferSize = stBuffSize; return IMG_SUCCESS; }
/*! ****************************************************************************** @Function DMANKM_RegisterDevice ******************************************************************************/ IMG_RESULT DMANKM_RegisterDevice(IMG_CHAR * pszDeviceName, DMANKM_pfnDevRegister pfnDevRegister) { DMANKM_sDevContext * psDevContext; IMG_UINT32 ui32Result; /* If the device context list is not initialised...*/ if (!gbDevListInitialised) { /* Initialise the device context list...*/ LST_init(&gsDevList); gbDevListInitialised = IMG_TRUE; } /* Locate the device - ensure it's not registered twice...*/ ui32Result = DMANKM_LocateDevice(pszDeviceName, (IMG_HANDLE *) &psDevContext); if (ui32Result != IMG_ERROR_DEVICE_NOT_FOUND) { IMG_ASSERT(ui32Result == IMG_ERROR_DEVICE_NOT_FOUND); return IMG_ERROR_GENERIC_FAILURE; } /* Allocate a device context structure...*/ psDevContext = IMG_MALLOC(sizeof(*psDevContext)); if (psDevContext == IMG_NULL ) { IMG_ASSERT(psDevContext != IMG_NULL); return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psDevContext, 0, sizeof(*psDevContext)); /* Setup the device context...*/ psDevContext->ui32DeviceId = gui32NextDeviceID; gui32NextDeviceID++; psDevContext->pszDeviceName = IMG_STRDUP(pszDeviceName); if (psDevContext->pszDeviceName == IMG_NULL ) { IMG_ASSERT(psDevContext->pszDeviceName != IMG_NULL); ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_dev_name; } psDevContext->pfnDevRegister = pfnDevRegister; psDevContext->ui8ApmPpmFlags = 0; ui32Result = SYSOSKM_CreateMutex(&psDevContext->hMutexHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_create_mutex; } LST_init(&psDevContext->sConnList); /* Disable interrupts...*/ SYSOSKM_DisableInt(); /* Add device to list...*/ LST_add(&gsDevList, psDevContext); /* Re-enable interrupts...*/ SYSOSKM_EnableInt(); /* If initialised...*/ if (gDmanKmInitialised) { /* Call device registration function...*/ ui32Result = psDevContext->pfnDevRegister(&psDevContext->sDevRegister); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_dev_register; } /* Set default if required...*/ if (psDevContext->sDevRegister.ui32ConnFlags == 0) { psDevContext->sDevRegister.ui32ConnFlags = DMAN_CFLAG_EXCLUSIVE; } } /* Return success...*/ return IMG_SUCCESS; /* Error handling. */ error_dev_register: SYSOSKM_DisableInt(); LST_remove(&gsDevList, psDevContext); SYSOSKM_EnableInt(); SYSOSKM_DestroyMutex(psDevContext->hMutexHandle); error_create_mutex: IMG_FREE(psDevContext->pszDeviceName); error_dev_name: IMG_FREE(psDevContext); return ui32Result; }
/*! ****************************************************************************** @Function DMANKM_OpenDevice ******************************************************************************/ IMG_RESULT DMANKM_OpenDevice(IMG_HANDLE hDevHandle, DMAN_eOpenMode eOpenMode, IMG_HANDLE * phConnHandle, IMG_UINT32 * pui32ConnId) { DMANKM_sDevContext * psDevContext = (DMANKM_sDevContext *) hDevHandle; DMANKM_sConnContext * psConnContext; DMANKM_sConnContext * psInitConnContext = IMG_NULL; IMG_UINT32 ui32Result; IMG_HANDLE hProcessId; /* Check mode. */ if ((eOpenMode != DMAN_OMODE_EXCLUSIVE) && (eOpenMode != DMAN_OMODE_SHARED)) { IMG_ASSERT(IMG_FALSE); return IMG_ERROR_INVALID_PARAMETERS; } /* Loop over the device connections to see if this process already has a connection...*/ hProcessId = SYSOSKM_GetProcessId(); psConnContext = (DMANKM_sConnContext *) LST_first(&psDevContext->sConnList); while (psConnContext != IMG_NULL ) { /* If process already has a connection. */ if (psConnContext->hProcessId == hProcessId) { /* Update the open count...*/ psConnContext->ui32OpenCnt++; /* Return the connection handle and/or id...*/ if (phConnHandle != IMG_NULL ) { *phConnHandle = psConnContext; } if (pui32ConnId != IMG_NULL ) { *pui32ConnId = psConnContext->ui32ConnId; } /* Return success...*/ return IMG_SUCCESS; } /* Look at next connection. */ psConnContext = (DMANKM_sConnContext *) LST_next(psConnContext); } /* See if we have a connection exclusive access required or only exclusive access available. */ psConnContext = (DMANKM_sConnContext *) LST_first(&psDevContext->sConnList); if ((psConnContext != IMG_NULL )&& ( (eOpenMode == DMAN_OMODE_EXCLUSIVE) || (psConnContext->psDevContext->sDevRegister.ui32ConnFlags == DMAN_CFLAG_EXCLUSIVE) ) ){ IMG_ASSERT(IMG_FALSE); return IMG_ERROR_DEVICE_UNAVAILABLE; } /* Allocate connection context...*/ psConnContext = IMG_MALLOC(sizeof(*psConnContext)); if (psConnContext == IMG_NULL ) { IMG_ASSERT(psConnContext != IMG_NULL); return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psConnContext, 0, sizeof(*psConnContext)); /* Initialise list of resource allocator...*/ LST_init(&psConnContext->sAttachList); /* Setup connection context...*/ psConnContext->psDevContext = psDevContext; psConnContext->ui32OpenCnt = 1; psConnContext->hProcessId = hProcessId; /* Update the count of connections...*/ psDevContext->ui32ConnCnt++; /* If this is the first connection...*/ if (psDevContext->ui32ConnCnt == 1) { /* Create resource bucket for connections and attachments...*/ RMAN_Initialise(); ui32Result = RMAN_CreateBucket(&psDevContext->hResBHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_create_bucket; } } /* Add to list of connections...*/ LST_add(&psDevContext->sConnList, psConnContext); ui32Result = RMAN_RegisterResource(psDevContext->hResBHandle, DMAN_CONN_TYPE_ID, IMG_NULL, psConnContext, &psConnContext->hResHandle, &psConnContext->ui32ConnId); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_register_resource; } /* Register with the Process Manager in case the process dies...*/ ui32Result = PMAN_Initialise(); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_pman_init; } PMAN_RegisterProcessLostCb(dmankm_fnProcessLostCb, psConnContext, &psConnContext->hProcLostCbHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_pman_register_cb; } /* If this the first connection and initialise function...*/ if ((psDevContext->ui32ConnCnt == 1) && (psDevContext->sDevRegister.pfnDevInit != IMG_NULL )) { /* Allocate implicit connection context...*/ psInitConnContext = IMG_MALLOC(sizeof(*psInitConnContext)); if (psInitConnContext == IMG_NULL ) { IMG_ASSERT(psInitConnContext != IMG_NULL); ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_init_conn_ctx; } IMG_MEMSET(psInitConnContext, 0, sizeof(*psInitConnContext)); /* Associated this connection with the device and process...*/ psInitConnContext->psDevContext = psDevContext; psInitConnContext->ui32OpenCnt = 1; psInitConnContext->hProcessId = hProcessId; /* Mark this as the init connection...*/ psInitConnContext->bInitConn = IMG_TRUE; /* Add implicit to list of connections...*/ LST_add(&psDevContext->sConnList, psInitConnContext); ui32Result = RMAN_RegisterResource(psDevContext->hResBHandle, DMAN_CONN_TYPE_ID, IMG_NULL, psInitConnContext, &psInitConnContext->hResHandle, &psInitConnContext->ui32ConnId); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_register_resource_init_ctx; } IMG_ASSERT( (psDevContext->sDevRegister.ui32ConnFlags == DMAN_CFLAG_EXCLUSIVE) || (psDevContext->sDevRegister.ui32ConnFlags == DMAN_CFLAG_SHARED)); /* If it's not a pseudo device... */ if ((psDevContext->sDevRegister.ui32DevFlags & DMAN_DFLAG_PSEUDO_DEVICE) == 0) { /* Open the device...*/ ui32Result = SYSDEVU_OpenDevice(psDevContext->pszDeviceName, &psDevContext->hSysDevHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_open_device; } /* Power the device on. */ SYSDEVU_SetPowerState(psDevContext->hSysDevHandle, SYSOSKM_POWERSTATE_S0, IMG_FALSE); } ui32Result = psDevContext->sDevRegister.pfnDevInit(psDevContext, psInitConnContext, &psDevContext->pvDevInstanceData); if (ui32Result != IMG_SUCCESS) { REPORT(REPORT_MODULE_DMAN, REPORT_ERR, "dev init failed (%d)", ui32Result); goto error_dev_init; } /* If there is a Device Kernel mode HISR...*/ if (psDevContext->sDevRegister.pfnDevKmHisr != IMG_NULL ) { IMG_ASSERT(psDevContext->sDevRegister.pfnDevKmLisr != IMG_NULL); ui32Result = SYSOSKM_CreateKmHisr(&dmankm_fnDevKmHisr, psDevContext, &psDevContext->hHISRHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_create_km_hisr; } } /* If there is a Device Kernel mode LISR...*/ if (psDevContext->sDevRegister.pfnDevKmLisr != IMG_NULL ) { /* Register the LISR wrapper...*/ SYSDEVU_RegisterDevKmLisr(psDevContext->hSysDevHandle, &dmankm_fnDevKmLisr, psDevContext); } } /* If connect/open function...*/ if (psDevContext->sDevRegister.pfnDevConnect != IMG_NULL ) { ui32Result = psDevContext->sDevRegister.pfnDevConnect(psConnContext, psDevContext->pvDevInstanceData, &psConnContext->pvDevConnectionData); IMG_ASSERT( ui32Result == IMG_SUCCESS || ui32Result == IMG_ERROR_INTERRUPTED); if (ui32Result != IMG_SUCCESS && ui32Result != IMG_ERROR_INTERRUPTED) { goto error_dev_connect; } } /* Return the connection handle and/or id...*/ if (phConnHandle != IMG_NULL ) { *phConnHandle = psConnContext; } if (pui32ConnId != IMG_NULL ) { *pui32ConnId = psConnContext->ui32ConnId; } /* Return success...*/ return ui32Result; /* Error handling. */ error_dev_connect: /* If this not the first connection or there's no initialise function...*/ if ((1 != psDevContext->ui32ConnCnt) || (IMG_NULL == psDevContext->sDevRegister.pfnDevInit)) { /* ...skip de-initialisation of this part. */ goto error_init_conn_ctx; } if (IMG_NULL != psDevContext->sDevRegister.pfnDevKmHisr) { SYSOSKM_DestroyKmHisr(psDevContext->hHISRHandle); } error_create_km_hisr: if (IMG_NULL != psDevContext->sDevRegister.pfnDevDeinit) { psDevContext->sDevRegister.pfnDevDeinit(psDevContext, psInitConnContext, psDevContext->pvDevInstanceData); } error_dev_init: if ((psDevContext->sDevRegister.ui32DevFlags & DMAN_DFLAG_PSEUDO_DEVICE) == 0) { SYSDEVU_CloseDevice(psDevContext->hSysDevHandle); } error_open_device: RMAN_FreeResource(psInitConnContext->hResHandle); error_register_resource_init_ctx: LST_remove(&psDevContext->sConnList, psInitConnContext); IMG_FREE(psInitConnContext); error_init_conn_ctx: PMAN_RemoveProcessLostCb(psConnContext->hProcLostCbHandle); /* release per-process resources in PMAN, allocated inside PMAN_RegisterProcessLostCb. We have to use device disconnect, although the device wasn't actually initialised, because no other function is exposed by PMAN */ PMAN_DevDisconnectComplete(hProcessId); error_pman_register_cb: error_pman_init: RMAN_FreeResource(psConnContext->hResHandle); error_register_resource: LST_remove(&psDevContext->sConnList,psConnContext); if (1 == psDevContext->ui32ConnCnt) { RMAN_DestroyBucket(psDevContext->hResBHandle); } error_create_bucket: psDevContext->ui32ConnCnt--; IMG_FREE(psConnContext); return ui32Result; }
/*! ****************************************************************************** @Function DMANKM_AttachComponent ******************************************************************************/ IMG_RESULT DMANKM_AttachComponent(IMG_HANDLE hConnHandle, IMG_CHAR * pszCompName, DMANKM_pfnCompAttach pfnCompAttach, IMG_HANDLE * phAttachHandle, IMG_UINT32 * pui32AttachId) { DMANKM_sConnContext * psConnContext = (DMANKM_sConnContext *) hConnHandle; IMG_BOOL bFound; DMANKM_sAttachContext * psAttachContext; IMG_UINT32 ui32Result; IMG_ASSERT(gDmanKmInitialised); /* See if this component is already register with this connection...*/ bFound = dman_LocateComponentKM(pszCompName, psConnContext, &psAttachContext); if (bFound) { /* Cross check name and attach function should be the same...*/ IMG_ASSERT(psAttachContext->pfnCompAttach == pfnCompAttach); /* Return the attachment handle and/or id...*/ if (phAttachHandle != IMG_NULL ) { *phAttachHandle = psAttachContext; } if (pui32AttachId != IMG_NULL ) { *pui32AttachId = psAttachContext->ui32AttachId; } return IMG_SUCCESS; } /* Allocate a attachment context structure...*/ psAttachContext = IMG_MALLOC(sizeof(*psAttachContext)); if (psAttachContext == IMG_NULL ) { IMG_ASSERT(psAttachContext != IMG_NULL); return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psAttachContext, 0, sizeof(*psAttachContext)); /* Copy the component name etc...*/ psAttachContext->pszCompName = IMG_STRDUP(pszCompName); if (psAttachContext->pszCompName == IMG_NULL ) { IMG_ASSERT(psAttachContext->pszCompName != IMG_NULL); ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_comp_name; } psAttachContext->pfnCompAttach = pfnCompAttach; psAttachContext->psConnContext = psConnContext; ui32Result = RMAN_CreateBucket(&psAttachContext->hResBHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_create_bucket; } /* Add to the attachment component list...*/ LST_add(&psConnContext->sAttachList, psAttachContext); ui32Result = RMAN_RegisterResource(psConnContext->psDevContext->hResBHandle, DMAN_ATTACH_TYPE_ID, IMG_NULL, psAttachContext, &psAttachContext->hResHandle, &psAttachContext->ui32AttachId); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_register_resource; } /* Call components attach function...*/ ui32Result = pfnCompAttach(psAttachContext, &psAttachContext->sCompAttach); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_comp_attach; } /* If connect/open function...*/ if (psAttachContext->sCompAttach.pfnCompConnect != IMG_NULL ) { ui32Result = psAttachContext->sCompAttach.pfnCompConnect( psAttachContext, &psAttachContext->pvCompAttachmentData); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_comp_connect; } } /* Return the attachment handle and/or id...*/ if (phAttachHandle != IMG_NULL ) { *phAttachHandle = psAttachContext; } if (pui32AttachId != IMG_NULL ) { *pui32AttachId = psAttachContext->ui32AttachId; } /* Return success...*/ return IMG_SUCCESS; /* Error handling. */ error_comp_connect: error_comp_attach: RMAN_FreeResource( psAttachContext->hResHandle); error_register_resource: LST_remove(&psConnContext->sAttachList, psAttachContext); RMAN_DestroyBucket(psAttachContext->hResBHandle); error_create_bucket: IMG_FREE(psAttachContext->pszCompName); error_comp_name: IMG_FREE(psAttachContext); return ui32Result; }
/*! ****************************************************************************** @Function POOL_ResClone ******************************************************************************/ IMG_RESULT POOL_ResClone( IMG_HANDLE hPoolResHandle, IMG_HANDLE * phClonePoolResHandle, IMG_VOID ** ppvParam ) { POOL_sResource * psResource = hPoolResHandle; POOL_sResPool * psResPool; POOL_sResource * psOrigResource = psResource; POOL_sResource * psCloneResource; IMG_UINT32 ui32Result; IMG_ASSERT(gInitialised); IMG_ASSERT(psResource != IMG_NULL); if (!gInitialised || psResource == IMG_NULL) { ui32Result = IMG_ERROR_INVALID_PARAMETERS; goto error_nolock; } /* Allocate a resource structure...*/ psCloneResource = IMG_MALLOC(sizeof(*psCloneResource)); IMG_ASSERT(psCloneResource != IMG_NULL); if (psCloneResource == IMG_NULL) { return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psCloneResource, 0, sizeof(*psCloneResource)); psResPool = psResource->psResPool; IMG_ASSERT(psResPool != IMG_NULL); if(psResPool == IMG_NULL) { return IMG_ERROR_FATAL; } /* Lock the pool...*/ SYSOSKM_LockMutex(psResPool->hMutexHandle); /* Set resource id...*/ ui32Result = IDGEN_AllocId(psResPool->hIdGenHandle, (IMG_HANDLE)psCloneResource, &psCloneResource->ui32ResId); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_alloc_id; } /* If this is a clone, set the original...*/ if (psResource->bIsClone) { psOrigResource = psResource->psOrigResource; } IMG_ASSERT(psOrigResource->ui32RefCnt > 0); /* Setup the cloned resource...*/ psCloneResource->bIsClone = IMG_TRUE; psCloneResource->psResPool = psResPool; psCloneResource->psOrigResource = psOrigResource; /* Add to clone list...*/ LST_add(&psOrigResource->sCloneResList, psCloneResource); psOrigResource->ui32RefCnt++; /* If ppvParam is not IMG_NULL...*/ if (ppvParam !=IMG_NULL) { /* If the size of the original vParam is 0...*/ if (psOrigResource->ui32SizevParam == 0) { *ppvParam = IMG_NULL; } else { /* Allocate memory for a copy of the original vParam...*/ *ppvParam = IMG_MALLOC(psOrigResource->ui32SizevParam); IMG_ASSERT(*ppvParam != IMG_NULL); if (*ppvParam == IMG_NULL) { ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_copy_param; } IMG_MEMCPY(*ppvParam, psOrigResource->pvParam, psOrigResource->ui32SizevParam); } } /* Unlock the pool...*/ SYSOSKM_UnlockMutex(psResPool->hMutexHandle); /* Return the cloned resource...*/ *phClonePoolResHandle = psCloneResource; /* Return IMG_SUCCESS...*/ return IMG_SUCCESS; /* Error handling. */ error_copy_param: LST_remove(&psOrigResource->sCloneResList, psCloneResource); psOrigResource->ui32RefCnt--; error_alloc_id: IMG_FREE(psCloneResource); /* Unlock the pool...*/ SYSOSKM_UnlockMutex(psResPool->hMutexHandle); error_nolock: return ui32Result; }
/*! ****************************************************************************** @Function POOL_ResRegister ******************************************************************************/ IMG_RESULT POOL_ResRegister( IMG_HANDLE hPoolHandle, POOL_pfnDestructor pfnDestructor, IMG_VOID * pvParam, IMG_UINT32 ui32SizevParam, IMG_BOOL bAlloc, IMG_UINT32 * pui32ResId, IMG_HANDLE * phPoolResHandle ) { POOL_sResPool * psResPool = hPoolHandle; POOL_sResource * psResource; IMG_UINT32 ui32Result; IMG_ASSERT(gInitialised); IMG_ASSERT(psResPool != IMG_NULL); if (!gInitialised || psResPool == IMG_NULL) { ui32Result = IMG_ERROR_INVALID_PARAMETERS; goto error_nolock; } /* Allocate a resource structure...*/ psResource = IMG_MALLOC(sizeof(*psResource)); IMG_ASSERT(psResource != IMG_NULL); if (psResource == IMG_NULL) { return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psResource, 0, sizeof(*psResource)); /* Setup the resource...*/ psResource->pfnDestructor = pfnDestructor; psResource->pvParam = pvParam; psResource->ui32SizevParam = ui32SizevParam; psResource->psResPool = psResPool; LST_init(&psResource->sCloneResList); /* Lock the pool...*/ SYSOSKM_LockMutex(psResPool->hMutexHandle); /* Set resource id...*/ ui32Result = IDGEN_AllocId(psResPool->hIdGenHandle, (IMG_HANDLE)psResource, &psResource->ui32ResId); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { IMG_FREE(psResource); /* Unlock the pool...*/ SYSOSKM_UnlockMutex(psResPool->hMutexHandle); return ui32Result; } /* If allocated or free callback not set...*/ if ( (bAlloc) || (psResPool->pfnFree != IMG_NULL) ) { /* Add to active list...*/ LST_add(&psResPool->sActResList, psResource); psResource->ui32RefCnt++; } else { /* Add to free list...*/ LST_add(&psResPool->sFreeResList, psResource); } /* Return the resource id...*/ if (pui32ResId != IMG_NULL) { *pui32ResId = psResource->ui32ResId; } /* Return the handle to the resource...*/ if (phPoolResHandle != IMG_NULL) { *phPoolResHandle = psResource; } /* Unlock the pool...*/ SYSOSKM_UnlockMutex(psResPool->hMutexHandle); /* If free callback set...*/ if (psResPool->pfnFree != IMG_NULL) { /* Call the free callback...*/ psResPool->pfnFree(psResource->ui32ResId, psResource->pvParam); } /* Return IMG_SUCCESS...*/ return IMG_SUCCESS; error_nolock: return ui32Result; }
/*! ****************************************************************************** @Function RMAN_RegisterResource ******************************************************************************/ IMG_RESULT RMAN_RegisterResource( IMG_HANDLE hResBHandle, IMG_UINT32 ui32TypeId, RMAN_pfnFree pfnFree, IMG_VOID * pvParam, IMG_HANDLE * phResHandle, IMG_UINT32 * pui32ResId ) { RMAN_sBucket * psBucket = (RMAN_sBucket *) hResBHandle; RMAN_sResource * psResource; IMG_RESULT i32Result; IMG_ASSERT(gInitialised); IMG_ASSERT(ui32TypeId != RMAN_ALL_TYPES); IMG_ASSERT(hResBHandle != IMG_NULL); if (hResBHandle == IMG_NULL) { return IMG_ERROR_GENERIC_FAILURE; } /* Allocate a resource structure...*/ psResource = IMG_MALLOC(sizeof(*psResource)); IMG_ASSERT(psResource != IMG_NULL); if (psResource == IMG_NULL) { return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psResource, 0, sizeof(*psResource)); /* Fill in the resource structure...*/ psResource->psBucket = psBucket; psResource->ui32TypeId = ui32TypeId; psResource->pfnFree = pfnFree; psResource->pvParam = pvParam; /* Allocate resource Id...*/ SYSOSKM_LockMutex(globalMutext); i32Result = IDGEN_AllocId(psBucket->hIdGenerator, psResource, &psResource->ui32ResId); SYSOSKM_UnlockMutex(globalMutext); if(i32Result != IMG_SUCCESS) { IMG_ASSERT(!"failed to allocate RMAN id"); return i32Result; } IMG_ASSERT(psResource->ui32ResId <= RMAN_CRESID_MAX_RES_ID); // add this resource to the bucket SYSOSKM_DisableInt(); DQ_addTail(&psBucket->sResList, psResource); /* Update count of resources...*/ psBucket->ui32ResCnt++; SYSOSKM_EnableInt(); /* If resource handle required...*/ if (phResHandle != IMG_NULL) { *phResHandle = psResource; } /* If resource id required...*/ if (pui32ResId != IMG_NULL) { *pui32ResId = RMAN_GetResourceId(psResource); } /* Return success...*/ return IMG_SUCCESS; }
IMG_RESULT SYSMEMKM_AddDevIFMemory( SYSDEVU_sInfo *sysdev, IMG_UINTPTR vstart, IMG_PHYSADDR pstart, IMG_UINT32 size, SYS_eMemPool * peMemPool ) { IMG_RESULT ui32Result; struct priv_params *prv; IMG_ASSERT(size != 0); IMG_ASSERT((vstart & (HOST_MMU_PAGE_SIZE - 1)) == 0); if((0 == size) || (0 != (vstart & (HOST_MMU_PAGE_SIZE - 1)))) { return IMG_ERROR_INVALID_PARAMETERS; } prv = (struct priv_params *)IMG_MALLOC(sizeof(*prv)); IMG_ASSERT(IMG_NULL != prv); if (IMG_NULL == prv) { return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET((void *)prv, 0, sizeof(*prv)); IMG_ASSERT(size != 0); IMG_ASSERT((((IMG_UINTPTR)vstart) & (HOST_MMU_PAGE_SIZE-1)) == 0); // not allowed to use kmalloc for this size of buffer in the kernel. prv->npages = (size + (HOST_MMU_PAGE_SIZE-1)) / HOST_MMU_PAGE_SIZE; prv->alloc_pool = IMG_BIGALLOC(prv->npages); IMG_ASSERT(prv->alloc_pool != IMG_NULL); if(IMG_NULL == prv->alloc_pool) { ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_pool_alloc; } IMG_MEMSET(prv->alloc_pool, 0, prv->npages); prv->pstart = pstart; prv->size = size; prv->vstart = vstart; ui32Result = SYSMEMU_AddMemoryHeap(&devif_ops, sysdev, IMG_TRUE, (IMG_VOID *)prv, peMemPool); IMG_ASSERT(IMG_SUCCESS == ui32Result); if(IMG_SUCCESS != ui32Result) { goto error_heap_add; } return IMG_SUCCESS; /* Error handling. */ error_heap_add: IMG_BIGFREE(prv->alloc_pool); error_pool_alloc: IMG_FREE(prv); return ui32Result; }
static IMG_RESULT AllocPages( SYSMEM_Heap * heap, IMG_UINT32 ui32Size, SYSMEMU_sPages * psPages, SYS_eMemAttrib eMemAttrib ) { IMG_UINT32 ui32NoPages; IMG_UINT32 ui32ExamPages; IMG_UINT32 i; IMG_UINT64 ui64DeviceMemoryBase; IMG_PHYSADDR paCpuPhysAddr; IMG_UINT32 ui32Result; size_t physAddrArrSize; struct priv_params * prv = (struct priv_params *)heap->priv; /* If we don't know where the memory is...*/ SYSOSKM_DisableInt(); /* Calculate required no. of pages...*/ ui32NoPages = (ui32Size + (HOST_MMU_PAGE_SIZE-1)) / HOST_MMU_PAGE_SIZE; /* Loop over allocated pages until we find an unallocated slot big enough for this allocation...*/ ui32ExamPages = 0; while (ui32ExamPages < prv->npages) { /* If the current page is not allocated and we might have enough remaining to make this allocation...*/ if ( (!prv->alloc_pool[prv->cur_index]) && ((prv->cur_index + ui32NoPages) <= prv->npages) ) { /* Can we make this allocation...*/ for (i=0; i<ui32NoPages; i++) { if (prv->alloc_pool[prv->cur_index+i]) { break; } } if (i == ui32NoPages) { /* Yes, mark pages as allocated...*/ for (i=0; i<ui32NoPages; i++) { prv->alloc_pool[prv->cur_index+i] = IMG_TRUE; } /* Calculate the memory address of the start of the allocation...*/ //psPages->pvCpuKmAddr = (IMG_VOID *)((IMG_UINTPTR)prv->vstart + (prv->cur_index * HOST_MMU_PAGE_SIZE)); psPages->pvImplData = (IMG_VOID *)(prv->vstart + (prv->cur_index * HOST_MMU_PAGE_SIZE)); /* Update the current page index....*/ prv->cur_index += ui32NoPages; if (prv->cur_index >= prv->npages) { prv->cur_index = 0; } break; } } /* Update examined pages and page index...*/ ui32ExamPages++; prv->cur_index++; if (prv->cur_index >= prv->npages) { prv->cur_index = 0; } } SYSOSKM_EnableInt(); /* Check if allocation failed....*/ IMG_ASSERT(ui32ExamPages < prv->npages); if (ui32ExamPages >= prv->npages) { /* Failed...*/ /* dump some fragmentation information */ int i = 0; int nAllocated = 0; int n64kBlocks = 0; // number of blocks of <16 consecutive pages int n128kBlocks = 0; int n256kBlocks = 0; int nBigBlocks = 0; // number of blocks of >=64 consecutive pages int nMaxBlocks = 0; int nPages = 0; for(i = 0; i < (int)prv->npages; i++) { IMG_UINT8 isallocated = prv->alloc_pool[i]; nPages++; if(i == prv->npages-1 || isallocated != prv->alloc_pool[i+1]) { if(isallocated) nAllocated += nPages; else if(nPages < 16) n64kBlocks++; else if(nPages < 32) n128kBlocks++; else if(nPages < 64) n256kBlocks++; else nBigBlocks++; if(nMaxBlocks < nPages) nMaxBlocks = nPages; isallocated = prv->alloc_pool[i]; nPages = 0; } } #ifdef printk /* hopefully, this will give some idea of the fragmentation of the memory */ printk("AllocPages not able to allocate memory \n"); printk(" number available memory areas under 64k:%d\n", n64kBlocks); printk(" number available memory areas under 128k:%d\n", n128kBlocks); printk(" number available memory areas under 256k:%d\n", n256kBlocks); printk(" number available memory areas over 256k:%d\n", nBigBlocks); printk(" total allocated memory:%dk/%dk\n", nAllocated*4, prv->npages*4); #endif return IMG_ERROR_OUT_OF_MEMORY; } paCpuPhysAddr = CpuKmAddrToCpuPAddr(heap, psPages->pvImplData); IMG_ASSERT(paCpuPhysAddr != 0); if (paCpuPhysAddr == 0) { return IMG_ERROR_GENERIC_FAILURE; } #ifdef CONFIG_ARM /* This flushes the outer cache in ARM, so we avoid memory corruption by late flushes of memory previously marked as cached. */ if ((eMemAttrib & SYS_MEMATTRIB_CACHED) == 0) { mb(); /* the following two calls are somewhat expensive, but are there for defensive reasons */ flush_cache_all(); outer_flush_all(); } #endif { IMG_PHYSADDR * ppaCpuPhysAddrs; size_t numPages, pg_i, offset; // Memory for physical addresses numPages = (ui32Size + HOST_MMU_PAGE_SIZE - 1)/HOST_MMU_PAGE_SIZE; physAddrArrSize = sizeof(*ppaCpuPhysAddrs) * numPages; ppaCpuPhysAddrs = IMG_BIGORSMALL_ALLOC(physAddrArrSize); if (!ppaCpuPhysAddrs) { return IMG_ERROR_OUT_OF_MEMORY; } for (pg_i = 0, offset = 0; pg_i < numPages; offset += HOST_MMU_PAGE_SIZE, ++pg_i) { ppaCpuPhysAddrs[pg_i] = paCpuPhysAddr + offset; } // Set pointer to physical address in structure psPages->ppaPhysAddr = ppaCpuPhysAddrs; } /* Add this to the list of mappable regions...*/ ui32Result = SYSBRGU_CreateMappableRegion(paCpuPhysAddr, ui32Size, eMemAttrib, psPages, &psPages->hRegHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_mappable_region; } #if defined (CLEAR_PAGES) if (psPages->pvImplData) IMG_MEMSET( psPages->pvImplData, 0, ui32Size); #endif return IMG_SUCCESS; /* Error handling. */ error_mappable_region: IMG_BIGORSMALL_FREE(physAddrArrSize, psPages->ppaPhysAddr); psPages->ppaPhysAddr = IMG_NULL; return ui32Result; }
/* ****************************************************************************** @Function MTXIO_SendMTXMsg ******************************************************************************/ IMG_RESULT MTXIO_SendMTXMsg( const MTXIO_sContext * psContext, MSVDX_eCommsArea eArea, const IMG_VOID * psMsgHdr ) { IMG_UINT32 ui32BufferSize; IMG_UINT32 ui32WriteIdx; IMG_UINT32 * pui32Message = (IMG_UINT32*)psMsgHdr; IMG_UINT32 ui32MessageSize = (MEMIO_READ_FIELD(psMsgHdr, V2_PADMSG_SIZE) + 3) / 4; MTXIO_sCommsBuf sCommsBuf; IMG_UINT32 * pui32PaddingHeader = sCommsBuf.aui32ControlMsgHdr; IMG_UINT8 ui8PaddingID; IMG_UINT8 ui8PaddingSize; IMG_UINT8 ui32PaddingWords; #if !defined(SECURE_MEDIA_SUPPORT) && !defined(VXD_BRIDGING) IMG_CHAR szPdumpComment[100]; #endif #if !defined(SECURE_MEDIA_SUPPORT) && !defined(VXD_BRIDGING) snprintf(szPdumpComment, 99, "MTXIO_SendMTXMsg - Send message to FW area %s", eArea == MTXIO_AREA_CONTROL ? "CONTROL" : eArea == MTXIO_AREA_DECODE ? "DECODE" : eArea == MTXIO_AREA_COMPLETION ? "COMPLETION" : "UNKNOWN"); szPdumpComment[99] = 0; /* reproduce wait in a pdump script */ MSVDXIO_PDUMPComment(psContext->hMsvdxIoCtx, psContext->asComms[eArea].eMemSpace, szPdumpComment); #endif ui32BufferSize = mtxio_commsAreaGet(psContext, eArea, MTXIO_FIELD_SIZE); ui32WriteIdx = mtxio_commsAreaGet(psContext, eArea, MTXIO_FIELD_WRT_INDEX); if (psContext->asComms[eArea].ui32Size != ui32BufferSize) { REPORT(REPORT_MODULE_MTXIO, REPORT_ERR, "Comms area seems to be corrupted, wrong buffer size!"); return IMG_ERROR_GENERIC_FAILURE; } IMG_ASSERT(ui32MessageSize <= ui32BufferSize); IMG_ASSERT( MTXIO_AREA_CONTROL == eArea || MTXIO_AREA_DECODE == eArea ); IMG_MEMSET( pui32PaddingHeader, 0, sizeof(MTXIO_sCommsBuf) ); // prepare a padding message ui8PaddingID = VDECFW_MSGID_BASE_PADDING; if ( MTXIO_AREA_DECODE == eArea ) { ui8PaddingID = VDECFW_MSGID_PSR_PADDING; } // if there is not enough space in the buffer, send the padding message if ( (ui32WriteIdx + ui32MessageSize) > ui32BufferSize ) { ui32PaddingWords = ui32BufferSize - ui32WriteIdx; if ( ((ui32PaddingWords * 4) > 0xFF) || (ui32BufferSize < ui32WriteIdx)) { REPORT(REPORT_MODULE_MTXIO, REPORT_ERR, "Comms area seems to be corrupted, wrong write index!"); return IMG_ERROR_GENERIC_FAILURE; } ui8PaddingSize = (ui32PaddingWords * 4); MEMIO_WRITE_FIELD(pui32PaddingHeader, V2_PADMSG_SIZE, ui8PaddingSize); MEMIO_WRITE_FIELD(pui32PaddingHeader, V2_PADMSG_MID, ui8PaddingID); // wait until there is space to write the message into the message buffer mtxio_waitForCommsSpace( psContext, eArea, ui32WriteIdx, ui32PaddingWords, ui32BufferSize ); // write the message mtxio_commsWriteWords( psContext, eArea, (ui32WriteIdx<<2), ui32PaddingWords, pui32PaddingHeader ); // set the new write index IMG_ASSERT(ui32WriteIdx + ui32PaddingWords == ui32BufferSize); ui32WriteIdx = 0; mtxio_commsAreaSet( psContext, eArea, MTXIO_FIELD_WRT_INDEX, ui32WriteIdx ); } // wait until there is space to write the message into the message buffer mtxio_waitForCommsSpace( psContext, eArea, ui32WriteIdx, ui32MessageSize, ui32BufferSize ); // write the message mtxio_commsWriteWords( psContext, eArea, (ui32WriteIdx<<2), ui32MessageSize, pui32Message ); // calculate and set the new write index ui32WriteIdx += ui32MessageSize; if ( ui32WriteIdx >= ui32BufferSize ) { ui32WriteIdx = 0; } mtxio_commsAreaSet( psContext, eArea, MTXIO_FIELD_WRT_INDEX, ui32WriteIdx ); #if !defined(SECURE_MEDIA_SUPPORT) && !defined(VXD_BRIDGING) /* reproduce wait in a pdump script */ MSVDXIO_PDUMPComment(psContext->hMsvdxIoCtx, psContext->asComms[eArea].eMemSpace, "MTXIO_SendMTXMsg - Message to FW sent" ); #endif return IMG_SUCCESS; }
/* ****************************************************************************** @Function MTXIO_InitMTXComms ******************************************************************************/ IMG_RESULT MTXIO_InitMTXComms( const IMG_HANDLE hMsvdxIoCtx, MTXIO_sContext * psMtxIoCtx ) { IMG_UINT32 ui32Offset; IMG_UINT32 ui32VecRamVal = 0; IMG_UINT32 ui32Result; /* setup buffer pointers, sizes and handles */ VDECFW_sCommsControl * psControlArea = IMG_NULL; VDECFW_sCommsDecode * psDecodeArea = IMG_NULL; VDECFW_sCommsCompletion * psCompletionArea = IMG_NULL; IMG_MEMSET(psMtxIoCtx, 0, sizeof(*psMtxIoCtx)); psMtxIoCtx->hMsvdxIoCtx = hMsvdxIoCtx; /* Initially set all areas to general VLRFE_REGSPACE so the setup of VLR memory comes to FE Pdump Context */ psMtxIoCtx->asComms[MTXIO_AREA_CONTROL].eMemSpace = REGION_VLRFE_REGSPACE; psMtxIoCtx->asComms[MTXIO_AREA_DECODE].eMemSpace = REGION_VLRFE_REGSPACE; psMtxIoCtx->asComms[MTXIO_AREA_COMPLETION].eMemSpace = REGION_VLRFE_REGSPACE; /* Set field offsets */ psMtxIoCtx->asComms[MTXIO_AREA_CONTROL].ui32SizeOffset = (IMG_UINT32)((IMG_UINTPTR)&psControlArea->sHeader.ui32BufSize - (IMG_UINTPTR)&psControlArea->sHeader); psMtxIoCtx->asComms[MTXIO_AREA_CONTROL].ui32RdIndexOffset = (IMG_UINT32)((IMG_UINTPTR)&psControlArea->sHeader.ui32RdIndex - (IMG_UINTPTR)&psControlArea->sHeader); psMtxIoCtx->asComms[MTXIO_AREA_CONTROL].ui32WrtIndexOffset = (IMG_UINT32)((IMG_UINTPTR)&psControlArea->sHeader.ui32WrtIndex - (IMG_UINTPTR)&psControlArea->sHeader); psMtxIoCtx->asComms[MTXIO_AREA_CONTROL].ui32BufOffset = (IMG_UINT32)((IMG_UINTPTR)&psControlArea->sHeader.aui32Buf - (IMG_UINTPTR)&psControlArea->sHeader); psMtxIoCtx->asComms[MTXIO_AREA_DECODE].ui32SizeOffset = (IMG_UINT32)((IMG_UINTPTR)&psDecodeArea->sHeader.ui32BufSize - (IMG_UINTPTR)&psDecodeArea->sHeader); psMtxIoCtx->asComms[MTXIO_AREA_DECODE].ui32RdIndexOffset = (IMG_UINT32)((IMG_UINTPTR)&psDecodeArea->sHeader.ui32RdIndex - (IMG_UINTPTR)&psDecodeArea->sHeader); psMtxIoCtx->asComms[MTXIO_AREA_DECODE].ui32WrtIndexOffset = (IMG_UINT32)((IMG_UINTPTR)&psDecodeArea->sHeader.ui32WrtIndex - (IMG_UINTPTR)&psDecodeArea->sHeader); psMtxIoCtx->asComms[MTXIO_AREA_DECODE].ui32BufOffset = (IMG_UINT32)((IMG_UINTPTR)&psDecodeArea->sHeader.aui32Buf - (IMG_UINTPTR)&psDecodeArea->sHeader); psMtxIoCtx->asComms[MTXIO_AREA_COMPLETION].ui32SizeOffset = (IMG_UINT32)((IMG_UINTPTR)&psCompletionArea->sHeader.ui32BufSize - (IMG_UINTPTR)&psCompletionArea->sHeader); psMtxIoCtx->asComms[MTXIO_AREA_COMPLETION].ui32RdIndexOffset = (IMG_UINT32)((IMG_UINTPTR)&psCompletionArea->sHeader.ui32RdIndex - (IMG_UINTPTR)&psCompletionArea->sHeader); psMtxIoCtx->asComms[MTXIO_AREA_COMPLETION].ui32WrtIndexOffset = (IMG_UINT32)((IMG_UINTPTR)&psCompletionArea->sHeader.ui32WrtIndex - (IMG_UINTPTR)&psCompletionArea->sHeader); psMtxIoCtx->asComms[MTXIO_AREA_COMPLETION].ui32BufOffset = (IMG_UINT32)((IMG_UINTPTR)&psCompletionArea->sHeader.aui32Buf - (IMG_UINTPTR)&psCompletionArea->sHeader); /* set buffer sizes - in 32-bit words */ psMtxIoCtx->asComms[MTXIO_AREA_CONTROL].ui32Size = (VLR_CONTROL_COMMS_AREA_SIZE - psMtxIoCtx->asComms[MTXIO_AREA_CONTROL].ui32BufOffset) >> 2; psMtxIoCtx->asComms[MTXIO_AREA_DECODE].ui32Size = (VLR_DECODE_COMMS_AREA_SIZE - psMtxIoCtx->asComms[MTXIO_AREA_DECODE].ui32BufOffset) >> 2; psMtxIoCtx->asComms[MTXIO_AREA_COMPLETION].ui32Size = (VLR_COMPLETION_COMMS_AREA_SIZE - psMtxIoCtx->asComms[MTXIO_AREA_COMPLETION].ui32BufOffset) >> 2; /* clear VLR */ ui32VecRamVal = MTXIO_VEC_RAM_RESET_VAL; for (ui32Offset = 0; ui32Offset < VLR_SIZE; ui32Offset += 4) { ui32Result = MSVDXIO_VLRWriteWords(hMsvdxIoCtx, REGION_VLRFE_REGSPACE, ui32Offset, 1, &ui32VecRamVal); IMG_ASSERT(ui32Result == IMG_SUCCESS); } /* set up message buffers ready to use */ /* size is forced to a value derived from system.h in mtxio_initCommsInfo() */ mtxio_commsAreaSet(psMtxIoCtx, MTXIO_AREA_CONTROL, MTXIO_FIELD_SIZE, 0); mtxio_commsAreaSet(psMtxIoCtx, MTXIO_AREA_DECODE, MTXIO_FIELD_SIZE, 0); mtxio_commsAreaSet(psMtxIoCtx, MTXIO_AREA_COMPLETION, MTXIO_FIELD_SIZE, 0); /* After setup set each area to the right memspace so they come up to the right Pdump context */ psMtxIoCtx->asComms[MTXIO_AREA_COMPLETION].eMemSpace = REGION_VLRBE_REGSPACE; return IMG_SUCCESS; }
/* ****************************************************************************** @Function VXDIO_Initialise ******************************************************************************/ IMG_RESULT VXDIO_Initialise( IMG_BOOL bFakeMtx, IMG_BOOL bPost, IMG_BOOL bStackUsageTest, IMG_UINT32 ui32CoreNum, VXD_eDevType eDeviceType, IMG_HANDLE * phVxdCtx ) { IMG_RESULT ui32Result; VXDIO_sContext * psVxdCtx; #ifdef SECURE_TAL SECURE_sDev sDevInfo; #endif if (phVxdCtx == IMG_NULL) { REPORT(REPORT_MODULE_VXDIO, REPORT_ERR, "An video decoder device context handle must be provided (%d)", __LINE__); return IMG_ERROR_INVALID_PARAMETERS; } psVxdCtx = IMG_MALLOC(sizeof(*psVxdCtx)); IMG_ASSERT(psVxdCtx); if (psVxdCtx == IMG_NULL) { REPORT(REPORT_MODULE_VXDIO, REPORT_ERR, "Failed to allocate memory for VXDIO context"); return IMG_ERROR_OUT_OF_MEMORY; } IMG_MEMSET(psVxdCtx, 0, sizeof(*psVxdCtx)); *phVxdCtx = psVxdCtx; if (ui32NumOfCoresInit == 0) { #ifdef SECURE_TAL IMG_UINT32 i; for(i = 0; i < gsTargetConfig.ui32DevNum; i++) { sDevInfo.pszDeviceName = gsTargetConfig.pasDevices[i].pszDeviceName; ui32Result = SECDEV_Initialise(); if(ui32Result != IMG_SUCCESS) { goto error; } ui32Result = SECDEV_LocateDevice(&sDevInfo, SECDEV_MAPAREA_REGISTER); if (ui32Result != IMG_SUCCESS) { goto error; } gsTargetConfig.pasDevices[i].pvKmRegBase = sDevInfo.pvKmRegBase; gsTargetConfig.pasDevices[i].ui32RegSize = sDevInfo.ui32RegSize; } TARGET_Initialise(&gsTargetConfig); #else TARGET_Initialise(IMG_NULL); #endif } switch (eDeviceType) { case VXD_DEV_MSVDX: #ifdef POST_TEST #ifdef STACK_USAGE_TEST ui32Result = MSVDXIO_Initialise(bFakeMtx, bPost, bStackUsageTest, ui32CoreNum, (IMG_HANDLE)psVxdCtx, &psVxdCtx->hCoreCtx); #else /* POST required only */ ui32Result = MSVDXIO_Initialise(bFakeMtx, bPost, IMG_FALSE, ui32CoreNum, (IMG_HANDLE)psVxdCtx, &psVxdCtx->hCoreCtx); #endif #else #ifdef STACK_USAGE_TEST /* STACK USAGE TEST required only */ ui32Result = MSVDXIO_Initialise(bFakeMtx, IMG_FALSE, bStackUsageTest, ui32CoreNum, (IMG_HANDLE)psVxdCtx, &psVxdCtx->hCoreCtx); #else /* POST and STACK USAGE TEST not required */ ui32Result = MSVDXIO_Initialise(bFakeMtx, IMG_FALSE, IMG_FALSE, ui32CoreNum, (IMG_HANDLE)psVxdCtx, &psVxdCtx->hCoreCtx); #endif #endif break; #ifdef VDEC_USE_PVDEC case VXD_DEV_PVDEC: ui32Result = PVDECIO_Initialise(bFakeMtx, ui32CoreNum, (IMG_HANDLE)psVxdCtx, &psVxdCtx->hCoreCtx); break; #endif /* VDEC_USE_PVDEC */ default: REPORT(REPORT_MODULE_VXDIO, REPORT_ERR, "Wrong device type selected"); ui32Result = IMG_ERROR_INVALID_PARAMETERS; goto error; } return ui32Result; error: IMG_FREE(psVxdCtx); *phVxdCtx = IMG_NULL; return ui32Result; }
/*! ****************************************************************************** @Function PALLOC_Import1 ******************************************************************************/ IMG_RESULT PALLOC_Import1( IMG_UINT32 ui32AttachId, SYS_eMemAttrib eMemAttrib, int buff_fd, PALLOC_sUmAlloc __user * psUmAlloc ) { IMG_HANDLE hDevHandle; IMG_UINT32 ui32Result; PALLOC_sKmAlloc * psKmAlloc; IMG_HANDLE hAttachHandle; PALLOC_sAttachContext * psAttachContext; IMG_UINT32 ui32PageNo; IMG_UINT32 ui32PageIdx; IMG_UINT64 ui64CpuPAddr; PALLOC_sUmAlloc sUmAllocCp; IMG_UINT64 * paui64DevAddrs; SYSDEVU_sInfo * psSysDev; SYS_eMemPool eMemPool; IMG_PVOID pvCpuKmAddr; LOG_EVENT(PALLOC, PALLOC_IMPORT, LOG_FLAG_START | LOG_FLAG_QUAL_ARG1 | LOG_FLAG_QUAL_ARG2, ui32AttachId, buff_fd); DEBUG_REPORT(REPORT_MODULE_PALLOC, "PALLOC_Import1 fd %d", buff_fd); if (SYSOSKM_CopyFromUser(&sUmAllocCp, psUmAlloc, sizeof sUmAllocCp) != IMG_SUCCESS) { return IMG_ERROR_FATAL; } IMG_ASSERT(sUmAllocCp.bMappingOnly); /* Get the attachment handle from its ID... */ ui32Result = DMANKM_GetAttachHandleFromId(ui32AttachId, &hAttachHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } /* Get access to the attachment specific data...*/ psAttachContext = DMANKM_GetCompAttachmentData(hAttachHandle); /* Get access to the device handle...*/ hDevHandle = DMANKM_GetDevHandleFromAttach(hAttachHandle); /* Lock the device...*/ DMANKM_LockDeviceContext(hDevHandle); psSysDev = SYSDEVU_GetDeviceById(SYSDEVKM_GetDeviceID(psAttachContext->hSysDevHandle)); IMG_ASSERT(psSysDev != IMG_NULL); // I if (psSysDev == IMG_NULL) { ui32Result = IMG_ERROR_DEVICE_NOT_FOUND; goto error_get_dev_by_id; } eMemPool = (eMemAttrib & SYS_MEMATTRIB_SECURE) ? psSysDev->secureMemPool : psSysDev->sMemPool; /* Allocate allocation info...*/ psKmAlloc = IMG_MALLOC(sizeof *psKmAlloc); IMG_ASSERT(psKmAlloc != IMG_NULL); if (psKmAlloc == IMG_NULL) { ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_alloc_info; } IMG_MEMSET(psKmAlloc, 0, sizeof *psKmAlloc); /* Save device handle etc... */ psKmAlloc->hDevHandle = hDevHandle; psKmAlloc->sAllocInfo.ui32Size = sUmAllocCp.ui32Size; psKmAlloc->sAllocInfo.bIsContiguous = IMG_FALSE; /* Get the device id...*/ ui32Result = DMANKM_GetDeviceId(hDevHandle, &sUmAllocCp.ui32DeviceId); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_get_dev_id; } psKmAlloc->sAllocInfo.bMappingOnly = IMG_TRUE; /* Calculate the size of the allocation in pages */ ui32PageNo = (sUmAllocCp.ui32Size + SYS_MMU_PAGE_SIZE - 1)/SYS_MMU_PAGE_SIZE; psKmAlloc->sAllocInfo.psSysPAddr = IMG_BIGORSMALL_ALLOC(sizeof(IMG_SYS_PHYADDR) * ui32PageNo); IMG_ASSERT(psKmAlloc->sAllocInfo.psSysPAddr); if (IMG_NULL == psKmAlloc->sAllocInfo.psSysPAddr) { ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_page_array; } paui64DevAddrs = IMG_BIGORSMALL_ALLOC((sizeof *paui64DevAddrs) * ui32PageNo); IMG_ASSERT(paui64DevAddrs); if (IMG_NULL == paui64DevAddrs) { ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_addr_array; } if(buff_fd >= 0) { pvCpuKmAddr = NULL; /* ION buffer */ #if defined ANDROID_ION_BUFFERS psKmAlloc->eBufType = PALLOC_BUFTYPE_ANDROIDNATIVE; #if defined CONFIG_X86 ui32Result = palloc_GetIONPages(eMemPool, buff_fd, sUmAllocCp.ui32Size, psKmAlloc->sAllocInfo.psSysPAddr, &pvCpuKmAddr, &psKmAlloc->hBufHandle); #else // if CONFIG_X86 ui32Result = palloc_GetIONPages(eMemPool, buff_fd, sUmAllocCp.ui32Size, psKmAlloc->sAllocInfo.psSysPAddr, NULL, &psKmAlloc->hBufHandle); #endif // if CONFIG_X86 if (ui32Result != IMG_SUCCESS) { IMG_ASSERT(!"palloc_GetIONPages"); goto error_get_pages; } #else // if ANDROID_ION_BUFFERS IMG_ASSERT(!"NOT ANDROID: ION not supported"); goto error_get_pages; #endif // if ANDROID_ION_BUFFERS } else { /* User space allocated buffer */ IMG_VOID __user * pvUmBuff = ( IMG_VOID __user * ) sUmAllocCp.pvCpuUmAddr; IMG_ASSERT(pvUmBuff); psKmAlloc->hBufHandle = (IMG_HANDLE)(sUmAllocCp.pvCpuUmAddr); psKmAlloc->eBufType = PALLOC_BUFTYPE_USERALLOC; /* Assign and lock physical addresses to the user space buffer. The mapping of the first page in the kernel is also returned */ ui32Result = SYSOSKM_CpuUmAddrToCpuPAddrArray(pvUmBuff, psKmAlloc->sAllocInfo.psSysPAddr, ui32PageNo, &pvCpuKmAddr); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_get_pages; } } /* Import pages */ ui32Result = SYSMEMU_ImportExternalPages(eMemPool, sUmAllocCp.ui32Size, eMemAttrib, &psKmAlloc->hPagesHandle, pvCpuKmAddr, psKmAlloc->sAllocInfo.psSysPAddr); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_import_pages; } // Access from user space is not needed for the moment. Can be changed. sUmAllocCp.lOffset = 0; #if PALLOC_EXPOSE_KM_HANDLE sUmAllocCp.hKmAllocHandle = psKmAlloc->hPagesHandle; #endif /* PALLOC_EXPOSE_KM_HANDLE */ for (ui32PageIdx = 0; ui32PageIdx < ui32PageNo; ++ui32PageIdx) { ui64CpuPAddr = psKmAlloc->sAllocInfo.psSysPAddr[ui32PageIdx]; paui64DevAddrs[ui32PageIdx] = SYSDEVKM_CpuPAddrToDevPAddr(psAttachContext->hSysDevHandle, ui64CpuPAddr); } /* Register this with the resource manager */ ui32Result = RMAN_RegisterResource(psAttachContext->hResBHandle, PALLOC_RES_TYPE_1, palloc_fnFree, psKmAlloc, IMG_NULL, &sUmAllocCp.ui32AllocId); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_resource_register; } LOG_EVENT(PALLOC, PALLOC_IMPORTID, LOG_FLAG_END | LOG_FLAG_QUAL_ARG1 | LOG_FLAG_QUAL_ARG2, ui32AttachId, sUmAllocCp.ui32AllocId); /* Unlock the device...*/ DMANKM_UnlockDeviceContext(hDevHandle); /* Copy to user changed PALLOC_sUmAlloc, including physical device addresses */ if (SYSOSKM_CopyToUser(psUmAlloc, &sUmAllocCp, sizeof sUmAllocCp)) { ui32Result = IMG_ERROR_FATAL; goto error_copy_to_user; } if (SYSOSKM_CopyToUser(psUmAlloc->aui64DevPAddr, paui64DevAddrs, (sizeof *paui64DevAddrs) * ui32PageNo)) { ui32Result = IMG_ERROR_FATAL; goto error_copy_to_user; } /* Free the address array */ IMG_BIGORSMALL_FREE((sizeof *paui64DevAddrs) * ui32PageNo, paui64DevAddrs); LOG_EVENT(PALLOC, PALLOC_IMPORT, LOG_FLAG_END | LOG_FLAG_QUAL_ARG1 | LOG_FLAG_QUAL_ARG2, ui32AttachId, buff_fd); /* Return. */ return IMG_SUCCESS; /* Error handling. */ error_copy_to_user: /* Free everything. */ PALLOC_Free1(sUmAllocCp.ui32AllocId); goto error_return; error_resource_register: SYSMEMU_FreePages(psKmAlloc->hPagesHandle); error_import_pages: if (buff_fd >= 0) { #ifdef ANDROID_ION_BUFFERS palloc_ReleaseIONBuf(psKmAlloc->hBufHandle, NULL); #endif /* ANDROID_ION_BUFFERS */ } else { SYSOSKM_ReleaseCpuPAddrArray(pvCpuKmAddr, psKmAlloc->hBufHandle, psKmAlloc->sAllocInfo.psSysPAddr, ui32PageNo); } error_get_pages: IMG_BIGORSMALL_FREE((sizeof *paui64DevAddrs) * ui32PageNo, paui64DevAddrs); error_addr_array: IMG_BIGORSMALL_FREE(sizeof(IMG_SYS_PHYADDR) * ui32PageNo, psKmAlloc->sAllocInfo.psSysPAddr); error_page_array: error_get_dev_id: IMG_FREE(psKmAlloc); error_alloc_info: error_get_dev_by_id: /* Unlock the device. */ DMANKM_UnlockDeviceContext(hDevHandle); error_return: return ui32Result; }
/*! ****************************************************************************** @Function PALLOC_Alloc1 ******************************************************************************/ IMG_RESULT PALLOC_Alloc1( IMG_UINT32 ui32AttachId, SYS_eMemAttrib eMemAttrib, PALLOC_sUmAlloc __user * psUmAlloc ) { IMG_HANDLE hDevHandle; IMG_UINT32 ui32Result; PALLOC_sKmAlloc * psKmAlloc; IMG_HANDLE hAttachHandle; PALLOC_sAttachContext * psAttachContext; IMG_UINT32 ui32PageNo; PALLOC_sUmAlloc sUmAllocCp; IMG_UINT32 ui32PageIdx; IMG_UINT64 * pui64Phys; SYSMEMU_sPages * psSysMem; SYS_eMemPool eMemPool; SYSDEVU_sInfo * psSysDev; /* the following code assumes that IMG_SYS_PHYADDR and IMG_UINT64 are the same size */ #ifndef SYSBRG_BRIDGING IMG_VOID * pvKmAddr; #endif if (SYSOSKM_CopyFromUser(&sUmAllocCp, psUmAlloc, sizeof(sUmAllocCp)) != IMG_SUCCESS) { return IMG_ERROR_FATAL; } LOG_EVENT(PALLOC, PALLOC_ALLOC, (LOG_FLAG_START | LOG_FLAG_QUAL_ARG1 |LOG_FLAG_QUAL_ARG2), ui32AttachId, sUmAllocCp.ui32Size); IMG_ASSERT(!sUmAllocCp.bMappingOnly); /* Get the attachment handle from its ID...*/ ui32Result = DMANKM_GetAttachHandleFromId(ui32AttachId, &hAttachHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { return ui32Result; } /* Get access to the attachment specific data...*/ psAttachContext = DMANKM_GetCompAttachmentData(hAttachHandle); /* Get access to the device handle...*/ hDevHandle = DMANKM_GetDevHandleFromAttach(hAttachHandle); /* Lock the device...*/ DMANKM_LockDeviceContext(hDevHandle); psSysDev = SYSDEVU_GetDeviceById(SYSDEVKM_GetDeviceID(psAttachContext->hSysDevHandle)); IMG_ASSERT(psSysDev != IMG_NULL); // I if (psSysDev == IMG_NULL) { return IMG_ERROR_DEVICE_NOT_FOUND; } eMemPool = (eMemAttrib & SYS_MEMATTRIB_SECURE) ? psSysDev->secureMemPool : psSysDev->sMemPool; /* Allocate allocation info...*/ psKmAlloc = IMG_MALLOC(sizeof(*psKmAlloc)); IMG_ASSERT(psKmAlloc != IMG_NULL); if (psKmAlloc == IMG_NULL) { ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_alloc_info; } IMG_MEMSET(psKmAlloc, 0, sizeof(*psKmAlloc)); /* Save device handle etc...*/ psKmAlloc->hDevHandle = hDevHandle; psKmAlloc->sAllocInfo.ui32Size = sUmAllocCp.ui32Size; psKmAlloc->hBufHandle = NULL; psKmAlloc->eBufType = PALLOC_BUFTYPE_PALLOCATED; /* Allocate pages...*/ ui32Result = SYSMEMU_AllocatePages(sUmAllocCp.ui32Size, eMemAttrib, eMemPool, &psKmAlloc->hPagesHandle, &pui64Phys); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_alloc_pages; } #ifndef SYSBRG_BRIDGING SYSMEMU_GetCpuKmAddr(&pvKmAddr, psKmAlloc->hPagesHandle); IMG_ASSERT(pvKmAddr != IMG_NULL); if(pvKmAddr == IMG_NULL) { ui32Result = IMG_ERROR_FATAL; goto error_cpu_km_addr; } #endif /* Return addresses...*/ psSysMem = psKmAlloc->hPagesHandle; #ifdef PALLOC_EXPOSE_KM_HANDLE sUmAllocCp.hKmAllocHandle = psKmAlloc->hPagesHandle; #endif /* Check if contiguous...*/ psKmAlloc->sAllocInfo.bIsContiguous = SYSMEMKM_IsContiguous(psKmAlloc->hPagesHandle); /* Get the device id...*/ ui32Result = DMANKM_GetDeviceId(hDevHandle, &sUmAllocCp.ui32DeviceId); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_get_dev_id; } sUmAllocCp.lOffset = 0; if (psSysMem->hRegHandle) { // Determine the offset to memory if it has been made mappable in UM. sUmAllocCp.lOffset = (long)pui64Phys[0]; } /* Calculate the size of the allocation in pages...*/ ui32PageNo = (sUmAllocCp.ui32Size + SYS_MMU_PAGE_SIZE - 1)/SYS_MMU_PAGE_SIZE; psKmAlloc->sAllocInfo.psSysPAddr = IMG_BIGORSMALL_ALLOC(sizeof(IMG_SYS_PHYADDR) * ui32PageNo); IMG_ASSERT(psKmAlloc->sAllocInfo.psSysPAddr); if (IMG_NULL == psKmAlloc->sAllocInfo.psSysPAddr) { ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_page_array; } IMG_MEMSET(psKmAlloc->sAllocInfo.psSysPAddr, 0, sizeof(IMG_SYS_PHYADDR) * ui32PageNo); for (ui32PageIdx = 0; ui32PageIdx < ui32PageNo; ++ui32PageIdx) { psKmAlloc->sAllocInfo.psSysPAddr[ui32PageIdx] = pui64Phys[ui32PageIdx]; } /* Register this with the resource manager...*/ ui32Result = RMAN_RegisterResource(psAttachContext->hResBHandle, PALLOC_RES_TYPE_1, palloc_fnFree, psKmAlloc, IMG_NULL, &sUmAllocCp.ui32AllocId); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_resource_register; } LOG_EVENT(PALLOC, PALLOC_ALLOCID, (LOG_FLAG_END | LOG_FLAG_QUAL_ARG1 |LOG_FLAG_QUAL_ARG2), ui32AttachId, sUmAllocCp.ui32AllocId); /* Unlock the device...*/ DMANKM_UnlockDeviceContext(hDevHandle); /* Copy to user changed PALLOC_sUmAlloc, including physical device addresses */ if (SYSOSKM_CopyToUser(psUmAlloc, &sUmAllocCp, sizeof(sUmAllocCp))) { ui32Result = IMG_ERROR_FATAL; goto error_copy_to_user; } if (SYSOSKM_CopyToUser(psUmAlloc->aui64DevPAddr, psKmAlloc->sAllocInfo.psSysPAddr, sizeof(psKmAlloc->sAllocInfo.psSysPAddr[0]) * ui32PageNo)) { ui32Result = IMG_ERROR_FATAL; goto error_copy_to_user; } LOG_EVENT(PALLOC, PALLOC_ALLOC, (LOG_FLAG_END | LOG_FLAG_QUAL_ARG1 |LOG_FLAG_QUAL_ARG2), ui32AttachId, sUmAllocCp.ui32Size); /* Return. */ return IMG_SUCCESS; /* Error handling. */ error_copy_to_user: /* Free everything. */ PALLOC_Free1(sUmAllocCp.ui32AllocId); goto error_return; error_resource_register: IMG_BIGORSMALL_FREE(sizeof(IMG_SYS_PHYADDR) * ui32PageNo, psKmAlloc->sAllocInfo.psSysPAddr); error_page_array: error_get_dev_id: #ifndef SYSBRG_BRIDGING error_cpu_km_addr: #endif /* SYSBRG_BRIDGING */ SYSMEMU_FreePages(psKmAlloc->hPagesHandle); error_alloc_pages: IMG_FREE(psKmAlloc); error_alloc_info: /* Unlock the device. */ DMANKM_UnlockDeviceContext(hDevHandle); error_return: return ui32Result; }
/*! ****************************************************************************** @Function ADDR_CxInitialise ******************************************************************************/ PREF IMG_RESULT ADDR_CxInitialise( ADDR_sContext * const psContext ) { IMG_UINT32 ui32Result = IMG_ERROR_FATAL; IMG_ASSERT(IMG_NULL != psContext); if (IMG_NULL == psContext) { ui32Result = IMG_ERROR_INVALID_PARAMETERS; goto error; } //If we are not initialised if (!bInitalised) { //Initialise context IMG_MEMSET(psContext, 0x00, sizeof(*psContext)); addr_alloc_CreateLock(); addr_alloc_Lock(); //Initialise the hash functions.. ui32Result = VID_HASH_Initialise(); IMG_ASSERT(IMG_SUCCESS == ui32Result); if(IMG_SUCCESS != ui32Result) { addr_alloc_UnLock(); ui32Result = IMG_ERROR_UNEXPECTED_STATE; goto error; } //Initialise the arena functions ui32Result = VID_RA_Initialise(); if(IMG_SUCCESS != ui32Result) { addr_alloc_UnLock(); ui32Result = VID_HASH_Finalise(); IMG_ASSERT(IMG_SUCCESS == ui32Result); ui32Result = IMG_ERROR_UNEXPECTED_STATE; goto error; } #if !defined (IMG_KERNEL_MODULE) //Seed the random number generator srand(RANDOM_BLOCK_SEED); #endif //We are now initalised bInitalised = IMG_TRUE; ui32Result = IMG_SUCCESS; } else { addr_alloc_Lock(); } gui32NoContext++; addr_alloc_UnLock(); error: return ui32Result; }
/*! ****************************************************************************** @Function SYSMEMKM_AllocPages ******************************************************************************/ static IMG_RESULT AllocPages( SYSMEM_Heap * heap, IMG_UINT32 ui32Size, SYSMEMU_sPages * psPages, SYS_eMemAttrib eMemAttrib ) { struct priv_params * prv = (struct priv_params *)heap->priv; IMG_PHYSADDR paCpuPhysAddr, paOffset; IMG_RESULT ui32Result; IMG_PHYSADDR * ppaCpuPhysAddrs; size_t numPages, pg_i; size_t physAddrArrSize; /* Calculate required no. of pages...*/ psPages->pvImplData = (IMG_VOID *)gen_pool_alloc(prv->pool, ui32Size); if(psPages->pvImplData == IMG_NULL) { return IMG_ERROR_OUT_OF_MEMORY; } paCpuPhysAddr = CpuKmAddrToCpuPAddr(heap, psPages->pvImplData); IMG_ASSERT(paCpuPhysAddr != 0); if (paCpuPhysAddr == 0) { ui32Result = IMG_ERROR_GENERIC_FAILURE; goto error_map; } numPages = (ui32Size + HOST_MMU_PAGE_SIZE - 1)/HOST_MMU_PAGE_SIZE; physAddrArrSize = sizeof(*ppaCpuPhysAddrs) * numPages; ppaCpuPhysAddrs = IMG_BIGORSMALL_ALLOC(physAddrArrSize); if (!ppaCpuPhysAddrs) { ui32Result = IMG_ERROR_OUT_OF_MEMORY; goto error_array_alloc; } for (pg_i = 0, paOffset = 0; pg_i < numPages; paOffset += HOST_MMU_PAGE_SIZE, ++pg_i) { ppaCpuPhysAddrs[pg_i] = paCpuPhysAddr + paOffset; } psPages->ppaPhysAddr = ppaCpuPhysAddrs; /* Add this to the list of mappable regions...*/ ui32Result = SYSBRGU_CreateMappableRegion(psPages->ppaPhysAddr[0], ui32Size, eMemAttrib, IMG_FALSE, psPages, &psPages->hRegHandle); IMG_ASSERT(ui32Result == IMG_SUCCESS); if (ui32Result != IMG_SUCCESS) { goto error_region_create; } #if defined (CLEAR_PAGES) IMG_MEMSET( psPages->pvImplData, 0, ui32Size); #endif return IMG_SUCCESS; /* Error handling. */ error_region_create: IMG_BIGORSMALL_FREE(physAddrArrSize, psPages->ppaPhysAddr); error_array_alloc: error_map: gen_pool_free(prv->pool, (unsigned long)psPages->pvImplData, ui32Size); psPages->ppaPhysAddr = IMG_NULL; psPages->hRegHandle = IMG_NULL; return ui32Result; }