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

📄 sharedutils.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
字号:
/*!****************************************************************************
@File			sharedutils.c

@Title			functionality shared across UM/KM

@Author			Imagination Technologies

@date   		24/10/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	Provides shared user/kernel side functions

@DoxygenVer		

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

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

$Log: sharedutils.c $
*****************************************************************************/

#if defined(PVR_KERNEL)
#include "services_headers.h"
#else
#include "img_defs.h"
#include "services.h"
#include "pvr3dif.h"
#include "queue.h"
#include "syscommon.h"
#include "hostfunc_um.h"
#include "pvr_debug.h"
#endif
#include "sharedutils.h"
#include "mbx1defs.h"
#include "mbx13ddef.h"

#define HWCONTEXTID_ZERO	0
#define HWCONTEXTID_ONE		1
#define HWCONTEXTID_BUSY	1
#define HWCONTEXTID_FREE	0

// Quick and easy slave port monitor.
#define TRACK_SLAVEPORT		0		// 0 to disable, 1 to enable.

#if TRACK_SLAVEPORT
BOOL gbTrackSlaveport = FALSE;		// Set to 1 in debugger to enable
#endif

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

 @Function	FreeHWContextID
 
 @Description 
 
 USER AND KERNEL MODE FUNCTION
 frees context id. Called from StoreContext and 3D complete ISR
  
 @Input    psDevInfo 			 : UM devinfo
 
 @Input    ui32HWContextID		 : ID to free
 
 @Return   none

******************************************************************************/
IMG_VOID FreeHWContextID(PVRSRV_DEV_INFO *psDevInfo, IMG_UINT32 ui32HWContextID)
{
	DEVICE3D *psDevice3D = &psDevInfo->sDeviceSpecific.s3D;

	if(ui32HWContextID == HWCONTEXTID_ZERO)
	{
		/* id == 0 */
		PVR_ASSERT(psDevice3D->aui32HWContextIDState[HWCONTEXTID_ZERO] == HWCONTEXTID_BUSY);
		psDevice3D->aui32HWContextIDState[HWCONTEXTID_ZERO] = HWCONTEXTID_FREE;
	}
	else
	{
		/* id == 1 */
		PVR_ASSERT(psDevice3D->aui32HWContextIDState[HWCONTEXTID_ONE] == HWCONTEXTID_BUSY);
		psDevice3D->aui32HWContextIDState[HWCONTEXTID_ONE] = HWCONTEXTID_FREE;
	}	
}


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

 @Function	PVRSRVAcquireSlavePort
 
 @Description 
 
 USER AND KERNEL MODE FUNCTION
 Acquire the specified SlavePort(s). The TA must be acquired before 
 acquiring the 3D slave port. Called from display driver, 3D driver and ISRs
 
 @Input    psDevInfo 			 : UM devinfo

 @Input    eSlavePortType	: slaveport type to acquire

 @Input    bBlock			: block until port is available or return failure

 @Return   PVRSRV_ERROR 	: NO_ERROR or PVRSRV_BAD_PARAM

******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireSlavePort (PVRSRV_DEV_INFO		*psDevInfo,
											  	  PVRSRV_SLAVEPORT_TYPE eSlavePortType,
											   	  IMG_BOOL 				bBlock)
{
	DEVICE3D			*ps3D = &psDevInfo->sDeviceSpecific.s3D;
	PVRSRV_ERROR		eError = PVRSRV_OK;
	
	switch (eSlavePortType)
	{
		case PVRSRV_SLAVEPORT_3D :
			/* nothing to do */
			break;
		case PVRSRV_SLAVEPORT_2D :
			eError = HostLockResource(&ps3D->h2DSlaveportResource, bBlock);	
			break;
		default :
			PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireSlavePort: invalid slaveport type"));
			eError = PVRSRV_ERROR_INVALID_PARAMS;
			break;
	}
	
	return eError;	
}

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

 @Function	PVRSRVReleaseSlavePort
 
 @Description 
 
 USER AND KERNEL MODE FUNCTION
 Releases the specified SlavePort(s). The 3D slaveport must be 
 released before releasing the TA. Called from display driver, 3D driver 
 and ISRs
 
 @Input    psDevInfo 		: UM devinfo 

 @Input    eSlavePortType	: slaveport type to acquire

 @Return   PVRSRV_ERROR	: NO_ERROR, PVRSRV_BAD_PARAM or RESOURCE_NOT_LOCKED

******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVReleaseSlavePort (PVRSRV_DEV_INFO 		*psDevInfo,
											  	  PVRSRV_SLAVEPORT_TYPE	eSlavePortType)
{
	DEVICE3D			*ps3D = &psDevInfo->sDeviceSpecific.s3D;
	PVRSRV_ERROR		eError = PVRSRV_OK;

	switch (eSlavePortType)
	{
		case PVRSRV_SLAVEPORT_3D :
			/* reset the reserve */
			ps3D->ui32BytesReservedTA = 0;
			break;
		case PVRSRV_SLAVEPORT_2D :
			/* reset the reserve */
			ps3D->ui32BytesReserved2d = 0;
			eError = HostUnlockResource(&ps3D->h2DSlaveportResource);
			break;
		default :
			PVR_DPF((PVR_DBG_ERROR,"PVRSRVReleaseSlavePort: invalid slaveport type"));
			eError = PVRSRV_ERROR_INVALID_PARAMS;
			break;
	}
	
	return eError;	
}


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

 @Function	ReadHWReg
 
 @Description 
 
 register access function

 @input pvLinRegBaseAddr :	lin addr of register block base

 @input ui32Offset :	 byte offset from register base
 
 @Return   register value

******************************************************************************/
IMG_EXPORT
IMG_UINT32 ReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
{
	return *(volatile IMG_UINT32*)((IMG_UINT32)pvLinRegBaseAddr+ui32Offset);
}

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

 @Function	WriteHWReg
 
 @Description 
 
 register access function

 @input pvLinRegBaseAddr :	lin addr of register block base

 @input ui32Offset :	 byte offset from register base

 @input ui32Value :	 value to write to register
 
 @Return   register value : original reg. value

******************************************************************************/
IMG_EXPORT
IMG_VOID WriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
{
	PVR_DPF((PVR_DBG_MESSAGE,"WriteHWReg Base:%x, Offset: %x, Value %x",pvLinRegBaseAddr,ui32Offset,ui32Value));

	HostWriteHWReg(pvLinRegBaseAddr, ui32Offset, ui32Value);
}


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

 @Function	WriteHWRegs
 
 @Description 
 
 register access function

 @input pvLinRegBaseAddr :	lin addr of register block base

 @input ui32Count :	 register count

 @input psHWRegs :	 address/value register list
 
 @Return   none

******************************************************************************/
IMG_EXPORT
IMG_VOID WriteHWRegs(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Count, PVRSRV_HWREG *psHWRegs)
{
	while (ui32Count--)
	{
		HostWriteHWReg(pvLinRegBaseAddr, psHWRegs->ui32RegAddr, psHWRegs->ui32RegVal);
		psHWRegs++;
	}
}


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

 @Function	PVRSRVWriteSlavePort
 
 @Description 
 writes data to SP
 
 @Input    psSlavePort : 
 
 @Input    ui32Value :

 @Return   none

******************************************************************************/
IMG_EXPORT
IMG_VOID PVRSRVWriteSlavePort(PPVRSRV_DEV_SLAVE_PORT psSlavePort, 
						IMG_UINT32 ui32Value)
{
	volatile IMG_UINT32 *pui32LinPortAddr;
	IMG_UINT32 ui32Offset = *psSlavePort->pui32Offset;

#if TRACK_SLAVEPORT
	if (gbTrackSlaveport) PVR_TRACE(("SP:%08X",ui32Value));
#endif

	pui32LinPortAddr = (IMG_UINT32*)((IMG_UINT32)psSlavePort->pvData + ui32Offset);
	*pui32LinPortAddr = ui32Value;

#if defined(INCREMENTING_SPWRITES)
	ui32Offset += 4;
	*psSlavePort->pui32Offset = (ui32Offset >= psSlavePort->ui32DataRange) ? 0 : ui32Offset;
#endif
}

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

 @Function	PVRSRVWriteSlavePortBatch
 
 @Description 
 writes data to SP
 
 @Input    psSlavePort : 
 
 @Input    pvLinDataAddr :
 
 @Input    ui32Bytes :

 @Return   PVRSRV_ERROR  : 

******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR PVRSRVWriteSlavePortBatch (PPVRSRV_DEV_SLAVE_PORT psSlavePort,
							  IMG_PVOID pvLinDataAddr,
							  IMG_UINT32 ui32Bytes)
{
#if defined(SUPPORT_XSCALE_PLATFORM)
	volatile IMG_UINT32 *pui32LinPortAddr;
	IMG_UINT32 *pui32LinDataAddr;
	IMG_UINT32 ui32SlavePortSize;
	IMG_UINT32 i;
#if defined(INCREMENTING_SPWRITES)
	IMG_UINT32 *pui32Offset;
#endif

	/* ensure we write 4byte blocks */
	PVR_ASSERT ((ui32Bytes & 0x3) == 0);

#if TRACK_SLAVEPORT
	if (gbTrackSlaveport) PVR_TRACE(("SlavePortBatch:%ld writes",ui32Bytes>>2));
#endif

	ui32SlavePortSize = psSlavePort->ui32DataRange;
		
	pui32LinDataAddr = (IMG_UINT32*)pvLinDataAddr;
	
#if defined(INCREMENTING_SPWRITES)
	pui32Offset = psSlavePort->pui32Offset;
	
	if(ui32Bytes < (ui32SlavePortSize - *pui32Offset))
	{
		pui32LinPortAddr = (IMG_UINT32*)((IMG_UINT32)psSlavePort->pvData + *pui32Offset);

		/* we can fit all of this data without wrapping */
		for(i=0;i<ui32Bytes;i+=4)
		{
			*pui32LinPortAddr++ = *pui32LinDataAddr++;	
		}
		*pui32Offset += ui32Bytes;

		return PVRSRV_OK;
	}
	else
	{
		/* we will need to split this data up to fit it into the slave port */

		/* (ui32Wrap - *pui32Offset) represents how much data we can write to the slave port before
		 * we have to wrap 
		 */
		IMG_UINT32 ui32DataBeforeWrap = (ui32SlavePortSize - *pui32Offset);
		
		while(ui32Bytes >= ui32DataBeforeWrap)
		{
			pui32LinPortAddr = (IMG_UINT32*)((IMG_UINT32)psSlavePort->pvData + *pui32Offset);

			for(i=0; i<ui32DataBeforeWrap;i+=4)
			{
				*pui32LinPortAddr++ = *pui32LinDataAddr++;	
			}

			*pui32Offset = 0;
			ui32DataBeforeWrap = ui32SlavePortSize;
			ui32Bytes -= i;
		}

		pui32LinPortAddr = (IMG_UINT32*)(psSlavePort->pvData);

		/* we can fit all of this data without wrapping */
		for(i=0;i<ui32Bytes;i+=4)
		{
			*pui32LinPortAddr++ = *pui32LinDataAddr++;	
		}
		*pui32Offset += ui32Bytes;

		return PVRSRV_OK;
	}
#else
	
	pui32LinPortAddr = (IMG_UINT32*)psSlavePort->pvData;

	/* we can fit all of this data without wrapping */
	for(i=0;i<ui32Bytes;i+=4)
	{
		*pui32LinPortAddr = *pui32LinDataAddr++;	
	}

#endif
#else
	IMG_INT32 i;
	IMG_UINT32			   *pui32LinDataAddr = (IMG_UINT32*) pvLinDataAddr;
	IMG_UINT32			   *pui32LinPortAddrBase = (IMG_UINT32*) psSlavePort->pvData;
	IMG_UINT32			   *pui32LinPortAddr;
	IMG_UINT32 				ui32DWORDs = ui32Bytes>>2;

	for (i = ui32DWORDs; i != 0 ; i -= ui32DWORDs)
	{
		ui32DWORDs = (i < 32) ? i : 32;
		pui32LinPortAddr = pui32LinPortAddrBase;

		switch(ui32DWORDs)
		{
			case 32:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 31:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 30:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 29:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 28:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 27:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 26:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 25:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 24:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 23:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 22:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 21:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 20:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 19:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 18:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 17:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 16:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 15:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 14:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 13:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 12:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 11:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 10:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 9:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 8:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 7:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 6:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 5:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 4:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 3:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 2:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
			case 1:
			*pui32LinPortAddr++ = *pui32LinDataAddr++;
		}
	}
#endif

	return PVRSRV_OK;
}


⌨️ 快捷键说明

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