📄 hostfunc_um.c
字号:
/*!****************************************************************************
@File hostfunc_um.c
@Title platform related function header
@Author Imagination Technologies
@date 22 / 10 / 03
@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 wince
@Description environment related functions
@DoxygenVer
******************************************************************************/
/******************************************************************************
Modifications :-
$Log: hostfunc_um.c $
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
*****************************************************************************/
#include <windows.h>
#include <ceddk.h>
#include "img_defs.h"
#include "services.h"
#include "syscommon.h"
#include "pvr_debug.h"
#include "hostfunc_um.h"
/*!
******************************************************************************
@Function HostAcquireMutex
@Description locks an OS dependant mutex object
@Input psMutex - pointer to OS dependent mutex structure
@Input bBlock - do we want to block?
@Return error status
******************************************************************************/
PVRSRV_ERROR HostAcquireMutex (PVRSRV_MUTEX_HANDLE *phMutex,
IMG_BOOL bBlock)
{
PVRSRV_ERROR eError;
IMG_UINT32 ui32LockVal;
IMG_UINT32 ui32Result;
IMG_UINT32 ui32Count = 0;
IMG_UINT32 ui32Ms = 0;
IMG_UINT32 *pui32Access = (IMG_UINT32 *)phMutex;
IMG_UINT32 i;
/*
The ideal implementation may be mutex objects
For now we'll implement spin-locks using `atomic exchange' and Sleep(0)
*/
/* get process id and use as lock id */
ui32LockVal = HostGetCurrentProcessID();
if (bBlock)
{
for(i=0; i<WAIT_TRY_COUNT; i++)
{
if(ui32Result = InterlockedTestExchange(pui32Access, 0, ui32LockVal))
{
if (i > 100)
{
HostReleaseThreadQuanta();
}
/* wait some time */
HostWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
}
else
{
break;
}
}
}
else
{
/* try once or more*/
ui32Result = InterlockedTestExchange(pui32Access, 0, ui32LockVal);
}
if(ui32Result == 0)
{
eError = PVRSRV_OK;
}
else
{
PVR_DPF((PVR_DBG_ERROR,"HostAcquireMutex: failed\n"));
eError = PVRSRV_ERROR_GENERIC;
}
return eError;
}
/*!
******************************************************************************
@Function HostReleaseMutex
@Description Releases an OS dependant mutex object
@Input psMutex3D - pointer to OS dependent mutex structure
@Return error status
******************************************************************************/
PVRSRV_ERROR HostReleaseMutex (PVRSRV_MUTEX_HANDLE *phMutex)
{
IMG_UINT32 ui32LockVal;
volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)phMutex;
PVRSRV_ERROR eError = PVRSRV_OK;
/*
The ideal implementation may be `cheap semaphores provided by linux
For now we'll implement spin-locks using `atomic exchange' and Sleep(0)
*/
ui32LockVal = HostGetCurrentProcessID();
if (*pui32Access != ui32LockVal)
{
PVR_DPF((PVR_DBG_ERROR,"HostReleaseMutex: Mutex is not locked with expected value"));
eError = PVRSRV_ERROR_GENERIC;
}
else
{
*pui32Access = 0;
}
return eError;
}
/*!
******************************************************************************
@Function HostLockResource
@Description locks an OS dependant Resource
@Input phResource - pointer to OS dependent Resource
@Input bBlock - do we want to block?
@Return error status
******************************************************************************/
PVRSRV_ERROR HostLockResource (PVRSRV_RES_HANDLE *phResource,
IMG_BOOL bBlock)
{
PVRSRV_ERROR eError;
IMG_UINT32 ui32LockVal;
IMG_UINT32 ui32Result;
IMG_UINT32 ui32Count = 0;
IMG_UINT32 ui32Ms = 0;
IMG_UINT32 *pui32Access = (IMG_UINT32 *)phResource;
IMG_UINT32 i;
/*
The ideal implementation may be mutex objects
For now we'll implement spin-locks using `atomic exchange' and Sleep(0)
*/
/* get process id and use as lock id */
ui32LockVal = HostGetCurrentProcessID();
if (bBlock)
{
for(i=0; i<WAIT_TRY_COUNT; i++)
{
if (ui32Result = InterlockedTestExchange(pui32Access, 0, ui32LockVal))
{
if (i > 100)
{
HostReleaseThreadQuanta();
}
/* wait some time */
HostWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
}
else
{
break;
}
}
}
else
{
/* try once or more*/
ui32Result = InterlockedTestExchange(pui32Access, 0, ui32LockVal);
}
if(ui32Result == 0)
{
eError = PVRSRV_OK;
}
else
{
PVR_DPF((PVR_DBG_ERROR,"HostLockResource: failed\n"));
eError = PVRSRV_ERROR_GENERIC;
}
return eError;
}
/*!
******************************************************************************
@Function HostUnlockResource
@Description unlocks an OS dependant resource
@Input psMutex3D - pointer to OS dependent mutex structure
@Return
******************************************************************************/
PVRSRV_ERROR HostUnlockResource (PVRSRV_RES_HANDLE *phResource)
{
IMG_UINT32 ui32LockVal;
volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)phResource;
PVRSRV_ERROR eError = PVRSRV_OK;
/*
The ideal implementation may be `cheap semaphores provided by linux
For now we'll implement spin-locks using `atomic exchange' and Sleep(0)
*/
ui32LockVal = HostGetCurrentProcessID();
if (*pui32Access != ui32LockVal)
{
PVR_DPF((PVR_DBG_ERROR,"HostUnlockResource: Resource is not locked with expected value"));
eError = PVRSRV_ERROR_GENERIC;
}
else
{
*pui32Access = 0;
}
return eError;
}
#ifdef DEBUG
/*!
******************************************************************************
@Function HostIsResourceLocked
@Description tests if resource is locked
@Input phResource - pointer to OS dependent mutex structure
@Return error status
******************************************************************************/
IMG_BOOL HostIsResourceLocked (PVRSRV_RES_HANDLE *phResource)
{
volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)phResource;
return *(volatile IMG_UINT32 *)pui32Access == 0
? IMG_FALSE
: IMG_TRUE;
}
#endif
/*!
******************************************************************************
@Function HostAllocUserModeMem
@Description Allocates memory that is can be accessed by user mode code
@Input ui32Size : number of bytes to allocate
@Return On succes address of allocated buffer else NULL
******************************************************************************/
IMG_PVOID HostAllocUserModeMem (IMG_UINT32 ui32Size)
{
return (IMG_PVOID)malloc(ui32Size);
}
/*----------------------------------------------------------------------------
<function>
FUNCTION : HostFreeUserModeMem
PURPOSE : Free memory that was allocated with HostAllocUserModeMem()
PARAMETERS : PVOID pvMem - pointer to memory to free
RETURNS : nothing
</function>
------------------------------------------------------------------------------*/
IMG_VOID HostFreeUserModeMem (IMG_PVOID pvMem)
{
free(pvMem);
}
/*!
******************************************************************************
@Function HostReallocUserModeMem
@Description
The function changes the size of the block whose address is pvBase
to be ui32Size. The block must previously have been allocated via
HostAllocUserModeMem or HostReallocUserModeMem.
If you pass IMG_NULL for pvBase, the function behaves just like
HostAllocUserModeMem.
Like HostAllocUserModeMem this function may return IMG_NULL if no
memory space is available to make the block bigger. When this
happens the original block is not modified or relocated.
@Input pvBase - base pointer of block to resize.
@Input uNewSize - new size required in bytes.
@Return Pointer to re-allocated block on success, or IMG_NULL on failure.
******************************************************************************/
IMG_PVOID
HostReallocUserModeMem (IMG_PVOID pvBase, IMG_SIZE_T uNewSize)
{
return realloc (pvBase, uNewSize);
}
/*!
******************************************************************************
@Function HostClockus
@Description
This function returns the clock in microseconds
@Input void
@Return - clock (us)
******************************************************************************/
IMG_UINT32 HostClockus (IMG_VOID)
{
return (GetTickCount() * 1000);
}
/*!
******************************************************************************
@Function HostWaitus
@Description
This function implements a busy wait of specified microseconds
This function does NOT release thread quanta
@Input ui32Timeus - (us)
@Return nothing
******************************************************************************/
IMG_VOID HostWaitus (IMG_UINT32 ui32Timeus)
{
#define APPROX_LOOPS_PER_MICROSECOND 10
IMG_UINT32 uiMicroSecond;
volatile IMG_UINT32 uiLoop;
for (uiMicroSecond = 0; uiMicroSecond < ui32Timeus; uiMicroSecond++)
{
for (uiLoop = 0; uiLoop < APPROX_LOOPS_PER_MICROSECOND; uiLoop++) ;
}
}
/*!
******************************************************************************
@Function HostReleaseThreadQuanta
@Description
Releases thread quanta
@Return nothing
******************************************************************************/
IMG_VOID HostReleaseThreadQuanta ()
{
Sleep(0);
}
/*----------------------------------------------------------------------------
<function>
FUNCTION : HostMemCopy
PURPOSE : Copies memory around
PARAMETERS : pvDst, pvSrc, ui32Size
RETURNS :
</function>
------------------------------------------------------------------------------*/
IMG_VOID HostMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_UINT32 ui32Size)
{
memcpy(pvDst, pvSrc, ui32Size);
}
/*!
******************************************************************************
@Function HostMemSet
@Description Function that does the same as the C memset() functions
@Modified *pvDest : pointer to start of buffer to be set
@Input ui8Value: value to set each byte to
@Input ui32Size : number of bytes to set
@Return IMG_VOID
******************************************************************************/
IMG_VOID HostMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size)
{
memset(pvDest, (int) ui8Value, (size_t) ui32Size);
}
/*!
******************************************************************************
@Function HostGetCurrentProcessID
@Description Returns handle for current process
@Return ID of current process
******************************************************************************/
IMG_UINT32 HostGetCurrentProcessID (void)
{
return (IMG_UINT32)GetCurrentProcessId();
}
/*!
******************************************************************************
@Function HostOpenEvent
@Description Opens a named event allowing interprocess communication
@Input phWaitEventHandle - pointer to OS dependent event structure
@Return error status
******************************************************************************/
PVRSRV_ERROR HostCreateEvent (PVRSRV_MUTEX_HANDLE *phEvent)
{
volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)phEvent;
IMG_UINT16 ui16EventName[3];
/* Set up name from passed in Handle */
*((IMG_UINT32*)(ui16EventName)) = *pui32Access;
ui16EventName[2] = 0;/* Null Termination */
*pui32Access = (IMG_UINT32) CreateEvent(IMG_NULL, IMG_FALSE, IMG_FALSE, (LPTSTR)ui16EventName);
if(*pui32Access == IMG_NULL)
return PVRSRV_ERROR_GENERIC;
else
return PVRSRV_OK;
}
/*!
******************************************************************************
@Function HostOpenEvent
@Description Opens a named event allowing interprocess communication
@Input phWaitEventHandle - pointer to OS dependent event structure
@Return error status
******************************************************************************/
PVRSRV_ERROR HostOpenEvent(PVRSRV_MUTEX_HANDLE *phWaitEventHandle)
{
volatile IMG_UINT32 *pui32Access = (volatile IMG_UINT32 *)phWaitEventHandle;
IMG_UINT16 ui16EventName[3];
/* Set up name from passed in Handle */
*((IMG_UINT32*)(ui16EventName)) = *pui32Access;
ui16EventName[2] = 0;/* Null Termination */
*pui32Access = (IMG_UINT32) OpenEvent(EVENT_ALL_ACCESS, IMG_FALSE, (LPCTSTR)ui16EventName);
if(!*pui32Access)
return PVRSRV_ERROR_GENERIC;
else
return PVRSRV_OK;
}
/*!
******************************************************************************
@Function HostWriteHWReg
@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_UINT32 HostReadHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset)
{
return *(volatile IMG_UINT32*)((IMG_UINT32)pvLinRegBaseAddr+ui32Offset);
}
/*!
******************************************************************************
@Function HostWriteHWRegs
@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_VOID HostWriteHWReg(IMG_PVOID pvLinRegBaseAddr, IMG_UINT32 ui32Offset, IMG_UINT32 ui32Value)
{
*(IMG_UINT32*)((IMG_UINT32)pvLinRegBaseAddr+ui32Offset) = ui32Value;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -