예제 #1
0
/*!
******************************************************************************

 @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;
    }

}
예제 #2
0
/*!
******************************************************************************

 @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;
}
예제 #4
0
/*!
******************************************************************************

 @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;
}
예제 #7
0
/*!
******************************************************************************

 @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;
}
예제 #12
0
/*!
******************************************************************************

 @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;
}
예제 #13
0
/*!
******************************************************************************

 @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;
}
예제 #14
0
/*!
******************************************************************************

 @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;
}
예제 #17
0
/*
******************************************************************************

 @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;
}
예제 #18
0
/*
******************************************************************************

 @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;
}
예제 #19
0
/*
******************************************************************************

 @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;
}
예제 #20
0
/*!
******************************************************************************

 @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;
}
예제 #21
0
/*!
******************************************************************************

 @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;
}
예제 #23
0
/*!
******************************************************************************

 @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;
}