⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pvrsrv.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	if(eError != PVRSRV_OK)
	{
		return(eError);
	}

	bFindByType = IMG_FALSE;
	if (eDeviceType != PVRSRV_DEVICE_TYPE_UNKNOWN)
	{
		bFindByType = IMG_TRUE;	
	}

	/*
	 * First have a look to see if we all ready have this device...
	 */
	psDevInfo = (PPVRSRV_DEV_INFO) 0;
	psThis    = psSysData->psDevInfoList;

	while (psThis)
	{	
		bFound = IMG_FALSE;
			
		if (bFindByType)
		{			
			if (psThis->sDevId.eDeviceType == eDeviceType)
			{
				bFound = IMG_TRUE;
			}
		}
		else
		{
			if (psThis->sDevId.ui32DeviceIndex == uiDevIndex)
			{
				bFound = IMG_TRUE;
			}
		}

		if (bFound)
		{
			psDevInfo	= psThis;
			psThis		= 0;
		}
		else
		{
			psThis = psThis->psNext;
		}
	}

	/*
	 *	Found it ? then return it..
	 */
	if(psDevInfo)
	{
		/*
		 *	Increment instance count first !
		 */
		psDevInfo->ui32NumConnected++;

		/*
		 *	Setup KM Ptr
		 */

		psDevData->psDevInfoKM = psDevInfo;

		/*
		   Fill in UM Ptr with KM Ptr.
		   This ptr must be overwritten by the IOCTL glue if a user/kernel divide exists
		 */
		psDevData->psDevInfoUM = psDevInfo;

		psDevData->hServices = IMG_NULL;

		psDevData->psResItem = ResManRegisterRes((PRESMAN_ITEM)IMG_NULL,
												 RESMAN_TYPE_ACQUIRE_DEVICE_DATA, 
												 psDevData->psDevInfoKM,
												 0, 
												 ReleaseDeviceDataCallBack, 
												 RESMAN_AUTOFREE_LEV5);

		return(PVRSRV_OK);
	}

	for(i=0; i < psSysData->ui32NumDevices; i++)
	{
		psDevID = &psSysData->asDevIdList[i];

		bFound = IMG_FALSE;

		if (bFindByType)
		{
			if (psDevID->eDeviceType == eDeviceType)
			{
				bFound = IMG_TRUE;
			}
		}
		else
		{
			if (psDevID->ui32DeviceIndex == uiDevIndex)
			{
				bFound = IMG_TRUE;
			}
		}

		if (bFound)
		{
			break;
		}
		else
		{
			psDevID = IMG_NULL;
		}
	}

	if(!psDevID)
	{
		return PVRSRV_ERROR_INVALID_PARAMS;
	}


	if(!psSysData->bBMInitialised && !psDevID->bIsMemoryMaster)
	{
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	eError = InitDeviceInfo(&psDevInfo, psDevID);

	if (eError != PVRSRV_OK)
	{
		return eError;
	}
	/*
	 *	Insert device info structure into linked list..
	 */
	psDevInfo->psNext = psSysData->psDevInfoList;
	psSysData->psDevInfoList  = psDevInfo;

	psDevData->psDevInfoKM = psDevInfo;

	/* initialise connection count */
	psDevInfo->ui32NumConnected  = 1;

	/* install ISR for the device */
	eError = SysInstallISR(psDevInfo);

	if (eError != PVRSRV_OK)
	{
		return eError;
	}

	/* initialise the device */
	if(psDevInfo->pfnInitDevice != IMG_NULL)
	{
		eError = psDevInfo->pfnInitDevice (psDevInfo);
		if (eError != PVRSRV_OK)
		{
			return eError;
		}
	}

	if(!psSysData->bBMInitialised)
	{
        /* Initialise the memory manager */
        if(BM_Initialise ( 	psDevInfo->sDevLocation.pvRegsBaseKM,
        					psDevInfo->sDevLocation.sDeviceSpecific.sMBX.s2DSlavePort.pvData,
        					psDevInfo->sDevId.ui32CoreConfig) != IMG_TRUE)
        {          
            return PVRSRV_ERROR_INIT_FAILURE;
        }
		psSysData->bBMInitialised = IMG_TRUE;
	}


	/*
	 * Fill in user mode ptr.
	 * This ptr must be overwritten by the IOCTL glue if a user/kernel divide exists
	 */

	psDevData->psDevInfoUM = psDevInfo;

	/* Require resource manager track resource */
	psDevData->psResItem = ResManRegisterRes((PRESMAN_ITEM)IMG_NULL,
			                                  RESMAN_TYPE_ACQUIRE_DEVICE_DATA, 
											  psDevData->psDevInfoKM,
											  0, 
											  ReleaseDeviceDataCallBack, 
											  RESMAN_AUTOFREE_LEV5);

	return(PVRSRV_OK);
}

/*!
******************************************************************************

 @Function	ReleaseDeviceDataCallBack
 
 @Description 
 
 This function is used to release device data it can either be called via the 
 resource manager or directly for PVRSRVReleaseDeviceData

 @Input    psDevData : 

 @Return   PVRSRV_ERROR IMG_CALLCONV  : 

******************************************************************************/

static PVRSRV_ERROR ReleaseDeviceDataCallBack(IMG_UINT32 ui32ProcessID, 
											  IMG_PVOID pvParam, 
											  IMG_UINT32 ui32Param)
{
	PPVRSRV_DEV_INFO psDevInfo = (PPVRSRV_DEV_INFO) pvParam;

	PPVRSRV_DEV_INFO	psThis,	psPrev;
	SYS_DATA			*psSysData;
	PVRSRV_ERROR		eError = PVRSRV_OK;
	IMG_BOOL bDoMemorySlavesExist = IMG_FALSE;

	PVR_ASSERT(pvParam != IMG_NULL);

	eError = SysAcquireData(&psSysData);

	if (eError != PVRSRV_OK)
	{
		return eError;
	}
	
	psThis    = psSysData->psDevInfoList;

	while (psThis)
	{
		if(!psThis->sDevId.bIsMemoryMaster)
		{
			bDoMemorySlavesExist = IMG_TRUE;
		}

		psThis = psThis->psNext;
	}

	
	psDevInfo->ui32NumConnected--;

	/* Time to go away ? */
	if (psDevInfo->ui32NumConnected == 0)
	{
		if(psDevInfo->sDevId.bIsMemoryMaster && bDoMemorySlavesExist)
		{
			PVR_DPF((PVR_DBG_ERROR,"Cannot release master device until slave devices have gone"));
			return PVRSRV_ERROR_INIT_FAILURE;
		}
	
		if(psSysData->psDevInfoList->psNext == IMG_NULL)
		{
			/* close down the buffer manager, eventually this call should
			take a device handle */
		    BM_Finalise ();
			psSysData->bBMInitialised = IMG_FALSE;
		}

		/* uninstall ISR for the device */
		eError = SysUnInstallISR(psDevInfo);

		if (eError != PVRSRV_OK)
		{
			return eError;
		}

		/* 
			de-init device 
		*/
		if(psDevInfo->pfnDeInitDevice != IMG_NULL)
		{
			eError = psDevInfo->pfnDeInitDevice (psDevInfo);
			if (eError != PVRSRV_OK)
			{
				return eError;
			}
		}

		/*
			Find list entry...
		*/
		psThis = psSysData->psDevInfoList;
		psPrev = 0;

		while (psThis)
		{
			if (psThis == psDevInfo)
			{
				/*
					Found it, so remove it...
				*/
				if (psPrev)
				{
					psPrev->psNext = psThis->psNext;
				}
				else
				{
					/* update head of the list */
					psSysData->psDevInfoList = psThis->psNext;
				}

				psThis = 0;
			}
			else
			{
				psPrev = psThis;
				psThis = psThis->psNext;
			}
		}

		/* free up heap allocations */
		eError = DeInitDeviceInfo(psDevInfo);
		if (eError != PVRSRV_OK)
		{
			return eError;
		}
	}

	return(eError);
}

/*!
******************************************************************************

 @Function	PVRSRVReleaseDeviceData
 
 @Description 
 
 This decrements the reference count to the device info structure and when the 
 reference count reaches zero causes the device to be de-initialised
 
 @Input    psDevData : 

 @Return   PVRSRV_ERROR  : 

******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVReleaseDeviceData (PPVRSRV_DEV_DATA psDevData)
{
	PVRSRV_ERROR eRtn;

	if (psDevData == IMG_NULL)
	{
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	if(psDevData->psResItem)
	{
		eRtn = ResManFreeResByPtr(psDevData->psResItem);
	}
	else
	{	
		/* Resource not managed call the free callback directly */
		eRtn = ReleaseDeviceDataCallBack(0,(IMG_PVOID) psDevData->psDevInfoKM, 0);
	}

	return(eRtn);
}

/*!
******************************************************************************

 @Function	PVRSRVAllocDeviceMem
 
 @Description 
 
 Allocates device memory
 
 @Input	   psDevData : DevData for the device this memory will primarily be used with

 @Input	   ui32Flags : Some combination of PVRSRV_MEMFLG_ flags

 @Input	   ui32Size :  Number of bytes to allocate

 @Input	   ui32Alignment : 

 @Output   **ppsMemInfo : On success, receives a pointer to the created MEM_INFO structure

 @Return   PVRSRV_ERROR : 

******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVAllocDeviceMem (PVRSRV_DEV_DATA	*psDevData,
										 IMG_UINT32			 ui32Flags,
										 IMG_UINT32			 ui32Size,
										 IMG_UINT32			 ui32Alignment,
										 PVRSRV_MEM_INFO **ppsMemInfo)
{

 	PVRSRV_MEM_INFO*   psMemInfo = (PVRSRV_MEM_INFO*)IMG_NULL;
	PVRSRV_DEV_DATA	 *psNewDevData;
	BM_HANDLE hBuffer;
	/* Pointer to implementation details within the mem_info */
	PVRSRV_MEMBLK *psMemBlock;

	IMG_UINT32	ui3BM2Flags;
	IMG_BOOL bBMError;

	PPVRSRV_DEV_INFO psDevInfo;

	if ((psDevData == IMG_NULL) || (ppsMemInfo == IMG_NULL))
	{
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psDevInfo = psDevData->psDevInfoKM;

	/* Start with an invalid pointer for the output value */
	*ppsMemInfo = IMG_NULL;

	if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP, 
					 sizeof(PVRSRV_MEM_INFO ), 
					 (IMG_VOID **)&psMemInfo, 0) != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocDeviceMem : Failed to alloc memory for block"));
		return (PVRSRV_ERROR_OUT_OF_MEMORY);
	}

	if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP, 
					 sizeof(IMG_UINT32), 
					 (IMG_VOID **)&psMemInfo->pui32Flags, 0) != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocDeviceMem : Failed to alloc memory for flag word"));
		HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psMemInfo);
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	psMemBlock = &(psMemInfo->sMemBlk);

	/* Translate to BM flags....*/
	ui3BM2Flags	= ((ui32Flags&PVRSRV_MEMFLG_CONTIGIOUS) ? BP_CONTIGUOUS : 0 );
 
	/* If requesting memory from alternate heap, request memory from secondary pool */
	if(ui32Flags & PVRSRV_MEMFLG_ALTERNATE_HEAP)
	{
		ui3BM2Flags |= 1;
	}

	bBMError = BM_Alloc (ui32Size, 
                         ui3BM2Flags,
                         ui32Alignment,
                         &hBuffer);

	if (!bBMError)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapDeviceMem : BM_Alloc Failed"));
		HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psMemInfo->pui32Flags);
		HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psMemInfo);
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	/* Fill in "Implementation dependant" section of mem info */
	psMemBlock->sSysPhysAddr = BM_HandleToSysPaddr(hBuffer);
	psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);

	/* Convert from BM_HANDLE to external IMG_HANDLE */
	psMemBlock->hBuffer = (IMG_HANDLE)hBuffer.h;

	/* Fill in the public fields of the MEM_INFO structure */

	psMemInfo->pvLinAddr = BM_HandleToCpuVaddr(hBuffer);

	psMemInfo->uiDevAddr = psMemBlock->sDevVirtAddr;

	// Set to a known value to start with.
	HostMemSet((void *)psMemInfo->pvLinAddr, 0x00, ui32Size);

	*psMemInfo->pui32Flags = ui32Flags;

	/* set the fact that the memory is valid */
	*psMemInfo->pui32Flags &= ~PVRSRV_MEMFLG_MEMORY_NOT_AVAILABLE;

	psMemInfo->ui32AllocSize = ui32Size;
	
	psMemInfo->psSyncInfo = AllocSyncInfo(psDevInfo);

	/* Clear the Backup buffer pointer as we do not have one at this point. We only allocate this as we are going up/down */
	psMemInfo->pvSysBackupBuffer = IMG_NULL;

	psMemInfo->psMemInfoKM = psMemInfo;

	/*
	 * Setup the output.
	 */
	*ppsMemInfo = psMemInfo;


	/* Register Resource */
	if(ui32Flags & PVRSRV_MEMFLG_NO_RESMAN)
	{
		psMemInfo->sMemBlk.psResItem = IMG_NULL;
	}
	else
	{
		if(ui32Flags & PVRSRV_MEMFLG_FLIPPABLE)
		{
			IMG_UINT32 i, ui32NumDevices;
			PVRSRV_DEVICE_IDENTIFIER asDeviceID[PVRSRV_MAX_DEVICES];

			HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP,sizeof(PVRSRV_DEV_DATA), (IMG_VOID **)&psNewDevData, 0);
			
			/* FIXME: this really is ugly and might not work on a system with more than one display device */			
			PVRSRVEnumerateDevices(psDevData->hServices, &ui32NumDevices, asDeviceID);

			for(i=0; i < ui32NumDevices; i++)
			{
				if(asDeviceID[i].eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY)
				{
					PVRSRVAcquireDeviceData(	psDevData->hServices, 
												asDeviceID[i].ui32DeviceIndex, 
												psNewDevData,
												PVRSRV_DEVICE_TYPE_UNKNOWN);
					break;
				}
			}

			psMemInfo->sMemBlk.psResItem = ResManRegisterRes((PRESMAN_ITEM)IMG_NULL, 
				                                             RESMAN_TYPE_FRAMBUFMEM, 
															 psMemInfo,
															 (IMG_UINT32)psNewDevData, 
															 FreeDeviceMemCallBack, 
															 RESMAN_AUTOFREE_LEV4);
		}
		else
		{
			psMemInfo->sMemBlk.psResItem = ResManRegisterRes((PRESMAN_ITEM)IMG_NULL, 
				                                             RESMAN_TYPE_FRAMBUFMEM, 
															 psMemInfo,
															 0, 
															 FreeDeviceMemCallBack, 
															 RESMAN_AUTOFREE_LEV4);
		}
	}

	/*
	 * And I think we're done for now....
	 */
	return (PVRSRV_OK);
}


/*!
******************************************************************************

 @Function	PVRSRVWrapDeviceMem

 @Description

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -