📄 hostfunc.c
字号:
@Function RemoveWCEntry
@Description Remove a WC entry from the list
@Input pvAddress
@Return PVRSRV_ERROR
******************************************************************************/
static PVRSRV_ERROR RemoveWCEntry(PVOID pvAddress)
{
PWRITE_COMBINED_MEM_TAG psWCEntry = &g_sWCList;
PWRITE_COMBINED_MEM_TAG psPrevWCEntry=NULL;
if(pvAddress==NULL)
{
return PVRSRV_OK;
}
while(psWCEntry!=NULL)
{
// search until we find our entry;
if(psWCEntry->pvAddress==pvAddress)
{
break;
}
psPrevWCEntry=psWCEntry;
psWCEntry=psWCEntry->psNext;
}
if(psWCEntry)
{
if(psWCEntry->pvAddress==pvAddress)
{
psPrevWCEntry->psNext=psWCEntry->psNext;
free(psWCEntry);
}
}
return PVRSRV_OK;
}
#endif
#ifdef LOCAL_MEMORY_SELF_REFRESH
/*
This function is used to create the only thread that is used to watch
local memory.
*/
HANDLE HostWatchLocalMemory(LPVOID psDevInfo)
{
static HANDLE hThread = NULL; // Static makes this only occur once.
if(hThread == NULL)
{
hThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)HostLocalMemoryThreadRoutine,
(LPVOID)psDevInfo, 0, NULL);
}
return hThread;
}
/*
The thread procedure that does everything having to do with putting
memory into self-refresh. Other power saving activities dealing with an
idle time could be included here as well. (For example, frequency
changes could be kicked off here potentially.)
*/
IMG_VOID HostLocalMemoryThreadRoutine(LPVOID pParam)
{
PPVRSRV_DEV_INFO psDevInfo = (PPVRSRV_DEV_INFO)pParam;
PSYS_SPECIFIC_DATA pMSysData = psDevInfo->pvSysDataPtr;
volatile signed long users = 0;
while(1) // Do this forever and ever...
{
// If we are still awake, and no one is using local memory...
WaitForSingleObject((HANDLE)pMSysData->hLocalMemoryIdleEvent, INFINITE);
// Then wait for a specified time...
Sleep(pMSysData->uiLocalMemoryTimeout);
// If someone used local memory during that time,
// don't go into self-refresh. Start the loop over.
if(pMSysData->bLocalMemoryTimeoutRefresh)
{
// Better acknowledge that we saw the memory was used.
// This is set to TRUE when someone uses memory as a
// signal to us.
pMSysData->bLocalMemoryTimeoutRefresh = FALSE;
continue;
}
LockLocalMemoryFunction();
if (!pMSysData->uiLocalMemoryUsers)
{
#if REDUCE_FREQ_IN_DISP_REFRESH
SysSDRAMSetStateWithFreqChanges(SYS_SDRAM_POWER_SLEEP);
#else
SysSDRAMSetState(SYS_SDRAM_POWER_SLEEP);
#endif
pMSysData->bSDRAMNeedsWaking = TRUE;
}
UnLockLocalMemoryFunction();
Sleep(0); // Let someone else play with the CPU
} // Keep watching for people to stop using local memory
}
#endif // LOCAL_MEMORY_SELF_REFRESH
/*****************************************************************************/
/************************* PCI interrupt support code ************************/
/*****************************************************************************/
#ifdef SUPPORT_PCI
/*!
******************************************************************************
@Function SetupGIISR
@Description interrupt installer
@Input ui32PhysAddr
@Input ui32IRQ
@Input hIsrHandle
@Input ui32IntMask
@Return PVRSRV_ERROR
******************************************************************************/
static IMG_BOOL SetupGIISR (IMG_UINT32 ui32PhysAddr, IMG_UINT32 ui32IRQ, HANDLE hIsrHandle, IMG_UINT32 ui32IntMask)
{
GIISR_INFO sInfo;
/* Set up ISR handler */
sInfo.SysIntr = ui32IRQ;
sInfo.CheckPort = TRUE;
sInfo.PortIsIO = FALSE;
sInfo.UseMaskReg = FALSE;
sInfo.PortAddr = ui32PhysAddr;
sInfo.PortSize = sizeof(ULONG);
sInfo.Mask = ui32IntMask;
if (!KernelLibIoControl(hIsrHandle, IOCTL_GIISR_INFO, &sInfo, sizeof(sInfo), NULL, 0, NULL))
{
PVR_DPF((PVR_DBG_ERROR,"SetupGIISR: KernelLibIoControl call failed.\n"));
return (FALSE);
}
return (TRUE);
}
/*!
******************************************************************************
@Function InitPCIInterrupts
@Description This function sets up the thread that will respond to hardware
interrupts, and configures the card to generate interrupts on the
events we need.
@Input psSysData
@Input psDevInfo
@Return PVRSRV_ERROR
******************************************************************************/
static PVRSRV_ERROR InitPCIInterrupts(SYS_DATA *psSysData, PVRSRV_DEV_INFO *psDevInfo)
{
PVRSRV_ERROR eRetVal = PVRSRV_OK;
IMG_UINT32 ui32BytesReturned = 0;
IMG_BOOL bInstallIsr = FALSE;
HAL_TRANSLATE_IRQ_BUFFER sBuffer;
WCHAR szwIsrDll[DEVDLL_LEN];
WCHAR szwIsrHandler[DEVENTRY_LEN];
ENV_DATA *psEnvData = (ENV_DATA*)psSysData->pvEnvSpecificData;
/*
Bind the event and thread to the interrupt. First, map the PCI IRQ
to a system IRQ.
*/
sBuffer.ulInterruptNumber = psDevInfo->sPCI.ui32Irq;
sBuffer.ulInterruptVector = 0;
if (KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,/* was IOCTL_HAL_TRANSLATE_IRQ - not supported after v4.1+ */
&sBuffer,
sizeof(sBuffer),
&psEnvData->ui32TransIRQ,
sizeof(psEnvData->ui32TransIRQ),
&ui32BytesReturned))
{
PVR_ASSERT (ui32BytesReturned == sizeof(psEnvData->ui32TransIRQ));
/* Check registry - are we supporting shared PCI interrupts? */
if ((GetRegistryConfig(&bInstallIsr, szwIsrDll, szwIsrHandler) == ERROR_SUCCESS)
&& (bInstallIsr == TRUE))
{
/* Install ISR handler. */
psEnvData->hISRHandle = LoadIntChainHandler (szwIsrDll,
szwIsrHandler,
(BYTE)sBuffer.ulInterruptNumber);
if (!psEnvData->hISRHandle)
{
PVR_DPF((PVR_DBG_ERROR,"PlatformInitializeInterrupts: Couldn't install ISR handler."));
eRetVal = PVRSRV_ERROR_GENERIC;
goto Error;
}
else
{
IMG_PVOID pvPhysAddr = NULL;
IMG_UINT32 ui32InIoSpace = 0;
PHYSICAL_ADDRESS MemAddress = {psDevInfo->sDevLocation.sRegsPhysBase.uiAddr, 0};
if (!TransBusAddrToStatic(PCIBus, 0, MemAddress, sizeof(DWORD), &ui32InIoSpace, &pvPhysAddr))
{
PVR_DPF((PVR_DBG_ERROR,"PlatformInitializeInterrupts: Failed TransBusAddrToStatic."));
eRetVal = PVRSRV_ERROR_GENERIC;
goto Error;
}
/* FIXME: */
//if(system has a display device ISR)
{
/* FIXME: how should we get JDISPLAY_INT_STATUS */
if (SetupGIISR ((IMG_UINT32)pvPhysAddr + JDISPLAY_INT_STATUS,
psEnvData->ui32TransIRQ,
psEnvData->hISRHandle,
JDISPLAY_INTERRUPT_VBLANK) == FALSE)
{
PVR_DPF((PVR_DBG_ERROR,"PlatformInitializeInterrupts: error installing VSync Ist"));
eRetVal = PVRSRV_ERROR_GENERIC;
goto Error;
}
}
/* FIXME: */
//if(system has a 3D device ISR)
{
IMG_UINT32 ui32InitIntEnable = MBX1_INT_CMDPROC
| MBX1_INT_RENDER_COMPLETE
| MBX1_INT_EVM_DALLOC
| MBX1_INT_TA_COMPLETE
| MBX1_INT_TA_OFLOW
| MBX1_INT_2DSYNC
| MBX1_INT_MASTER;
/* FIXME: how should we get MBX1_GLOBREG_INT_STATUS */
if (SetupGIISR((DWORD)pvPhysAddr + MBX1_GLOBREG_INT_STATUS,
psEnvData->ui32TransIRQ,
psEnvData->hISRHandle,
ui32InitIntEnable) == FALSE)
{
PVR_DPF((PVR_DBG_ERROR,"PlatformInitializeInterrupts: error installing 3D Ist"));
eRetVal = PVRSRV_ERROR_GENERIC;
goto Error;
}
}
}
}
}
Error:
return(eRetVal);
}
/*!
******************************************************************************
@Function HostPCIReadDword
@Description reads PCI config registers
@Input ui32Bus : bus id
@Input ui32Dev : device id
@Input ui32Func : funct type
@Input ui32Reg : register
@Return register value
******************************************************************************/
DWORD HostPCIReadDword(DWORD dwBus, DWORD dwDev, DWORD dwFunc, DWORD dwReg)
{
PCI_SLOT_NUMBER sSlot;
DWORD pdwBuf[1];
sSlot.u.bits.DeviceNumber = dwDev;
sSlot.u.bits.FunctionNumber = dwFunc;
sSlot.u.bits.Reserved = 0;
HalGetBusDataByOffset( PCIConfiguration, dwBus, sSlot.u.AsULONG, pdwBuf, dwReg, 4 );
return pdwBuf[0];
}
/*!
******************************************************************************
@Function HostPCIWriteDword
@Description reads PCI config registers
@Input ui32Bus : bus id
@Input ui32Dev : device id
@Input ui32Func : funct type
@Input ui32Reg : register
@Input ui32Value : value to write
@Return none
******************************************************************************/
void HostPCIWriteDword(DWORD dwBus, DWORD dwDev, DWORD dwFunc, DWORD dwReg, DWORD dwValue)
{
PCI_SLOT_NUMBER sSlot;
DWORD pdwBuf[1];
sSlot.u.bits.DeviceNumber = dwDev;
sSlot.u.bits.FunctionNumber = dwFunc;
sSlot.u.bits.Reserved = 0;
pdwBuf[0] = dwValue;
HalSetBusDataByOffset(PCIConfiguration, dwBus, sSlot.u.AsULONG, pdwBuf, dwReg, 4);
}
#endif /* SUPPORT_PCI */
/*!
******************************************************************************
@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;
}
/*!
******************************************************************************
@Function HostNoResManOnThisProcess
@Description
Checks if GWES is calling process if so returns true
@Input ui32ProcessID :
@Return IMG_BOOL :
******************************************************************************/
IMG_BOOL HostNoResManOnThisProcess(IMG_UINT32 ui32ProcessID)
{
HANDLE hProcTable;
PROCESSENTRY32 sProcEntry;
TCHAR *pszGWES = TEXT("gwes.exe");
TCHAR *ptszFileName;
IMG_BOOL bRetVal;
/* Get details of the current processes */
hProcTable = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcTable == INVALID_HANDLE_VALUE)
{
PVR_DPF((PVR_DBG_ERROR, "HostNoResManOnThisProcess: Couldn't obtain process table"));
return IMG_FALSE;
}
/* Get the first process */
sProcEntry.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(hProcTable, &sProcEntry))
{
PVR_DPF((PVR_DBG_ERROR, "HostNoResManOnThisProcess: Couldn't read the first process entry"));
CloseToolhelp32Snapshot(hProcTable);
return IMG_FALSE;
}
while(sProcEntry.th32ProcessID != ui32ProcessID)
{
if(!Process32Next(hProcTable, &sProcEntry))
{
PVR_DPF((PVR_DBG_ERROR, "HostNoResManOnThisProcess: Can't find current process in process table"));
CloseToolhelp32Snapshot(hProcTable);
return IMG_FALSE;
}
}
/* Extract the file name */
ptszFileName = _tcsrchr(sProcEntry.szExeFile, _T('\\'));
if(ptszFileName)
{
ptszFileName++;
}
else
{
ptszFileName = sProcEntry.szExeFile;
}
/* Test if this is GWES process */
if(_tcsicmp(pszGWES, ptszFileName) == 0)
{
bRetVal = IMG_TRUE;
}
else
{
bRetVal = IMG_FALSE;
}
CloseToolhelp32Snapshot(hProcTable);
return bRetVal;
}
/*****************************************************************************
End of file (hostfunc.c)
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -