📄 pvrsrv.c
字号:
/*!****************************************************************************
@File pvrsrv.c
@Title core services functions
@Author Imagination Technologies
@date 16 September 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 Main APIs for core services functions
@DoxygenVer
******************************************************************************/
/******************************************************************************
Modifications :-
$Log: pvrsrv.c $
*****************************************************************************/
#include "services_headers.h"
#include "buffer_manager.h"
#include "mbx1defs.h"
#include "mbx13ddef.h"
static PVRSRV_ERROR DisableDevice(PPVRSRV_DEV_INFO psDevInfo);
PVRSRV_ERROR EnableDevice(PPVRSRV_DEV_INFO psDevInfo);
/* Resman callbacks */
static PVRSRV_ERROR FreeDeviceMemCallBack(IMG_UINT32 ui32ProcessID, IMG_PVOID pvParam, IMG_UINT32 ui32Param);
static PVRSRV_ERROR ReleaseDeviceDataCallBack(IMG_UINT32 ui32ProcessID, IMG_PVOID pvParam, IMG_UINT32 ui32Param);
#ifdef SUPPORT_DEVCLASS_3D
/* FIXME: -> common 3d header */
PVRSRV_ERROR Init3DDeviceInfo(PVRSRV_DEV_INFO **ppsDevInfo,
PVRSRV_DEVICE_IDENTIFIER *psDevId);
PVRSRV_ERROR DeInit3DDeviceInfo(PVRSRV_DEV_INFO *psDevInfo);
PVRSRV_ERROR Enable3DDevice(PVRSRV_DEV_INFO *psDevInfo);
PVRSRV_ERROR Disable3DDevice(PVRSRV_DEV_INFO *psDevInfo);
#endif
#ifdef SUPPORT_DEVCLASS_DISPLAY
/* FIXME: -> common display header */
PVRSRV_ERROR InitDisplayDeviceInfo(PVRSRV_DEV_INFO **ppsDevInfo,
PVRSRV_DEVICE_IDENTIFIER *psDevId);
PVRSRV_ERROR DeInitDisplayDeviceInfo(PVRSRV_DEV_INFO *psDevInfo);
PVRSRV_ERROR EnableDisplayDevice(PVRSRV_DEV_INFO *psDevInfo);
PVRSRV_ERROR DisableDisplayDevice(PVRSRV_DEV_INFO *psDevInfo);
#endif
/* FIXME: -> common mpeg header */
#ifdef SUPPORT_DEVCLASS_MPEG
PVRSRV_ERROR InitMpegDeviceInfo(PVRSRV_DEV_INFO **ppsDevInfo,
PVRSRV_DEVICE_IDENTIFIER *psDevId);
PVRSRV_ERROR DeInitMpegDeviceInfo(PVRSRV_DEV_INFO *psDevInfo);
PVRSRV_ERROR EnableMpegDevice(PVRSRV_DEV_INFO *psDevInfo);
PVRSRV_ERROR DisableMpegDevice(PVRSRV_DEV_INFO *psDevInfo);
#endif
#ifdef SUPPORT_POWER_STATE
static void ProcessCallbacks(PVRSRV_DEV_INFO *psDevInfo, PVR_POWER_STATE ePVRState, IMG_UINT32 ui32Flags);
#endif
/*!
******************************************************************************
@Function InitDeviceInfo
@Description
Calls device class specific function to allocate and setup the devinfo
@Input psDevId : device identifier
@Return PVRSRV_ERROR :
******************************************************************************/
static PVRSRV_ERROR InitDeviceInfo (PVRSRV_DEV_INFO **ppsDevInfo,
PVRSRV_DEVICE_IDENTIFIER *psDevId)
{
PVRSRV_ERROR eError = PVRSRV_OK;
SYS_DATA *psSysData;
PVR_ASSERT(ppsDevInfo != IMG_NULL);
PVR_ASSERT(psDevId != IMG_NULL);
eError = SysAcquireData(&psSysData);
if (eError != PVRSRV_OK)
{
return eError;
}
/* allocate and setup the devinfo */
switch (psDevId->eDeviceClass)
{
#ifdef SUPPORT_DEVCLASS_3D
case PVRSRV_DEVICE_CLASS_3D :
{
eError = Init3DDeviceInfo(ppsDevInfo, psDevId);
break;
}
#endif
#ifdef SUPPORT_DEVCLASS_DISPLAY
case PVRSRV_DEVICE_CLASS_DISPLAY :
{
eError = InitDisplayDeviceInfo(ppsDevInfo, psDevId);
break;
}
#endif
#ifdef SUPPORT_DEVCLASS_MPEG
case PVRSRV_DEVICE_CLASS_MPEG :
{
eError = InitMpegDeviceInfo(ppsDevInfo, psDevId);
break;
}
#endif /* SUPPORT_DEVCLASS_MPEG */
default :
{
PVR_DPF((PVR_DBG_ERROR,"InitDeviceInfo: unknown device class"));
eError = PVRSRV_ERROR_GENERIC;
break;
}
}
if (eError == PVRSRV_OK)
{
/*
setup the kicker address in all devices
*/
(*ppsDevInfo)->pui32KickerAddrKM = psSysData->pui32KickerAddr;
}
return eError;
}
/*!
******************************************************************************
@Function DeInitDeviceInfo
@Description
Calls device class specific function to deallocate devinfo and associated
sub structures
@Input psDevInfo : device info structure
@Return PVRSRV_ERROR :
******************************************************************************/
static PVRSRV_ERROR DeInitDeviceInfo (PVRSRV_DEV_INFO *psDevInfo)
{
PVRSRV_ERROR eError = PVRSRV_OK;
PVR_ASSERT(psDevInfo != IMG_NULL);
/* allocate and setup the devinfo */
switch (psDevInfo->sDevId.eDeviceClass)
{
#ifdef SUPPORT_DEVCLASS_3D
case PVRSRV_DEVICE_CLASS_3D :
{
eError = DeInit3DDeviceInfo(psDevInfo);
break;
}
#endif
#ifdef SUPPORT_DEVCLASS_DISPLAY
case PVRSRV_DEVICE_CLASS_DISPLAY :
{
eError = DeInitDisplayDeviceInfo(psDevInfo);
break;
}
#endif
#ifdef SUPPORT_DEVCLASS_MPEG
case PVRSRV_DEVICE_CLASS_MPEG :
{
eError = DeInitMpegDeviceInfo(psDevInfo);
break;
}
#endif
default :
{
PVR_DPF((PVR_DBG_ERROR,"DeInitDeviceInfo: unknown device class"));
eError = PVRSRV_ERROR_GENERIC;
break;
}
}
return eError;
}
/*!
******************************************************************************
@Function EnableDevice
@Description
Calls device class specific function to enable the device
@Input psDevInfo : device info structure
@Return PVRSRV_ERROR :
******************************************************************************/
PVRSRV_ERROR EnableDevice (PVRSRV_DEV_INFO *psDevInfo)
{
PVRSRV_ERROR eError = PVRSRV_OK;
/* allocate and setup the devinfo */
switch (psDevInfo->sDevId.eDeviceClass)
{
case PVRSRV_DEVICE_CLASS_3D :
{
eError = Enable3DDevice(psDevInfo);
break;
}
case PVRSRV_DEVICE_CLASS_DISPLAY :
{
eError = EnableDisplayDevice(psDevInfo);
break;
}
#ifdef SUPPORT_DEVCLASS_MPEG
case PVRSRV_DEVICE_CLASS_MPEG :
{
eError = EnableMpegDevice(psDevInfo);
break;
}
#endif
default :
{
PVR_DPF((PVR_DBG_ERROR,"InitDeviceInfo: unknown device class"));
eError = PVRSRV_ERROR_GENERIC;
}
}
return eError;
}
/*!
******************************************************************************
@Function AllocSyncInfo
@Description
allocates a syncinfo structure
@Input psDevInfo
@Return pointer to syncinfo memory or IMG_NULL
******************************************************************************/
static IMG_PVOID AllocSyncInfo(PVRSRV_DEV_INFO *psDevInfo)
{
PVRSRV_SYNC_INFO * psSyncInfo = IMG_NULL;
PVR_ASSERT(psDevInfo != IMG_NULL);
if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP,
sizeof(PVRSRV_SYNC_INFO),
(IMG_VOID **)&psSyncInfo, 0) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"AllocSyncInfo : Failed to alloc syncinfo"));
return IMG_NULL;
}
/* wire-up the pui32LastWriteOp */
psSyncInfo->pui32LastWriteOp = &psSyncInfo->ui32LastWriteOpVal;
/* initialise structure members */
psSyncInfo->ui32NextWriteOp = 2;
*psSyncInfo->pui32LastWriteOp = 1;
psSyncInfo->ui32ReadOpsComplete = 0;
psSyncInfo->ui32ReadOpsPending = 0;
psSyncInfo->ui32BlitOpsPending = 0;
psSyncInfo->ui32BlitOpsComplete = 0;
psSyncInfo->psKernSyncInfo = psSyncInfo;
return psSyncInfo;
}
/*!
******************************************************************************
@Function FreeSyncInfo
@Description
frees a syncinfo structure
@Input psSyncInfo
@Return pointer to syncinfo memory or IMG_NULL
******************************************************************************/
static PVRSRV_ERROR FreeSyncInfo (PVRSRV_SYNC_INFO *psSyncInfo)
{
SYS_DATA *psSysData;
IMG_UINT32 i;
PVR_ASSERT(psSyncInfo != IMG_NULL);
if (SysAcquireData(&psSysData) != PVRSRV_OK)
{
return PVRSRV_ERROR_GENERIC;
}
for(i=0; i<WAIT_TRY_COUNT; i++)
{
if( (*psSyncInfo->pui32LastWriteOp == psSyncInfo->ui32NextWriteOp - 1)
&& (psSyncInfo->ui32ReadOpsComplete == psSyncInfo->ui32ReadOpsPending))
{
break;
}
SysKickCmdProc (psSysData->pui32KickerAddr);
HostWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
}
if(i==WAIT_TRY_COUNT)
{
PVR_DPF((PVR_DBG_ERROR,"FreeSyncInfo : Failed to free syncinfo"));
return PVRSRV_ERROR_GENERIC;
}
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psSyncInfo);
return PVRSRV_OK;
}
/*!
******************************************************************************
@Function PVRSRVEnumerateDevices
@Description
This function will enumerate all the devices supported by the
PowerVR services within the target system.
The function returns a list of the device ID strcutres stored either in
the services or constructed in the user mode glue component in certain
environments. The number of devices in the list is also returned.
In a binary layered component which does not support dynamic runtime selection,
the glue code should compile to return the supported devices statically,
e.g. multiple instances of the same device if multiple devices are supported,
or the target combination of MBX and display device.
In the case of an environment (for instance) where one MBX1 may connect to two
display devices this code would enumerate all three devices and even
non-dynamic MBX1 selection code should retain the facility to parse the list
to find the index of the MBX device
@input hServices: : bridging handle - not used on kernel side
@output pui32NumDevices : On success, contains the number of devices present
in the system
@output psDevIdList : Pointer to called supplied buffer to receive the
list of PVRSRV_DEVICE_IDENTIFIER
@return PVRSRV_ERROR : PVRSRV_NO_ERROR
******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVEnumerateDevices (IMG_HANDLE hServices,
IMG_UINT32 *pui32NumDevices,
PVRSRV_DEVICE_IDENTIFIER *psDevIdList)
{
PVRSRV_ERROR eError = PVRSRV_OK;
SYS_DATA *psSysData;
IMG_UINT32 i;
hServices = hServices;/* compiler - only used on bridging API but need same signature */
if(!pui32NumDevices || !psDevIdList)
{
return PVRSRV_ERROR_INVALID_PARAMS;
}
eError = SysAcquireData(&psSysData);
if (eError != PVRSRV_OK)
{
return eError;
}
/*
setup input buffer to be `empty'
*/
for (i=0; i<PVRSRV_MAX_DEVICES; i++)
{
psDevIdList[i].eDeviceType = PVRSRV_DEVICE_TYPE_UNKNOWN;
}
/*
PVRSRVConnect() passes a user structure containing a handle
(actually KMptr) this call makes a connection to the services
and creates an internal sys_data object based on data in the
sysconfig.h header file. If the sysconfig structure specifies
static enumeration we simply copy back the appropriate
PVRSRV_DEVICE_IDENTIFIER structures to the caller (assume the caller
always supplies MAX_DEVICE_IDENTIFIERS * PVRSRV_DEVICE_IDENTIFIER)
The sysdata object has a list of `partial devinfo' structures. `partial'
because the we only need a limited amount of data from the full devinfo
in order to find the device.(?)
struct PVRSRV_SYS_DATA
{
struct PVRSRV_DEVINFO_INIT
{
PVRSRV_DEVICE_IDENTIFIER sDevIdentity;
IMG_UINT32 *ui32RefCount;
... much more (see devinfo)
}
// this gets allocated or populated on first call to getdevinfo for the device
struct PVRSRV_DEVINFO_USE
{
// data structures required to use device
}
}
Each structure in the list represents a device in the system.
n.b. if bStaticEnumeration then each structure represents a device
that IS present in the system whereas if bDynamicEnum the structures
represent devices that MAY be present:
*/
if (psSysData->bStaticEnumeration)
{
/* here we know what's there so just set it up */
for (i=0; i<psSysData->ui32NumDevices; i++)
{
psDevIdList[i] = psSysData->asDevIdList[i];
}
/* return device count */
*pui32NumDevices = psSysData->ui32NumDevices;
}
#if 0/* add later */
else /* dynamic enumeration */
{
/* here we must try to find all possible devices available to the system */
for (i=0, j=0; i<psSysData->ui32NumDevices; i++)
{
if (FindDevice(&psSysData->psDevInfoInit[i]) == PVRSRV_OK)
{
psDevIdList[j] = psSysData->asDevIdList[i];
/* move to next */
j++;
}
}
/* return device count */
*puiNumDevices = j;
}
#endif
return PVRSRV_OK;
}
/*!
******************************************************************************
@Function PVRSRVAcquireDeviceData
@Description
This returns a pointer to the device info structure for the requested device
This populates a PVRSRV_DEV_DATA structure with appropriate pointers to the
DevInfo structure for the device requested.
In a non-plug-and-play the first call to GetDeviceInfo for a device causes
device initialisation
Calls to GetDeviceInfo are reference counted
@Input hServices : Handle to services
@Input uiDevIndex : Index to the required device obtained from the
PVRSRVEnumerateDevice function
@Input eDeviceType : Required device type. If type is unknown use uiDevIndex
to locate device data
@Output psDevData :
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceData ( IMG_HANDLE hServices,
IMG_UINT32 uiDevIndex,
PVRSRV_DEV_DATA *psDevData,
PVRSRV_DEVICE_TYPE eDeviceType)
{
PPVRSRV_DEV_INFO psDevInfo, psThis;
SYS_DATA *psSysData;
PVRSRV_ERROR eError = PVRSRV_OK;
PVRSRV_DEVICE_IDENTIFIER *psDevID = IMG_NULL;
IMG_UINT32 i;
IMG_BOOL bFindByType;
IMG_BOOL bFound;
PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceData"));
if (psDevData == IMG_NULL)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceData - Received IMG_NULL pointer to device data"));
return PVRSRV_ERROR_INVALID_PARAMS;
}
psDevData->hServices = hServices;/* compiler - only used on bridging API but need same signature */
psDevData->psResItem = IMG_NULL; /* Not registered with RESMAN */
eError = SysAcquireData(&psSysData);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -