📄 sharedutils.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 + -