Example #1
0
IMG_HANDLE
BM_CreateContext(PVRSRV_DEVICE_NODE			*psDeviceNode,
				 IMG_DEV_PHYADDR			*psPDDevPAddr,
				 PVRSRV_PER_PROCESS_DATA	*psPerProc,
				 IMG_BOOL					*pbCreated)
{
	BM_CONTEXT			*pBMContext;
	DEVICE_MEMORY_INFO	*psDevMemoryInfo;
	IMG_BOOL			bKernelContext;
	PRESMAN_CONTEXT		hResManContext;

	PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateContext"));

	if (psPerProc == IMG_NULL)
	{
		bKernelContext = IMG_TRUE;
		hResManContext = psDeviceNode->hResManContext;
	}
	else
	{
		bKernelContext = IMG_FALSE;
		hResManContext = psPerProc->hResManContext;
	}

	if (pbCreated != IMG_NULL)
	{
		*pbCreated = IMG_FALSE;
	}

	
	psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;

	if (bKernelContext == IMG_FALSE)
	{
		IMG_HANDLE res = (IMG_HANDLE) List_BM_CONTEXT_Any_va(psDevMemoryInfo->pBMContext,
															&BM_CreateContext_IncRefCount_AnyVaCb,
															hResManContext);
		if (res)
		{
			return res;
		}
	}

	
	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
					 sizeof (struct _BM_CONTEXT_),
					 (IMG_PVOID *)&pBMContext, IMG_NULL,
					 "Buffer Manager Context") != PVRSRV_OK)
	{
		PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: Alloc failed"));
		return IMG_NULL;
	}
	OSMemSet(pBMContext, 0, sizeof (BM_CONTEXT));

	
	pBMContext->psDeviceNode = psDeviceNode;

	
	
	pBMContext->pBufferHash = HASH_Create(32);
	if (pBMContext->pBufferHash==IMG_NULL)
	{
		PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: HASH_Create failed"));
		goto cleanup;
	}

	if(psDeviceNode->pfnMMUInitialise(psDeviceNode,
										&pBMContext->psMMUContext,
										psPDDevPAddr) != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: MMUInitialise failed"));
		goto cleanup;
	}

	if(bKernelContext)
	{
		
		PVR_ASSERT(psDevMemoryInfo->pBMKernelContext == IMG_NULL);
		psDevMemoryInfo->pBMKernelContext = pBMContext;
	}
	else
	{
		




		PVR_ASSERT(psDevMemoryInfo->pBMKernelContext);

		if (psDevMemoryInfo->pBMKernelContext == IMG_NULL)
		{
			PVR_DPF((PVR_DBG_ERROR, "BM_CreateContext: psDevMemoryInfo->pBMKernelContext invalid"));
			goto cleanup;
		}

		PVR_ASSERT(psDevMemoryInfo->pBMKernelContext->psBMHeap);

		



		pBMContext->psBMSharedHeap = psDevMemoryInfo->pBMKernelContext->psBMHeap;

		


		List_BM_HEAP_ForEach_va(pBMContext->psBMSharedHeap,
								&BM_CreateContext_InsertHeap_ForEachVaCb,
								psDeviceNode,
								pBMContext);

		
		List_BM_CONTEXT_Insert(&psDevMemoryInfo->pBMContext, pBMContext);
	}

	
	pBMContext->ui32RefCount++;

	
	pBMContext->hResItem = ResManRegisterRes(hResManContext,
											RESMAN_TYPE_DEVICEMEM_CONTEXT,
											pBMContext,
											0,
											&BM_DestroyContextCallBack);
	if (pBMContext->hResItem == IMG_NULL)
	{
		PVR_DPF ((PVR_DBG_ERROR, "BM_CreateContext: ResManRegisterRes failed"));
		goto cleanup;
	}

	if (pbCreated != IMG_NULL)
	{
		*pbCreated = IMG_TRUE;
	}
	return (IMG_HANDLE)pBMContext;

cleanup:
	(IMG_VOID)BM_DestroyContextCallBack(pBMContext, 0);

	return IMG_NULL;
}
void *BM_CreateContext(struct PVRSRV_DEVICE_NODE *psDeviceNode,
		 struct IMG_DEV_PHYADDR *psPDDevPAddr,
		 struct PVRSRV_PER_PROCESS_DATA *psPerProc, IMG_BOOL *pbCreated)
{
	struct BM_CONTEXT *pBMContext;
	struct BM_HEAP *psBMHeap;
	struct DEVICE_MEMORY_INFO *psDevMemoryInfo;
	IMG_BOOL bKernelContext;
	struct RESMAN_CONTEXT *hResManContext;

	PVR_DPF(PVR_DBG_MESSAGE, "BM_CreateContext");

	if (psPerProc == NULL) {
		bKernelContext = IMG_TRUE;
		hResManContext = psDeviceNode->hResManContext;
	} else {
		bKernelContext = IMG_FALSE;
		hResManContext = psPerProc->hResManContext;
	}

	if (pbCreated != NULL)
		*pbCreated = IMG_FALSE;

	psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo;

	if (bKernelContext == IMG_FALSE)
		for (pBMContext = psDevMemoryInfo->pBMContext;
		     pBMContext != NULL; pBMContext = pBMContext->psNext)
			if (ResManFindResourceByPtr(hResManContext,
						     pBMContext->hResItem) ==
			    PVRSRV_OK) {
				pBMContext->ui32RefCount++;
				return (void *)pBMContext;
			}
	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_CONTEXT),
		       (void **)&pBMContext, NULL) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "BM_CreateContext: Alloc failed");
		return NULL;
	}
	OSMemSet(pBMContext, 0, sizeof(struct BM_CONTEXT));

	pBMContext->psDeviceNode = psDeviceNode;

	pBMContext->pBufferHash = HASH_Create(32);
	if (pBMContext->pBufferHash == NULL) {
		PVR_DPF(PVR_DBG_ERROR,
			 "BM_CreateContext: HASH_Create failed");
		goto cleanup;
	}

	if (psDeviceNode->pfnMMUInitialise(psDeviceNode,
					   &pBMContext->psMMUContext,
					   psPDDevPAddr) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR,
			 "BM_CreateContext: MMUInitialise failed");
		goto cleanup;
	}

	if (bKernelContext) {
		PVR_ASSERT(psDevMemoryInfo->pBMKernelContext == NULL);
		psDevMemoryInfo->pBMKernelContext = pBMContext;
	} else {

		PVR_ASSERT(psDevMemoryInfo->pBMKernelContext);

		if (psDevMemoryInfo->pBMKernelContext == NULL) {
			PVR_DPF(PVR_DBG_ERROR, "BM_CreateContext: "
				"psDevMemoryInfo->pBMKernelContext invalid");
			goto cleanup;
		}

		PVR_ASSERT(psDevMemoryInfo->pBMKernelContext->psBMHeap);

		pBMContext->psBMSharedHeap =
		    psDevMemoryInfo->pBMKernelContext->psBMHeap;

		psBMHeap = pBMContext->psBMSharedHeap;
		while (psBMHeap) {
			switch (psBMHeap->sDevArena.DevMemHeapType) {
			case DEVICE_MEMORY_HEAP_SHARED:
			case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
				{
					psDeviceNode->
					    pfnMMUInsertHeap(pBMContext->
								 psMMUContext,
							     psBMHeap->
								 pMMUHeap);
					break;
				}
			}
			psBMHeap = psBMHeap->psNext;
		}
		pBMContext->psNext = psDevMemoryInfo->pBMContext;
		psDevMemoryInfo->pBMContext = pBMContext;
	}
	pBMContext->ui32RefCount++;
	pBMContext->hResItem = ResManRegisterRes(hResManContext,
						 RESMAN_TYPE_DEVICEMEM_CONTEXT,
						 pBMContext,
						 0, BM_DestroyContextCallBack);
	if (pBMContext->hResItem == NULL) {
		PVR_DPF(PVR_DBG_ERROR,
			 "BM_CreateContext: ResManRegisterRes failed");
		goto cleanup;
	}

	if (pbCreated != NULL)
		*pbCreated = IMG_TRUE;
	return (void *)pBMContext;

cleanup:
	BM_DestroyContextCallBack(pBMContext, 0);

	return NULL;
}