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

📄 queue.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*!****************************************************************************
@File			services/common/queue.c

@Title			Kernel side command queue functions

@Author			Imagination Technologies

@date   		02/09/2003
 
@Copyright     	Copyright 2003-2004 by Imagination Technologies Limited.
                All rights reserved. No part of this software, either
                material or conceptual may be copied or distributed,
                transmitted, transcribed, stored in a retrieval system
                or translated into any human or computer language in any
                form by any means, electronic, mechanical, manual or
                other-wise, or disclosed to third parties without the
                express written permission of Imagination Technologies
                Limited, Unit 8, HomePark Industrial Estate,
                King's Langley, Hertfordshire, WD4 8LZ, U.K.

@Platform		generic

@Description	Kernel side command queue functions

@DoxygenVer		

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

/******************************************************************************
Modifications :-

$Log: queue.c $
*****************************************************************************/

#ifndef QUEUE_C
#define QUEUE_C

#include "services_headers.h"

#if defined(__linux__) && defined(__KERNEL__) 
#include "proc.h"

/*****************************************************************************
  Return the name of a command as a string
*/
static const char *					
CommandName (IMG_UINT32 ui32CommandID)
{
	switch (ui32CommandID)
	{
	case PVRSRV_CMD_ID_BLT:  	return "blt";  	 	break; 
	case PVRSRV_CMD_ID_FLIP:  	return "flip";  	break; 
	case PVRSRV_CMD_ID_RENDER:  return "render";  	break; 
	case PVRSRV_CMD_ID_LOCK:  	return "lock";  	break; 
	case PVRSRV_CMD_ID_UPDATE: 	return "update";  	break; 
	default:					return "unknown";  	break;
	}
} /*CommandName*/

/*****************************************************************************
 FUNCTION	:	QueuePrintCommands
    
 PURPOSE	:	Walks a command queue and prints each command into the supplied
				buffer 

 PARAMETERS	:	psQueue - the queue
				buf - buffer to print into
				size - total size of buffer
				off - the offset into the buffer to start at
*****************************************************************************/
static int
QueuePrintCommands (PVRSRV_QUEUE_INFO * psQueue, char * buffer, size_t size)
{
   off_t off = 0;
   IMG_UINT32 ui32ReadOffset  = psQueue->ui32ReadOffset;
   IMG_UINT32 ui32WriteOffset = psQueue->ui32WriteOffset;
   PVRSRV_CMD_HEADER * psCmdHeader;

   off = printAppend (buffer, size, off, "  queue at %p\n   ", psQueue);
   while (ui32ReadOffset != ui32WriteOffset)
   {
	   psCmdHeader = (PVRSRV_CMD_HEADER *)
		   ((IMG_UINT32)psQueue->pvLinQueueKM + ui32ReadOffset);

	   off = printAppend (buffer, size, off, "%s ",
						  CommandName (psCmdHeader->ui32CommandID));
	   
	   /* taken from UPDATE_QUEUE_ROFF in queue.h */
	   ui32ReadOffset += psCmdHeader->ui32Size;
	   ui32ReadOffset &= psQueue->ui32QueueSize - 1;
   }
   return printAppend (buffer, size, off, " <end>\n");
   
} /*QueuePrintCommands*/


/*****************************************************************************
 FUNCTION	:	QueuePrintQueues
    
 PURPOSE	:	Print the commands in each existing command queue

 PARAMETERS	:	buf - buffer to print into
				size - total size of buffer
				off - the offset into the buffer to start at
*****************************************************************************/
off_t
QueuePrintQueues (char * buffer, size_t size, off_t off)
{
	off_t n;
	SYS_DATA * psSysData;
	PVRSRV_QUEUE_INFO * psQueue;
	
	if (SysAcquireData(&psSysData) != PVRSRV_OK)
		return END_OF_FILE;

    if (!off)
        return printAppend (buffer, size, 0, "Command Queues\n");
    
	/* Find the allocation according to the index.  We do want the first entry
     * and, as 'off' is non-zero here, we must use off-1 */ 
	for (n=0, psQueue = psSysData->psQueueList; psQueue && n<off-1; n++)
		psQueue = psQueue->psNextKM;
	
	return psQueue ? QueuePrintCommands (psQueue, buffer, size) : END_OF_FILE;
    
} /*QueuePrintQueues*/

#endif // __linux__ && __KERNEL__ 

/***************************************************************************** 
	Kernel-side functions of User->Kernel transitions
******************************************************************************/

IMG_UINT32 NearestPower2(IMG_UINT32 ui32Value)
{
	IMG_UINT32 ui32Temp, ui32Result = 1;

	if(!ui32Value)
		return 0;

	ui32Temp = ui32Value - 1;
	while(ui32Temp)
	{
		ui32Result <<= 1;
		ui32Temp >>= 1;
	}

	return ui32Result;
}

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

 @Function	PVRSRVDestroyCommandQueueCallback
 
 @Description 
 
 Destroys a command queue
 
 @Input	   ui32ProcessID : process id
 
 @Input	   pvParam - data packet
 
 @Input	   ui32Param - packet size

 @Return   PVRSRV_ERROR : 

******************************************************************************/
static PVRSRV_ERROR IMG_CALLCONV DestroyCommandQueueCallBack(IMG_UINT32 ui32ProcessID, IMG_PVOID pvParam, IMG_UINT32 ui32Param)
{
	PVRSRV_QUEUE_INFO	*psQueueInfo = (PVRSRV_QUEUE_INFO *)pvParam;
	PVRSRV_QUEUE_INFO	*psQueue;
	SYS_DATA			*psSysData;
	PVRSRV_ERROR		eError;
	IMG_UINT32			i;
	
	eError = SysAcquireData(&psSysData);
	if (eError != PVRSRV_OK)
	{
		return eError;
	}

	psQueue = psSysData->psQueueList;

	for(i=0; i<WAIT_TRY_COUNT; i++)
	{
		if(psQueueInfo->ui32ReadOffset == psQueueInfo->ui32WriteOffset)
		{	
			break;
		}
		SysKickCmdProc (psSysData->pui32KickerAddr);
		HostWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
		//FIXME: not required in kernel? HostReleaseThreadQuanta();
	}

	if(i==WAIT_TRY_COUNT)
	{
		PVR_DPF((PVR_DBG_ERROR,"DestroyCommandQueueCallBack : Failed to empty queue"));
		return PVRSRV_ERROR_GENERIC;
	}

	/* Ensure we don't corrupt queue list, by blocking access */
	eError = HostLockResource(&psSysData->hQProcessResource, IMG_TRUE);
	if (eError != PVRSRV_OK)
	{
		return eError;
	}
	
	if(psQueue == psQueueInfo)
	{	
		psSysData->psQueueList = psQueueInfo->psNextKM;

		HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psQueueInfo->pvLinQueueKM);
		HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psQueueInfo);

		eError = HostDestroyResource(&psQueueInfo->hAccess);
		if (eError != PVRSRV_OK)
		{
			return eError;
		}
	}
	else
	{
		while(psQueue)
		{
			if(psQueue->psNextKM == psQueueInfo)
			{
				psQueue->psNextKM = psQueueInfo->psNextKM;

				HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psQueueInfo->pvLinQueueKM);
				HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psQueueInfo);

				eError = HostDestroyResource(&psQueueInfo->hAccess);
				if (eError != PVRSRV_OK)
				{
					return eError;
				}				
				break;
			}
			psQueue = psQueue->psNextKM;
		}

		if(!psQueue)
		{
			eError = HostUnlockResource(&psSysData->hQProcessResource);
			if (eError != PVRSRV_OK)
			{
				return eError;
			}
			return PVRSRV_ERROR_INVALID_PARAMS;
		}
	}

	return HostUnlockResource(&psSysData->hQProcessResource);
}


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

 @Function	PVRSRVCreateCommandQueue
 
 @Description 
 Creates a new command queue into which render/blt commands etc can be 
 inserted.
 
 @Input    psDevData : 

 @Input    ui32QueueSize : 

 @Output   ppsQueueInfo : 

 @Return   PVRSRV_ERROR  : 

******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueue(	PVRSRV_DEV_DATA *psDevData, 
													IMG_UINT32 ui32QueueSize, 
											  		PVRSRV_QUEUE_INFO **ppsQueueInfo)
{
	PVRSRV_QUEUE_INFO	*psQueueInfo;
	IMG_UINT32			ui32Power2QueueSize = NearestPower2(ui32QueueSize);
	SYS_DATA			*psSysData;
	PVRSRV_ERROR		eError;
	
	eError = SysAcquireData(&psSysData);
	if (eError != PVRSRV_OK)
	{
		return eError;
	}
	
	/* allocate an internal queue info structure */
	if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP, 
					 sizeof(PVRSRV_QUEUE_INFO), 
					 (IMG_VOID **)&psQueueInfo, 0) != PVRSRV_OK)
	{
		goto ErrorExit;
	}
	HostMemSet(psQueueInfo, 0, sizeof(PVRSRV_QUEUE_INFO));

	/* allocate the command queue buffer - allow for overrun */
	if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP, 
					 ui32Power2QueueSize + PVRSRV_MAX_CMD_SIZE, 
					 &psQueueInfo->pvLinQueueKM, 0) != PVRSRV_OK)
	{
		goto ErrorExit;
	}

	psQueueInfo->pvLinQueueUM = psQueueInfo->pvLinQueueKM;
	psQueueInfo->ui32ReadOffset = 0;
	psQueueInfo->ui32WriteOffset = 0;

	if (HostCreateResource(&psQueueInfo->hAccess) != PVRSRV_OK)
	{
		goto ErrorExit;
	}
	
	psQueueInfo->ui32QueueSize = ui32Power2QueueSize;
	
	/* Ensure we don't corrupt queue list, by blocking access */
	if (HostLockResource(&psSysData->hQProcessResource, IMG_TRUE) != PVRSRV_OK)

⌨️ 快捷键说明

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