IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick) #endif { PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo; SGXMKIF_COMMAND sCommand = {0}; SGXMKIF_TRANSFERCMD_SHARED *psSharedTransferCmd; PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; PVRSRV_ERROR eError; IMG_UINT32 loop; IMG_HANDLE hDevMemContext = IMG_NULL; IMG_BOOL abSrcSyncEnable[SGX_MAX_TRANSFER_SYNC_OPS]; IMG_UINT32 ui32RealSrcSyncNum = 0; IMG_BOOL abDstSyncEnable[SGX_MAX_TRANSFER_SYNC_OPS]; IMG_UINT32 ui32RealDstSyncNum = 0; #if defined(PDUMP) IMG_BOOL bPersistentProcess = IMG_FALSE; /* * For persistent processes, the HW kicks should not go into the * extended init phase; only keep memory transactions from the * window system which are necessary to run the client app. */ { PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); if(psPerProc != IMG_NULL) { bPersistentProcess = psPerProc->bPDumpPersistent; } } #endif /* PDUMP */ #if defined(FIX_HW_BRN_31620) hDevMemContext = psKick->hDevMemContext; #endif PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_ENTER, TRANSFER_TOKEN_SUBMIT); for (loop = 0; loop < SGX_MAX_TRANSFER_SYNC_OPS; loop++) { abSrcSyncEnable[loop] = IMG_TRUE; abDstSyncEnable[loop] = IMG_TRUE; } if (!CCB_OFFSET_IS_VALID(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset)) { PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: Invalid CCB offset")); PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, TRANSFER_TOKEN_SUBMIT); return PVRSRV_ERROR_INVALID_PARAMS; } /* override QAC warning about stricter alignment */ /* PRQA S 3305 1 */ psSharedTransferCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset); PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CMD_START, TRANSFER_TOKEN_SUBMIT); PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CCB, TRANSFER_TOKEN_CCB_OFFSET, psKick->ui32SharedCmdCCBOffset); if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_TA_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psSharedTransferCmd->ui32TASyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; psSharedTransferCmd->ui32TASyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } else { psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0; psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_3D_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psSharedTransferCmd->ui323DSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; psSharedTransferCmd->ui323DSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } else { psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0; psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0; } /* filter out multiple occurrences of the same sync object from srcs or dests * note : the same sync can still be used to synchronize both src and dst. */ for (loop = 0; loop < MIN(SGX_MAX_TRANSFER_SYNC_OPS, psKick->ui32NumSrcSync); loop++) { IMG_UINT32 i; PVRSRV_KERNEL_SYNC_INFO * psMySyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; for (i = 0; i < loop; i++) { if (abSrcSyncEnable[i]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i]; if (psSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr == psMySyncInfo->sWriteOpsCompleteDevVAddr.uiAddr) { PVR_DPF((PVR_DBG_WARNING, "SGXSubmitTransferKM : Same src synchronized multiple times!")); abSrcSyncEnable[loop] = IMG_FALSE; break; } } } if (abSrcSyncEnable[loop]) { ui32RealSrcSyncNum++; } } for (loop = 0; loop < MIN(SGX_MAX_TRANSFER_SYNC_OPS, psKick->ui32NumDstSync); loop++) { IMG_UINT32 i; PVRSRV_KERNEL_SYNC_INFO * psMySyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; for (i = 0; i < loop; i++) { if (abDstSyncEnable[i]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[i]; if (psSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr == psMySyncInfo->sWriteOpsCompleteDevVAddr.uiAddr) { PVR_DPF((PVR_DBG_WARNING, "SGXSubmitTransferKM : Same dst synchronized multiple times!")); abDstSyncEnable[loop] = IMG_FALSE; break; } } } if (abDstSyncEnable[loop]) { ui32RealDstSyncNum++; } } psSharedTransferCmd->ui32NumSrcSyncs = ui32RealSrcSyncNum; psSharedTransferCmd->ui32NumDstSyncs = ui32RealDstSyncNum; if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) { IMG_UINT32 i = 0; for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_SRC_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psSharedTransferCmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; psSharedTransferCmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; i++; } } PVR_ASSERT(i == ui32RealSrcSyncNum); i = 0; for (loop = 0; loop < psKick->ui32NumDstSync; loop++) { if (abDstSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; psSyncInfo->psSyncData->ui64LastWrite = ui64KickCount; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_DST_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psSharedTransferCmd->asDstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; psSharedTransferCmd->asDstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->asDstSyncs[i].ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending; psSharedTransferCmd->asDstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->asDstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psSharedTransferCmd->asDstSyncs[i].sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr; i++; } } PVR_ASSERT(i == ui32RealDstSyncNum); /* * We allow source and destination sync objects to be the * same, which is why the read/write pending updates are delayed * until the transfer command has been updated with the current * values from the objects. */ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; psSyncInfo->psSyncData->ui32ReadOpsPending++; } } for (loop = 0; loop < psKick->ui32NumDstSync; loop++) { if (abDstSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; psSyncInfo->psSyncData->ui32WriteOpsPending++; } } } #if defined(PDUMP) if ((PDumpIsCaptureFrameKM() || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) && (bPersistentProcess == IMG_FALSE) ) { PDUMPCOMMENT("Shared part of transfer command\r\n"); PDUMPMEM(psSharedTransferCmd, psCCBMemInfo, psKick->ui32CCBDumpWOff, sizeof(SGXMKIF_TRANSFERCMD_SHARED), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) { IMG_UINT32 i = 0; for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = psKick->ahSrcSyncInfo[loop]; PDUMPCOMMENT("Tweak src surface write op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Tweak src surface read op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); i++; } } i = 0; for (loop = 0; loop < psKick->ui32NumDstSync; loop++) { if (abDstSyncEnable[i]) { IMG_UINT32 ui32PDumpReadOp2 = 0; psSyncInfo = psKick->ahDstSyncInfo[loop]; PDUMPCOMMENT("Tweak dest surface write op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Tweak dest surface read op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Tweak dest surface read op2 in transfer cmd\r\n"); PDUMPMEM(&ui32PDumpReadOp2, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOps2PendingVal)), sizeof(ui32PDumpReadOp2), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); i++; } } /* * We allow the first source and destination sync objects to be the * same, which is why the read/write pending updates are delayed * until the transfer command has been updated with the current * values from the objects. */ for (loop = 0; loop < (psKick->ui32NumSrcSync); loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; } } for (loop = 0; loop < (psKick->ui32NumDstSync); loop++) { if (abDstSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0]; psSyncInfo->psSyncData->ui32LastOpDumpVal++; } } } if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = psKick->hTASyncInfo; PDUMPCOMMENT("Tweak TA/TQ surface write op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32TASyncWriteOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); psSyncInfo->psSyncData->ui32LastOpDumpVal++; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = psKick->h3DSyncInfo; PDUMPCOMMENT("Tweak 3D/TQ surface write op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui323DSyncWriteOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); psSyncInfo->psSyncData->ui32LastOpDumpVal++; } } #endif sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr; PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CMD_END, TRANSFER_TOKEN_SUBMIT); eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TRANSFER, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags, hDevMemContext, IMG_FALSE); if (eError == PVRSRV_ERROR_RETRY) { /* Client will retry, so undo the sync ops pending increment(s) done above. */ if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) { for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; psSyncInfo->psSyncData->ui32ReadOpsPending--; #if defined(PDUMP) if (PDumpIsCaptureFrameKM() || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) { psSyncInfo->psSyncData->ui32LastReadOpDumpVal--; } #endif } } for (loop = 0; loop < psKick->ui32NumDstSync; loop++) { if (abDstSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; psSyncInfo->psSyncData->ui32WriteOpsPending--; #if defined(PDUMP) if (PDumpIsCaptureFrameKM() || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) { psSyncInfo->psSyncData->ui32LastOpDumpVal--; } #endif } } } /* Command needed to be synchronised with the TA? */ if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } /* Command needed to be synchronised with the 3D? */ if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } } else if (PVRSRV_OK != eError) { PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: SGXScheduleCCBCommandKM failed.")); PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, TRANSFER_TOKEN_SUBMIT); return eError; } #if defined(NO_HARDWARE) if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE) == 0) { /* Update sync objects pretending that we have done the job*/ for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } } for (loop = 0; loop < psKick->ui32NumDstSync; loop++) { if (abDstSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } } if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } } #endif PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, TRANSFER_TOKEN_SUBMIT); return eError; }
PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo) #endif { SYS_DATA *psSysData; if(!psMiscInfo) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters")); return PVRSRV_ERROR_INVALID_PARAMS; } psMiscInfo->ui32StatePresent = 0; if(psMiscInfo->ui32StateRequest & ~(PVRSRV_MISC_INFO_TIMER_PRESENT |PVRSRV_MISC_INFO_CLOCKGATE_PRESENT |PVRSRV_MISC_INFO_MEMSTATS_PRESENT |PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT |PVRSRV_MISC_INFO_DDKVERSION_PRESENT |PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT |PVRSRV_MISC_INFO_RESET_PRESENT |PVRSRV_MISC_INFO_FREEMEM_PRESENT)) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags")); return PVRSRV_ERROR_INVALID_PARAMS; } SysAcquireData(&psSysData); if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_TIMER_PRESENT) != 0UL) && (psSysData->pvSOCTimerRegisterKM != IMG_NULL)) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_TIMER_PRESENT; psMiscInfo->pvSOCTimerRegisterKM = psSysData->pvSOCTimerRegisterKM; psMiscInfo->hSOCTimerRegisterOSMemHandle = psSysData->hSOCTimerRegisterOSMemHandle; } else { psMiscInfo->pvSOCTimerRegisterKM = IMG_NULL; psMiscInfo->hSOCTimerRegisterOSMemHandle = IMG_NULL; } if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CLOCKGATE_PRESENT) != 0UL) && (psSysData->pvSOCClockGateRegsBase != IMG_NULL)) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CLOCKGATE_PRESENT; psMiscInfo->pvSOCClockGateRegs = psSysData->pvSOCClockGateRegsBase; psMiscInfo->ui32SOCClockGateRegsSize = psSysData->ui32SOCClockGateRegsSize; } if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0UL) && (psMiscInfo->pszMemoryStr != IMG_NULL)) { RA_ARENA **ppArena; IMG_CHAR *pszStr; IMG_UINT32 ui32StrLen; IMG_INT32 i32Count; pszStr = psMiscInfo->pszMemoryStr; ui32StrLen = psMiscInfo->ui32MemoryStrLen; psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_MEMSTATS_PRESENT; ppArena = &psSysData->apsLocalDevMemArena[0]; while(*ppArena) { CHECK_SPACE(ui32StrLen); i32Count = OSSNPrintf(pszStr, 100, "\nLocal Backing Store:\n"); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); RA_GetStats(*ppArena, &pszStr, &ui32StrLen); ppArena++; } List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList, &PVRSRVGetMiscInfoKM_Device_AnyVaCb, &ui32StrLen, &i32Count, &pszStr, PVRSRV_MISC_INFO_MEMSTATS_PRESENT); i32Count = OSSNPrintf(pszStr, 100, "\n"); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); } if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0) && psMiscInfo->pszMemoryStr) { IMG_CHAR *pszStr; IMG_UINT32 ui32StrLen; IMG_INT32 i32Count; pszStr = psMiscInfo->pszMemoryStr; ui32StrLen = psMiscInfo->ui32MemoryStrLen; psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FREEMEM_PRESENT; List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList, &PVRSRVGetMiscInfoKM_Device_AnyVaCb, &ui32StrLen, &i32Count, &pszStr, PVRSRV_MISC_INFO_FREEMEM_PRESENT); i32Count = OSSNPrintf(pszStr, 100, "\n"); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); } if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) != 0UL) && (psSysData->psGlobalEventObject != IMG_NULL)) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT; psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject; } if (((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0UL) && ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) == 0UL) && (psMiscInfo->pszMemoryStr != IMG_NULL)) { IMG_CHAR *pszStr; IMG_UINT32 ui32StrLen; IMG_UINT32 ui32LenStrPerNum = 12; IMG_INT32 i32Count; IMG_INT i; psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT; psMiscInfo->aui32DDKVersion[0] = PVRVERSION_MAJ; psMiscInfo->aui32DDKVersion[1] = PVRVERSION_MIN; psMiscInfo->aui32DDKVersion[2] = PVRVERSION_BRANCH; psMiscInfo->aui32DDKVersion[3] = PVRVERSION_BUILD; pszStr = psMiscInfo->pszMemoryStr; ui32StrLen = psMiscInfo->ui32MemoryStrLen; for (i=0; i<4; i++) { if (ui32StrLen < ui32LenStrPerNum) { return PVRSRV_ERROR_INVALID_PARAMS; } i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%u", psMiscInfo->aui32DDKVersion[i]); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); if (i != 3) { i32Count = OSSNPrintf(pszStr, 2, "."); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); } } } if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT) != 0UL) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT; if(psMiscInfo->sCacheOpCtl.bDeferOp) { psSysData->ePendingCacheOpType = psMiscInfo->sCacheOpCtl.eCacheOpType; } else { #if defined (SUPPORT_SID_INTERFACE) PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = psMiscInfo->sCacheOpCtl.psKernelMemInfo; if(!psMiscInfo->sCacheOpCtl.psKernelMemInfo) #else PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; PVRSRV_PER_PROCESS_DATA *psPerProc; if(!psMiscInfo->sCacheOpCtl.u.psKernelMemInfo) #endif { PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: " "Ignoring non-deferred cache op with no meminfo")); return PVRSRV_ERROR_INVALID_PARAMS; } if(psSysData->ePendingCacheOpType != PVRSRV_MISC_INFO_CPUCACHEOP_NONE) { PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: " "Deferred cache op is pending. It is unlikely you want " "to combine deferred cache ops with immediate ones")); } #if defined (SUPPORT_SID_INTERFACE) PVR_DBG_BREAK #else psPerProc = PVRSRVFindPerProcessData(); if(PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_PVOID *)&psKernelMemInfo, psMiscInfo->sCacheOpCtl.u.psKernelMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: " "Can't find kernel meminfo")); return PVRSRV_ERROR_INVALID_PARAMS; } #endif if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH) { if(!OSFlushCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle, psMiscInfo->sCacheOpCtl.pvBaseVAddr, psMiscInfo->sCacheOpCtl.ui32Length)) { return PVRSRV_ERROR_CACHEOP_FAILED; } } else if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN) { if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle, psMiscInfo->sCacheOpCtl.pvBaseVAddr, psMiscInfo->sCacheOpCtl.ui32Length)) { return PVRSRV_ERROR_CACHEOP_FAILED; } } /* FIXME: Temporary fix needs to be revisited * LinuxMemArea struct listing is not registered for memory areas * wrapped through PVR2DMemWrap() call. For now, we are doing * cache flush/inv by grabbing the physical pages through * get_user_pages() for every blt call. */ else if (psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CUSTOM_FLUSH) { #if defined(CONFIG_OUTER_CACHE) && defined(PVR_NO_FULL_CACHE_OPS) if (1) { IMG_SIZE_T uPageOffset, uPageCount; IMG_VOID *pvPageAlignedCPUVAddr; IMG_SYS_PHYADDR *psIntSysPAddr = IMG_NULL; IMG_HANDLE hOSWrapMem = IMG_NULL; PVRSRV_ERROR eError; int i; uPageOffset = (IMG_UINTPTR_T)psMiscInfo->sCacheOpCtl.pvBaseVAddr & (HOST_PAGESIZE() - 1); uPageCount = HOST_PAGEALIGN(psMiscInfo->sCacheOpCtl.ui32Length + uPageOffset)/HOST_PAGESIZE(); pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psMiscInfo->sCacheOpCtl.pvBaseVAddr - uPageOffset); if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, uPageCount * sizeof(IMG_SYS_PHYADDR), (IMG_VOID **)&psIntSysPAddr, IMG_NULL, "Array of Page Addresses") != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block")); return PVRSRV_ERROR_OUT_OF_MEMORY; } eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr, uPageCount * HOST_PAGESIZE(), psIntSysPAddr, &hOSWrapMem); for (i = 0; i < uPageCount; i++) { outer_flush_range(psIntSysPAddr[i].uiAddr, psIntSysPAddr[i].uiAddr + HOST_PAGESIZE() -1); } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, uPageCount * sizeof(IMG_SYS_PHYADDR), psIntSysPAddr, IMG_NULL); OSReleasePhysPageAddr(hOSWrapMem); } #else OSFlushCPUCacheKM(); #endif /* CONFIG_OUTER_CACHE && PVR_NO_FULL_CACHE_OPS*/ } else if (psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CUSTOM_INV) { #if defined(CONFIG_OUTER_CACHE) /* TODO: Need to check full cache invalidation, but * currently it is not exported through * outer_cache interface. */ if (1) { IMG_SIZE_T uPageOffset, uPageCount; IMG_VOID *pvPageAlignedCPUVAddr; IMG_SYS_PHYADDR *psIntSysPAddr = IMG_NULL; IMG_HANDLE hOSWrapMem = IMG_NULL; PVRSRV_ERROR eError; int i; uPageOffset = (IMG_UINTPTR_T)psMiscInfo->sCacheOpCtl.pvBaseVAddr & (HOST_PAGESIZE() - 1); uPageCount = HOST_PAGEALIGN(psMiscInfo->sCacheOpCtl.ui32Length + uPageOffset)/HOST_PAGESIZE(); pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psMiscInfo->sCacheOpCtl.pvBaseVAddr - uPageOffset); if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, uPageCount * sizeof(IMG_SYS_PHYADDR), (IMG_VOID **)&psIntSysPAddr, IMG_NULL, "Array of Page Addresses") != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block")); return PVRSRV_ERROR_OUT_OF_MEMORY; } eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr, uPageCount * HOST_PAGESIZE(), psIntSysPAddr, &hOSWrapMem); for (i = 0; i < uPageCount; i++) { outer_inv_range(psIntSysPAddr[i].uiAddr, psIntSysPAddr[i].uiAddr + HOST_PAGESIZE() -1); } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, uPageCount * sizeof(IMG_SYS_PHYADDR), psIntSysPAddr, IMG_NULL); OSReleasePhysPageAddr(hOSWrapMem); } #endif /* CONFIG_OUTER_CACHE */ } } } #if defined(PVRSRV_RESET_ON_HWTIMEOUT) if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_RESET_PRESENT) != 0UL) { PVR_LOG(("User requested OS reset")); OSPanic(); } #endif return PVRSRV_OK; }
PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo) #endif { SYS_DATA *psSysData; if(!psMiscInfo) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters")); return PVRSRV_ERROR_INVALID_PARAMS; } psMiscInfo->ui32StatePresent = 0; if(psMiscInfo->ui32StateRequest & ~(PVRSRV_MISC_INFO_TIMER_PRESENT |PVRSRV_MISC_INFO_CLOCKGATE_PRESENT |PVRSRV_MISC_INFO_MEMSTATS_PRESENT |PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT |PVRSRV_MISC_INFO_DDKVERSION_PRESENT |PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT |PVRSRV_MISC_INFO_RESET_PRESENT |PVRSRV_MISC_INFO_FREEMEM_PRESENT |PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT)) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags")); return PVRSRV_ERROR_INVALID_PARAMS; } SysAcquireData(&psSysData); if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_TIMER_PRESENT) != 0UL) && (psSysData->pvSOCTimerRegisterKM != IMG_NULL)) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_TIMER_PRESENT; psMiscInfo->pvSOCTimerRegisterKM = psSysData->pvSOCTimerRegisterKM; psMiscInfo->hSOCTimerRegisterOSMemHandle = psSysData->hSOCTimerRegisterOSMemHandle; } else { psMiscInfo->pvSOCTimerRegisterKM = IMG_NULL; psMiscInfo->hSOCTimerRegisterOSMemHandle = IMG_NULL; } if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CLOCKGATE_PRESENT) != 0UL) && (psSysData->pvSOCClockGateRegsBase != IMG_NULL)) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CLOCKGATE_PRESENT; psMiscInfo->pvSOCClockGateRegs = psSysData->pvSOCClockGateRegsBase; psMiscInfo->ui32SOCClockGateRegsSize = psSysData->ui32SOCClockGateRegsSize; } if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0UL) && (psMiscInfo->pszMemoryStr != IMG_NULL)) { RA_ARENA **ppArena; IMG_CHAR *pszStr; IMG_UINT32 ui32StrLen; IMG_INT32 i32Count; pszStr = psMiscInfo->pszMemoryStr; ui32StrLen = psMiscInfo->ui32MemoryStrLen; psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_MEMSTATS_PRESENT; ppArena = &psSysData->apsLocalDevMemArena[0]; while(*ppArena) { CHECK_SPACE(ui32StrLen); i32Count = OSSNPrintf(pszStr, 100, "\nLocal Backing Store:\n"); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); RA_GetStats(*ppArena, &pszStr, &ui32StrLen); ppArena++; } List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList, &PVRSRVGetMiscInfoKM_Device_AnyVaCb, &ui32StrLen, &i32Count, &pszStr, PVRSRV_MISC_INFO_MEMSTATS_PRESENT); i32Count = OSSNPrintf(pszStr, 100, "\n"); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); } if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0) && psMiscInfo->pszMemoryStr) { IMG_CHAR *pszStr; IMG_UINT32 ui32StrLen; IMG_INT32 i32Count; pszStr = psMiscInfo->pszMemoryStr; ui32StrLen = psMiscInfo->ui32MemoryStrLen; psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FREEMEM_PRESENT; List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList, &PVRSRVGetMiscInfoKM_Device_AnyVaCb, &ui32StrLen, &i32Count, &pszStr, PVRSRV_MISC_INFO_FREEMEM_PRESENT); i32Count = OSSNPrintf(pszStr, 100, "\n"); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); } if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) != 0UL) && (psSysData->psGlobalEventObject != IMG_NULL)) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT; psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject; } if (((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0UL) && ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) == 0UL) && (psMiscInfo->pszMemoryStr != IMG_NULL)) { IMG_CHAR *pszStr; IMG_UINT32 ui32StrLen; IMG_UINT32 ui32LenStrPerNum = 12; IMG_INT32 i32Count; IMG_INT i; psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT; psMiscInfo->aui32DDKVersion[0] = PVRVERSION_MAJ; psMiscInfo->aui32DDKVersion[1] = PVRVERSION_MIN; psMiscInfo->aui32DDKVersion[2] = PVRVERSION_BUILD_HI; psMiscInfo->aui32DDKVersion[3] = PVRVERSION_BUILD_LO; pszStr = psMiscInfo->pszMemoryStr; ui32StrLen = psMiscInfo->ui32MemoryStrLen; for (i=0; i<4; i++) { if (ui32StrLen < ui32LenStrPerNum) { return PVRSRV_ERROR_INVALID_PARAMS; } i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%u", psMiscInfo->aui32DDKVersion[i]); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); if (i != 3) { i32Count = OSSNPrintf(pszStr, 2, "."); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); } } } if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT) != 0UL) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT; if(psMiscInfo->sCacheOpCtl.bDeferOp) { psSysData->ePendingCacheOpType = psMiscInfo->sCacheOpCtl.eCacheOpType; } else { #if defined (SUPPORT_SID_INTERFACE) PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = psMiscInfo->sCacheOpCtl.psKernelMemInfo; if(!psMiscInfo->sCacheOpCtl.psKernelMemInfo) #else PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; PVRSRV_PER_PROCESS_DATA *psPerProc; if(!psMiscInfo->sCacheOpCtl.u.psKernelMemInfo) #endif { PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: " "Ignoring non-deferred cache op with no meminfo")); return PVRSRV_ERROR_INVALID_PARAMS; } if(psSysData->ePendingCacheOpType != PVRSRV_MISC_INFO_CPUCACHEOP_NONE) { PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: " "Deferred cache op is pending. It is unlikely you want " "to combine deferred cache ops with immediate ones")); } #if defined (SUPPORT_SID_INTERFACE) PVR_DBG_BREAK #else psPerProc = PVRSRVFindPerProcessData(); if(PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_PVOID *)&psKernelMemInfo, psMiscInfo->sCacheOpCtl.u.psKernelMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: " "Can't find kernel meminfo")); return PVRSRV_ERROR_INVALID_PARAMS; } #endif if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH) { if(!OSFlushCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle, psMiscInfo->sCacheOpCtl.pvBaseVAddr, psMiscInfo->sCacheOpCtl.ui32Length)) { return PVRSRV_ERROR_CACHEOP_FAILED; } } else if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN) { /*if(psMiscInfo->sCacheOpCtl.bStridedCacheOp == IMG_TRUE) { IMG_BYTE *pbRowStart, *pbRowEnd, *pbRowThresh; IMG_UINT32 ui32Stride; pbRowStart = psMiscInfo->sCacheOpCtl.pbRowStart; pbRowEnd = psMiscInfo->sCacheOpCtl.pbRowEnd; pbRowThresh = psMiscInfo->sCacheOpCtl.pbRowThresh; ui32Stride = psMiscInfo->sCacheOpCtl.ui32Stride; do { if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle, (IMG_VOID *)pbRowStart, (IMG_UINT32)(pbRowEnd - pbRowStart))) { return PVRSRV_ERROR_CACHEOP_FAILED; } pbRowStart += ui32Stride; pbRowEnd += ui32Stride; } while(pbRowEnd <= pbRowThresh); } else { if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle, psMiscInfo->sCacheOpCtl.pvBaseVAddr, psMiscInfo->sCacheOpCtl.ui32Length)) { return PVRSRV_ERROR_CACHEOP_FAILED; } }*/ if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle, psMiscInfo->sCacheOpCtl.pvBaseVAddr, psMiscInfo->sCacheOpCtl.ui32Length)) return PVRSRV_ERROR_CACHEOP_FAILED; } } } if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT) != 0UL) { #if !defined (SUPPORT_SID_INTERFACE) PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; PVRSRV_PER_PROCESS_DATA *psPerProc; #endif psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT; #if defined (SUPPORT_SID_INTERFACE) PVR_DBG_BREAK #else psPerProc = PVRSRVFindPerProcessData(); if(PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_PVOID *)&psKernelMemInfo, psMiscInfo->sGetRefCountCtl.u.psKernelMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: " "Can't find kernel meminfo")); return PVRSRV_ERROR_INVALID_PARAMS; } psMiscInfo->sGetRefCountCtl.ui32RefCount = psKernelMemInfo->ui32RefCount; #endif } #if defined(PVRSRV_RESET_ON_HWTIMEOUT) if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_RESET_PRESENT) != 0UL) { PVR_LOG(("User requested OS reset")); OSPanic(); } #endif return PVRSRV_OK; }
IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick) #endif { PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo; SGXMKIF_COMMAND sCommand = {0}; SGXMKIF_2DCMD_SHARED *ps2DCmd; PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; PVRSRV_ERROR eError; IMG_UINT32 i; IMG_HANDLE hDevMemContext = IMG_NULL; #if defined(PDUMP) IMG_BOOL bPersistentProcess = IMG_FALSE; /* * For persistent processes, the HW kicks should not go into the * extended init phase; only keep memory transactions from the * window system which are necessary to run the client app. */ { PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); if(psPerProc != IMG_NULL) { bPersistentProcess = psPerProc->bPDumpPersistent; } } #endif /* PDUMP */ #if defined(FIX_HW_BRN_31620) hDevMemContext = psKick->hDevMemContext; #endif if (!CCB_OFFSET_IS_VALID(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset)) { PVR_DPF((PVR_DBG_ERROR, "SGXSubmit2DKM: Invalid CCB offset")); return PVRSRV_ERROR_INVALID_PARAMS; } /* override QAC warning about stricter alignment */ /* PRQA S 3305 1 */ ps2DCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset); OSMemSet(ps2DCmd, 0, sizeof(*ps2DCmd)); /* Command needs to be synchronised with the TA? */ if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; ps2DCmd->sTASyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; ps2DCmd->sTASyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ps2DCmd->sTASyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ps2DCmd->sTASyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } /* Command needs to be synchronised with the 3D? */ if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; ps2DCmd->s3DSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; ps2DCmd->s3DSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ps2DCmd->s3DSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ps2DCmd->s3DSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } /* * We allow the first source and destination sync objects to be the * same, which is why the read/write pending updates are delayed * until the transfer command has been updated with the current * values from the objects. */ ps2DCmd->ui32NumSrcSync = psKick->ui32NumSrcSync; for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; ps2DCmd->sSrcSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; ps2DCmd->sSrcSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ps2DCmd->sSrcSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ps2DCmd->sSrcSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = psKick->hDstSyncInfo; ps2DCmd->sDstSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; ps2DCmd->sDstSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ps2DCmd->sDstSyncData.ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending; ps2DCmd->sDstSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ps2DCmd->sDstSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ps2DCmd->sDstSyncData.sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr; } /* Read/Write ops pending updates, delayed from above */ for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending++; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = psKick->hDstSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending++; } #if defined(PDUMP) if ((PDumpIsCaptureFrameKM() || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) && (bPersistentProcess == IMG_FALSE) ) { /* Pdump the command from the per context CCB */ PDUMPCOMMENT("Shared part of 2D command\r\n"); PDUMPMEM(ps2DCmd, psCCBMemInfo, psKick->ui32CCBDumpWOff, sizeof(SGXMKIF_2DCMD_SHARED), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; PDUMPCOMMENT("Tweak src surface write op in 2D cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32WriteOpsPendingVal), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Tweak src surface read op in 2D cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32ReadOpsPendingVal), sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); } if (psKick->hDstSyncInfo != IMG_NULL) { IMG_UINT32 ui32PDumpReadOp2 = 0; psSyncInfo = psKick->hDstSyncInfo; PDUMPCOMMENT("Tweak dest surface write op in 2D cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32WriteOpsPendingVal), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Tweak dest surface read op in 2D cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOpsPendingVal), sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Tweak dest surface read op2 in 2D cmd\r\n"); PDUMPMEM(&ui32PDumpReadOp2, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOps2PendingVal), sizeof(ui32PDumpReadOp2), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); } /* Read/Write ops pending updates, delayed from above */ for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = psKick->hDstSyncInfo; psSyncInfo->psSyncData->ui32LastOpDumpVal++; } } #endif sCommand.ui32Data[1] = psKick->sHW2DContextDevVAddr.uiAddr; eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_2D, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags, hDevMemContext, IMG_FALSE); if (eError == PVRSRV_ERROR_RETRY) { /* Client will retry, so undo the write ops pending increment done above. */ #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32LastReadOpDumpVal--; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = psKick->hDstSyncInfo; psSyncInfo->psSyncData->ui32LastOpDumpVal--; } } #endif for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending--; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = psKick->hDstSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } /* Command needed to be synchronised with the TA? */ if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } /* Command needed to be synchronised with the 3D? */ if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } } #if defined(NO_HARDWARE) /* Update sync objects pretending that we have done the job*/ for(i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hDstSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } #endif return eError; }
IMG_EXPORT PVRSRV_ERROR SGXSubmit2DKM(IMG_HANDLE hDevHandle, PVRSRV_2D_SGX_KICK *psKick) #endif { PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo; SGXMKIF_COMMAND sCommand = {0}; SGXMKIF_2DCMD_SHARED *ps2DCmd; PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; PVRSRV_ERROR eError; IMG_UINT32 i; IMG_HANDLE hDevMemContext = IMG_NULL; #if defined(PDUMP) IMG_BOOL bPersistentProcess = IMG_FALSE; { PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); if(psPerProc != IMG_NULL) { bPersistentProcess = psPerProc->bPDumpPersistent; } } #endif #if defined(FIX_HW_BRN_31620) hDevMemContext = psKick->hDevMemContext; #endif if (!CCB_OFFSET_IS_VALID(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset)) { PVR_DPF((PVR_DBG_ERROR, "SGXSubmit2DKM: Invalid CCB offset")); return PVRSRV_ERROR_INVALID_PARAMS; } ps2DCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_2DCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset); OSMemSet(ps2DCmd, 0, sizeof(*ps2DCmd)); if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; ps2DCmd->sTASyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; ps2DCmd->sTASyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ps2DCmd->sTASyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ps2DCmd->sTASyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; ps2DCmd->s3DSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; ps2DCmd->s3DSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ps2DCmd->s3DSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ps2DCmd->s3DSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } ps2DCmd->ui32NumSrcSync = psKick->ui32NumSrcSync; for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; ps2DCmd->sSrcSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; ps2DCmd->sSrcSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ps2DCmd->sSrcSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ps2DCmd->sSrcSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = psKick->hDstSyncInfo; ps2DCmd->sDstSyncData.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; ps2DCmd->sDstSyncData.ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; ps2DCmd->sDstSyncData.ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending; ps2DCmd->sDstSyncData.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; ps2DCmd->sDstSyncData.sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; ps2DCmd->sDstSyncData.sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr; } for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending++; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = psKick->hDstSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending++; } #if defined(PDUMP) if ((PDumpIsCaptureFrameKM() || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) && (bPersistentProcess == IMG_FALSE) ) { PDUMPCOMMENT("Shared part of 2D command\r\n"); PDUMPMEM(ps2DCmd, psCCBMemInfo, psKick->ui32CCBDumpWOff, sizeof(SGXMKIF_2DCMD_SHARED), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; PDUMPCOMMENT("Hack src surface write op in 2D cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32WriteOpsPendingVal), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Hack src surface read op in 2D cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sSrcSyncData[i].ui32ReadOpsPendingVal), sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); } if (psKick->hDstSyncInfo != IMG_NULL) { IMG_UINT32 ui32PDumpReadOp2 = 0; psSyncInfo = psKick->hDstSyncInfo; PDUMPCOMMENT("Hack dest surface write op in 2D cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32WriteOpsPendingVal), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Hack dest surface read op in 2D cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOpsPendingVal), sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Hack dest surface read op2 in 2D cmd\r\n"); PDUMPMEM(&ui32PDumpReadOp2, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_2DCMD_SHARED, sDstSyncData.ui32ReadOps2PendingVal), sizeof(ui32PDumpReadOp2), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); } for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = psKick->hDstSyncInfo; psSyncInfo->psSyncData->ui32LastOpDumpVal++; } } #endif sCommand.ui32Data[1] = psKick->sHW2DContextDevVAddr.uiAddr; eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_2D, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags, hDevMemContext, IMG_FALSE); if (eError == PVRSRV_ERROR_RETRY) { #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32LastReadOpDumpVal--; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = psKick->hDstSyncInfo; psSyncInfo->psSyncData->ui32LastOpDumpVal--; } } #endif for (i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending--; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = psKick->hDstSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } } #if defined(NO_HARDWARE) for(i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } if (psKick->hDstSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hDstSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } #endif return eError; }
IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick) #endif { PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo; SGXMKIF_COMMAND sCommand = {0}; SGXMKIF_TRANSFERCMD_SHARED *psSharedTransferCmd; PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; PVRSRV_ERROR eError; IMG_UINT32 loop; IMG_HANDLE hDevMemContext = IMG_NULL; IMG_BOOL abSrcSyncEnable[SGX_MAX_TRANSFER_SYNC_OPS]; IMG_UINT32 ui32RealSrcSyncNum = 0; IMG_BOOL abDstSyncEnable[SGX_MAX_TRANSFER_SYNC_OPS]; IMG_UINT32 ui32RealDstSyncNum = 0; #if defined(PDUMP) IMG_BOOL bPersistentProcess = IMG_FALSE; { PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); if(psPerProc != IMG_NULL) { bPersistentProcess = psPerProc->bPDumpPersistent; } } #endif #if defined(FIX_HW_BRN_31620) hDevMemContext = psKick->hDevMemContext; #endif PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_ENTER, TRANSFER_TOKEN_SUBMIT); for (loop = 0; loop < SGX_MAX_TRANSFER_SYNC_OPS; loop++) { abSrcSyncEnable[loop] = IMG_TRUE; abDstSyncEnable[loop] = IMG_TRUE; } if (!CCB_OFFSET_IS_VALID(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset)) { PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: Invalid CCB offset")); PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, TRANSFER_TOKEN_SUBMIT); return PVRSRV_ERROR_INVALID_PARAMS; } psSharedTransferCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset); PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CMD_START, TRANSFER_TOKEN_SUBMIT); PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CCB, TRANSFER_TOKEN_CCB_OFFSET, psKick->ui32SharedCmdCCBOffset); if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_TA_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psSharedTransferCmd->ui32TASyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; psSharedTransferCmd->ui32TASyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } else { psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0; psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_3D_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psSharedTransferCmd->ui323DSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; psSharedTransferCmd->ui323DSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } else { psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0; psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0; } for (loop = 0; loop < MIN(SGX_MAX_TRANSFER_SYNC_OPS, psKick->ui32NumSrcSync); loop++) { IMG_UINT32 i; PVRSRV_KERNEL_SYNC_INFO * psMySyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; for (i = 0; i < loop; i++) { if (abSrcSyncEnable[i]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i]; if (psSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr == psMySyncInfo->sWriteOpsCompleteDevVAddr.uiAddr) { PVR_DPF((PVR_DBG_WARNING, "SGXSubmitTransferKM : Same src synchronized multiple times!")); abSrcSyncEnable[loop] = IMG_FALSE; break; } } } if (abSrcSyncEnable[loop]) { ui32RealSrcSyncNum++; } } for (loop = 0; loop < MIN(SGX_MAX_TRANSFER_SYNC_OPS, psKick->ui32NumDstSync); loop++) { IMG_UINT32 i; PVRSRV_KERNEL_SYNC_INFO * psMySyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; for (i = 0; i < loop; i++) { if (abDstSyncEnable[i]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[i]; if (psSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr == psMySyncInfo->sWriteOpsCompleteDevVAddr.uiAddr) { PVR_DPF((PVR_DBG_WARNING, "SGXSubmitTransferKM : Same dst synchronized multiple times!")); abDstSyncEnable[loop] = IMG_FALSE; break; } } } if (abDstSyncEnable[loop]) { ui32RealDstSyncNum++; } } psSharedTransferCmd->ui32NumSrcSyncs = ui32RealSrcSyncNum; psSharedTransferCmd->ui32NumDstSyncs = ui32RealDstSyncNum; if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) { IMG_UINT32 i = 0; for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_SRC_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psSharedTransferCmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; psSharedTransferCmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; i++; } } PVR_ASSERT(i == ui32RealSrcSyncNum); i = 0; for (loop = 0; loop < psKick->ui32NumDstSync; loop++) { if (abDstSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; psSyncInfo->psSyncData->ui64LastWrite = ui64KickCount; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_TRANSFER, TRANSFER_TOKEN_DST_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psSharedTransferCmd->asDstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; psSharedTransferCmd->asDstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->asDstSyncs[i].ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending; psSharedTransferCmd->asDstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->asDstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psSharedTransferCmd->asDstSyncs[i].sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr; i++; } } PVR_ASSERT(i == ui32RealDstSyncNum); for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; psSyncInfo->psSyncData->ui32ReadOpsPending++; } } for (loop = 0; loop < psKick->ui32NumDstSync; loop++) { if (abDstSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; psSyncInfo->psSyncData->ui32WriteOpsPending++; } } } #if defined(PDUMP) if ((PDumpIsCaptureFrameKM() || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) && (bPersistentProcess == IMG_FALSE) ) { PDUMPCOMMENT("Shared part of transfer command\r\n"); PDUMPMEM(psSharedTransferCmd, psCCBMemInfo, psKick->ui32CCBDumpWOff, sizeof(SGXMKIF_TRANSFERCMD_SHARED), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) { IMG_UINT32 i = 0; for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = psKick->ahSrcSyncInfo[loop]; PDUMPCOMMENT("Hack src surface write op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Hack src surface read op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); i++; } } i = 0; for (loop = 0; loop < psKick->ui32NumDstSync; loop++) { if (abDstSyncEnable[i]) { IMG_UINT32 ui32PDumpReadOp2 = 0; psSyncInfo = psKick->ahDstSyncInfo[loop]; PDUMPCOMMENT("Hack dest surface write op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Hack dest surface read op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Hack dest surface read op2 in transfer cmd\r\n"); PDUMPMEM(&ui32PDumpReadOp2, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOps2PendingVal)), sizeof(ui32PDumpReadOp2), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); i++; } } for (loop = 0; loop < (psKick->ui32NumSrcSync); loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; } } for (loop = 0; loop < (psKick->ui32NumDstSync); loop++) { if (abDstSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0]; psSyncInfo->psSyncData->ui32LastOpDumpVal++; } } } if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = psKick->hTASyncInfo; PDUMPCOMMENT("Tweak TA/TQ surface write op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui32TASyncWriteOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); psSyncInfo->psSyncData->ui32LastOpDumpVal++; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = psKick->h3DSyncInfo; PDUMPCOMMENT("Tweak 3D/TQ surface write op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + (IMG_UINT32)(offsetof(SGXMKIF_TRANSFERCMD_SHARED, ui323DSyncWriteOpsPendingVal)), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); psSyncInfo->psSyncData->ui32LastOpDumpVal++; } } #endif sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr; PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_CMD_END, TRANSFER_TOKEN_SUBMIT); eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TRANSFER, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags, hDevMemContext, IMG_FALSE); if (eError == PVRSRV_ERROR_RETRY) { if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) { for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; psSyncInfo->psSyncData->ui32ReadOpsPending--; #if defined(PDUMP) if (PDumpIsCaptureFrameKM() || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) { psSyncInfo->psSyncData->ui32LastReadOpDumpVal--; } #endif } } for (loop = 0; loop < psKick->ui32NumDstSync; loop++) { if (abDstSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; psSyncInfo->psSyncData->ui32WriteOpsPending--; #if defined(PDUMP) if (PDumpIsCaptureFrameKM() || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) { psSyncInfo->psSyncData->ui32LastOpDumpVal--; } #endif } } } if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } } else if (PVRSRV_OK != eError) { PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: SGXScheduleCCBCommandKM failed.")); PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, TRANSFER_TOKEN_SUBMIT); return eError; } #if defined(NO_HARDWARE) if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE) == 0) { for (loop = 0; loop < psKick->ui32NumSrcSync; loop++) { if (abSrcSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } } for (loop = 0; loop < psKick->ui32NumDstSync; loop++) { if (abDstSyncEnable[loop]) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } } if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } } #endif PVR_TTRACE(PVRSRV_TRACE_GROUP_TRANSFER, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, TRANSFER_TOKEN_SUBMIT); return eError; }
IMG_EXPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo) { SYS_DATA *psSysData; if(!psMiscInfo) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters")); return PVRSRV_ERROR_INVALID_PARAMS; } psMiscInfo->ui32StatePresent = 0; if(psMiscInfo->ui32StateRequest & ~(PVRSRV_MISC_INFO_TIMER_PRESENT |PVRSRV_MISC_INFO_CLOCKGATE_PRESENT |PVRSRV_MISC_INFO_MEMSTATS_PRESENT |PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT |PVRSRV_MISC_INFO_DDKVERSION_PRESENT |PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT |PVRSRV_MISC_INFO_RESET_PRESENT |PVRSRV_MISC_INFO_FREEMEM_PRESENT)) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags")); return PVRSRV_ERROR_INVALID_PARAMS; } SysAcquireData(&psSysData); if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_TIMER_PRESENT) != 0UL) && (psSysData->pvSOCTimerRegisterKM != IMG_NULL)) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_TIMER_PRESENT; psMiscInfo->pvSOCTimerRegisterKM = psSysData->pvSOCTimerRegisterKM; psMiscInfo->hSOCTimerRegisterOSMemHandle = psSysData->hSOCTimerRegisterOSMemHandle; } else { psMiscInfo->pvSOCTimerRegisterKM = IMG_NULL; psMiscInfo->hSOCTimerRegisterOSMemHandle = IMG_NULL; } if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CLOCKGATE_PRESENT) != 0UL) && (psSysData->pvSOCClockGateRegsBase != IMG_NULL)) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CLOCKGATE_PRESENT; psMiscInfo->pvSOCClockGateRegs = psSysData->pvSOCClockGateRegsBase; psMiscInfo->ui32SOCClockGateRegsSize = psSysData->ui32SOCClockGateRegsSize; } if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0UL) && (psMiscInfo->pszMemoryStr != IMG_NULL)) { RA_ARENA **ppArena; IMG_CHAR *pszStr; IMG_UINT32 ui32StrLen; IMG_INT32 i32Count; pszStr = psMiscInfo->pszMemoryStr; ui32StrLen = psMiscInfo->ui32MemoryStrLen; psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_MEMSTATS_PRESENT; ppArena = &psSysData->apsLocalDevMemArena[0]; while(*ppArena) { CHECK_SPACE(ui32StrLen); i32Count = OSSNPrintf(pszStr, 100, "\nLocal Backing Store:\n"); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); RA_GetStats(*ppArena, &pszStr, &ui32StrLen); ppArena++; } List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList, &PVRSRVGetMiscInfoKM_Device_AnyVaCb, &ui32StrLen, &i32Count, &pszStr, PVRSRV_MISC_INFO_MEMSTATS_PRESENT); i32Count = OSSNPrintf(pszStr, 100, "\n"); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); } if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) && psMiscInfo->pszMemoryStr) { IMG_CHAR *pszStr; IMG_UINT32 ui32StrLen; IMG_INT32 i32Count; pszStr = psMiscInfo->pszMemoryStr; ui32StrLen = psMiscInfo->ui32MemoryStrLen; psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FREEMEM_PRESENT; List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList, &PVRSRVGetMiscInfoKM_Device_AnyVaCb, &ui32StrLen, &i32Count, &pszStr, PVRSRV_MISC_INFO_FREEMEM_PRESENT); i32Count = OSSNPrintf(pszStr, 100, "\n"); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); } if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) != 0UL) && (psSysData->psGlobalEventObject != IMG_NULL)) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT; psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject; } if (((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0UL) && ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) == 0UL) && (psMiscInfo->pszMemoryStr != IMG_NULL)) { IMG_CHAR *pszStr; IMG_UINT32 ui32StrLen; IMG_UINT32 ui32LenStrPerNum = 12; IMG_INT32 i32Count; PVRSRV_SGXDEV_INFO *sgx_dev_info; PVRSRV_SGX_MISCINFO_INFO *sgx_misc_info; PVRSRV_SGX_MISCINFO_FEATURES *sgx_features; unsigned long fw_ver; IMG_INT i; psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT; /* * Since the kernel driver has already made sure that the * firmware version is supported by the kernel driver in * SGXDevInitCompatCheck, it's redundant for the user space * part to perform the same check. In order to support older * user space libraries where this check hasn't yet been removed, * simply report the version of the downloaded firmware which * will result in an exact match in user space. */ sgx_dev_info = pvr_get_sgx_dev_info(); if (!sgx_dev_info || !sgx_dev_info->psKernelSGXMiscMemInfo || !sgx_dev_info->psKernelSGXMiscMemInfo->pvLinAddrKM) return PVRSRV_ERROR_INVALID_DEVICE; sgx_misc_info = sgx_dev_info->psKernelSGXMiscMemInfo->pvLinAddrKM; sgx_features = &sgx_misc_info->sSGXFeatures; fw_ver = sgx_features->ui32DDKVersion; psMiscInfo->aui32DDKVersion[0] = PVR_FW_VER_MAJOR(fw_ver); psMiscInfo->aui32DDKVersion[1] = PVR_FW_VER_MINOR(fw_ver); psMiscInfo->aui32DDKVersion[2] = PVR_FW_VER_BRANCH(fw_ver); psMiscInfo->aui32DDKVersion[3] = sgx_features->ui32DDKBuild; pszStr = psMiscInfo->pszMemoryStr; ui32StrLen = psMiscInfo->ui32MemoryStrLen; for (i=0; i<4; i++) { if (ui32StrLen < ui32LenStrPerNum) { return PVRSRV_ERROR_INVALID_PARAMS; } i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%u", psMiscInfo->aui32DDKVersion[i]); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); if (i != 3) { i32Count = OSSNPrintf(pszStr, 2, "."); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); } } } if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT) != 0UL) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT; if(psMiscInfo->sCacheOpCtl.bDeferOp) { psSysData->ePendingCacheOpType = psMiscInfo->sCacheOpCtl.eCacheOpType; } else { PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; PVRSRV_PER_PROCESS_DATA *psPerProc; if(!psMiscInfo->sCacheOpCtl.u.psKernelMemInfo) { PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: " "Ignoring non-deferred cache op with no meminfo")); return PVRSRV_ERROR_INVALID_PARAMS; } if(psSysData->ePendingCacheOpType != PVRSRV_MISC_INFO_CPUCACHEOP_NONE) { PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: " "Deferred cache op is pending. It is unlikely you want " "to combine deferred cache ops with immediate ones")); } psPerProc = PVRSRVFindPerProcessData(); if(PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_PVOID *)&psKernelMemInfo, psMiscInfo->sCacheOpCtl.u.psKernelMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: " "Can't find kernel meminfo")); return PVRSRV_ERROR_INVALID_PARAMS; } if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH) { if(!OSFlushCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle, psMiscInfo->sCacheOpCtl.pvBaseVAddr, psMiscInfo->sCacheOpCtl.ui32Length)) { return PVRSRV_ERROR_CACHEOP_FAILED; } } else if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN) { if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle, psMiscInfo->sCacheOpCtl.pvBaseVAddr, psMiscInfo->sCacheOpCtl.ui32Length)) { return PVRSRV_ERROR_CACHEOP_FAILED; } } } } #if defined(PVRSRV_RESET_ON_HWTIMEOUT) if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_RESET_PRESENT) != 0UL) { PVR_LOG(("User requested OS reset")); OSPanic(); } #endif return PVRSRV_OK; }
IMG_EXPORT PVRSRV_ERROR SGXSubmitTransferKM(IMG_HANDLE hDevHandle, PVRSRV_TRANSFER_SGX_KICK *psKick) { PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psKick->hCCBMemInfo; SGXMKIF_COMMAND sCommand = {0}; SGXMKIF_TRANSFERCMD_SHARED *psSharedTransferCmd; PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; PVRSRV_ERROR eError; IMG_UINT32 loop; #if defined(PDUMP) IMG_BOOL bPersistentProcess = IMG_FALSE; { PVRSRV_PER_PROCESS_DATA* psPerProc = PVRSRVFindPerProcessData(); if(psPerProc != IMG_NULL) { bPersistentProcess = psPerProc->bPDumpPersistent; } } #endif if (!CCB_OFFSET_IS_VALID(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset)) { PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: Invalid CCB offset")); return PVRSRV_ERROR_INVALID_PARAMS; } psSharedTransferCmd = CCB_DATA_FROM_OFFSET(SGXMKIF_TRANSFERCMD_SHARED, psCCBMemInfo, psKick, ui32SharedCmdCCBOffset); if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; psSharedTransferCmd->ui32TASyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; psSharedTransferCmd->ui32TASyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } else { psSharedTransferCmd->sTASyncWriteOpsCompleteDevVAddr.uiAddr = 0; psSharedTransferCmd->sTASyncReadOpsCompleteDevVAddr.uiAddr = 0; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; psSharedTransferCmd->ui323DSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; psSharedTransferCmd->ui323DSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } else { psSharedTransferCmd->s3DSyncWriteOpsCompleteDevVAddr.uiAddr = 0; psSharedTransferCmd->s3DSyncReadOpsCompleteDevVAddr.uiAddr = 0; } psSharedTransferCmd->ui32NumSrcSyncs = psKick->ui32NumSrcSync; psSharedTransferCmd->ui32NumDstSyncs = psKick->ui32NumDstSync; if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) { for (loop=0; loop<psKick->ui32NumSrcSync; loop++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; psSharedTransferCmd->asSrcSyncs[loop].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; psSharedTransferCmd->asSrcSyncs[loop].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->asSrcSyncs[loop].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->asSrcSyncs[loop].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } for (loop=0; loop<psKick->ui32NumDstSync; loop++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; psSharedTransferCmd->asDstSyncs[loop].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; psSharedTransferCmd->asDstSyncs[loop].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psSharedTransferCmd->asDstSyncs[loop].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psSharedTransferCmd->asDstSyncs[loop].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; } for (loop=0; loop<psKick->ui32NumSrcSync; loop++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; psSyncInfo->psSyncData->ui32ReadOpsPending++; } for (loop=0; loop<psKick->ui32NumDstSync; loop++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[loop]; psSyncInfo->psSyncData->ui32WriteOpsPending++; } } #if defined(PDUMP) if ((PDumpIsCaptureFrameKM() || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) && (bPersistentProcess == IMG_FALSE) ) { PDUMPCOMMENT("Shared part of transfer command\r\n"); PDUMPMEM(psSharedTransferCmd, psCCBMemInfo, psKick->ui32CCBDumpWOff, sizeof(SGXMKIF_TRANSFERCMD_SHARED), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) { for (loop=0; loop<psKick->ui32NumSrcSync ; loop++) { psSyncInfo = psKick->ahSrcSyncInfo[loop]; PDUMPCOMMENT("Hack src surface write op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + loop * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Hack src surface read op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, asSrcSyncs) + loop * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); } } if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) { for (loop=0; loop< psKick->ui32NumDstSync; loop++) { psSyncInfo = psKick->ahDstSyncInfo[loop]; PDUMPCOMMENT("Hack dest surface write op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + loop * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal) , sizeof(psSyncInfo->psSyncData->ui32LastOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Hack dest surface read op in transfer cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psKick->ui32CCBDumpWOff + offsetof(SGXMKIF_TRANSFERCMD_SHARED, asDstSyncs) + loop * sizeof(PVRSRV_DEVICE_SYNC_OBJECT) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), sizeof(psSyncInfo->psSyncData->ui32LastReadOpDumpVal), psKick->ui32PDumpFlags, MAKEUNIQUETAG(psCCBMemInfo)); } } if((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING)== 0UL) { for (loop=0; loop<(psKick->ui32NumSrcSync); loop++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[loop]; psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; } } if((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) { for (loop=0; loop<(psKick->ui32NumDstSync); loop++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0]; psSyncInfo->psSyncData->ui32LastOpDumpVal++; } } } #endif sCommand.ui32Data[1] = psKick->sHWTransferContextDevVAddr.uiAddr; eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TRANSFER, &sCommand, KERNEL_ID, psKick->ui32PDumpFlags, IMG_FALSE); if (eError == PVRSRV_ERROR_RETRY) { if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_KEEPPENDING) == 0UL) { if (psKick->ui32NumSrcSync > 0) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0]; psSyncInfo->psSyncData->ui32ReadOpsPending--; } if (psKick->ui32NumDstSync > 0) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0]; psSyncInfo->psSyncData->ui32WriteOpsPending--; } #if defined(PDUMP) if (PDumpIsCaptureFrameKM() || ((psKick->ui32PDumpFlags & PDUMP_FLAGS_CONTINUOUS) != 0)) { if (psKick->ui32NumSrcSync > 0) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[0]; psSyncInfo->psSyncData->ui32LastReadOpDumpVal--; } if (psKick->ui32NumDstSync > 0) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[0]; psSyncInfo->psSyncData->ui32LastOpDumpVal--; } } #endif } if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsPending--; } } else if (PVRSRV_OK != eError) { PVR_DPF((PVR_DBG_ERROR, "SGXSubmitTransferKM: SGXScheduleCCBCommandKM failed.")); return eError; } #if defined(NO_HARDWARE) if ((psKick->ui32Flags & SGXMKIF_TQFLAGS_NOSYNCUPDATE) == 0) { IMG_UINT32 i; for(i = 0; i < psKick->ui32NumSrcSync; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahSrcSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } for(i = 0; i < psKick->ui32NumDstSync; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->ahDstSyncInfo[i]; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } if (psKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->hTASyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } if (psKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } } #endif return eError; }
/*! ****************************************************************************** @Function PVRSRVGetMiscInfoKM @Description Retrieves misc. info. @Output PVRSRV_MISC_INFO @Return PVRSRV_ERROR : ******************************************************************************/ IMG_EXPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVGetMiscInfoKM(PVRSRV_MISC_INFO *psMiscInfo) { SYS_DATA *psSysData; if(!psMiscInfo) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid parameters")); return PVRSRV_ERROR_INVALID_PARAMS; } psMiscInfo->ui32StatePresent = 0; /* do a basic check for uninitialised request flag */ if(psMiscInfo->ui32StateRequest & ~(PVRSRV_MISC_INFO_TIMER_PRESENT |PVRSRV_MISC_INFO_CLOCKGATE_PRESENT |PVRSRV_MISC_INFO_MEMSTATS_PRESENT |PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT |PVRSRV_MISC_INFO_DDKVERSION_PRESENT |PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT |PVRSRV_MISC_INFO_RESET_PRESENT |PVRSRV_MISC_INFO_FREEMEM_PRESENT |PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT |PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT |PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT)) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVGetMiscInfoKM: invalid state request flags")); return PVRSRV_ERROR_INVALID_PARAMS; } SysAcquireData(&psSysData); /* return SOC Timer registers */ if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_TIMER_PRESENT) != 0UL) && (psSysData->pvSOCTimerRegisterKM != IMG_NULL)) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_TIMER_PRESENT; psMiscInfo->pvSOCTimerRegisterKM = psSysData->pvSOCTimerRegisterKM; psMiscInfo->hSOCTimerRegisterOSMemHandle = psSysData->hSOCTimerRegisterOSMemHandle; } else { psMiscInfo->pvSOCTimerRegisterKM = IMG_NULL; psMiscInfo->hSOCTimerRegisterOSMemHandle = IMG_NULL; } /* return SOC Clock Gating registers */ if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CLOCKGATE_PRESENT) != 0UL) && (psSysData->pvSOCClockGateRegsBase != IMG_NULL)) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CLOCKGATE_PRESENT; psMiscInfo->pvSOCClockGateRegs = psSysData->pvSOCClockGateRegsBase; psMiscInfo->ui32SOCClockGateRegsSize = psSysData->ui32SOCClockGateRegsSize; } /* memory stats */ if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0UL) && (psMiscInfo->pszMemoryStr != IMG_NULL)) { RA_ARENA **ppArena; /* BM_HEAP *psBMHeap; BM_CONTEXT *psBMContext; PVRSRV_DEVICE_NODE *psDeviceNode;*/ IMG_CHAR *pszStr; IMG_UINT32 ui32StrLen; IMG_INT32 i32Count; pszStr = psMiscInfo->pszMemoryStr; ui32StrLen = psMiscInfo->ui32MemoryStrLen; psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_MEMSTATS_PRESENT; /* Local backing stores */ ppArena = &psSysData->apsLocalDevMemArena[0]; while(*ppArena) { CHECK_SPACE(ui32StrLen); i32Count = OSSNPrintf(pszStr, 100, "\nLocal Backing Store:\n"); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); RA_GetStats(*ppArena, &pszStr, &ui32StrLen); /* advance through the array */ ppArena++; } /* per device */ /* psDeviceNode = psSysData->psDeviceNodeList;*/ /*triple loop; devices:contexts:heaps*/ List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList, &PVRSRVGetMiscInfoKM_Device_AnyVaCb, &ui32StrLen, &i32Count, &pszStr, PVRSRV_MISC_INFO_MEMSTATS_PRESENT); /* attach a new line and string terminate */ i32Count = OSSNPrintf(pszStr, 100, "\n"); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); } /* Lean version of mem stats: only show free mem on each RA */ if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FREEMEM_PRESENT) != 0) && psMiscInfo->pszMemoryStr) { IMG_CHAR *pszStr; IMG_UINT32 ui32StrLen; IMG_INT32 i32Count; pszStr = psMiscInfo->pszMemoryStr; ui32StrLen = psMiscInfo->ui32MemoryStrLen; psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FREEMEM_PRESENT; /* triple loop over devices:contexts:heaps */ List_PVRSRV_DEVICE_NODE_PVRSRV_ERROR_Any_va(psSysData->psDeviceNodeList, &PVRSRVGetMiscInfoKM_Device_AnyVaCb, &ui32StrLen, &i32Count, &pszStr, PVRSRV_MISC_INFO_FREEMEM_PRESENT); i32Count = OSSNPrintf(pszStr, 100, "\n"); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); } if(((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) != 0UL) && (psSysData->psGlobalEventObject != IMG_NULL)) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT; psMiscInfo->sGlobalEventObject = *psSysData->psGlobalEventObject; } /* DDK version and memstats not supported in same call to GetMiscInfo */ if (((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0UL) && ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_MEMSTATS_PRESENT) == 0UL) && (psMiscInfo->pszMemoryStr != IMG_NULL)) { IMG_CHAR *pszStr; IMG_UINT32 ui32StrLen; IMG_UINT32 ui32LenStrPerNum = 12; /* string length per UI32: 10 digits + '.' + '\0' = 12 bytes */ IMG_INT32 i32Count; IMG_INT i; psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_DDKVERSION_PRESENT; /* construct DDK string */ psMiscInfo->aui32DDKVersion[0] = PVRVERSION_MAJ; psMiscInfo->aui32DDKVersion[1] = PVRVERSION_MIN; psMiscInfo->aui32DDKVersion[2] = PVRVERSION_BUILD_HI; psMiscInfo->aui32DDKVersion[3] = PVRVERSION_BUILD_LO; pszStr = psMiscInfo->pszMemoryStr; ui32StrLen = psMiscInfo->ui32MemoryStrLen; for (i=0; i<4; i++) { if (ui32StrLen < ui32LenStrPerNum) { return PVRSRV_ERROR_INVALID_PARAMS; } i32Count = OSSNPrintf(pszStr, ui32LenStrPerNum, "%u", psMiscInfo->aui32DDKVersion[i]); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); if (i != 3) { i32Count = OSSNPrintf(pszStr, 2, "."); UPDATE_SPACE(pszStr, i32Count, ui32StrLen); } } } if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT) != 0UL) { psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_CPUCACHEOP_PRESENT; if(psMiscInfo->sCacheOpCtl.bDeferOp) { /* For now, assume deferred ops are "full" cache ops, * and we don't need (or expect) a meminfo. */ psSysData->ePendingCacheOpType = psMiscInfo->sCacheOpCtl.eCacheOpType; } else { PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; PVRSRV_PER_PROCESS_DATA *psPerProc; if(!psMiscInfo->sCacheOpCtl.u.psKernelMemInfo) { PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: " "Ignoring non-deferred cache op with no meminfo")); return PVRSRV_ERROR_INVALID_PARAMS; } if(psSysData->ePendingCacheOpType != PVRSRV_MISC_INFO_CPUCACHEOP_NONE) { PVR_DPF((PVR_DBG_WARNING, "PVRSRVGetMiscInfoKM: " "Deferred cache op is pending. It is unlikely you want " "to combine deferred cache ops with immediate ones")); } psPerProc = PVRSRVFindPerProcessData(); if(PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_PVOID *)&psKernelMemInfo, psMiscInfo->sCacheOpCtl.u.psKernelMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: " "Can't find kernel meminfo")); return PVRSRV_ERROR_INVALID_PARAMS; } if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_FLUSH) { if(!OSFlushCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle, 0, psMiscInfo->sCacheOpCtl.pvBaseVAddr, psMiscInfo->sCacheOpCtl.ui32Length)) { return PVRSRV_ERROR_CACHEOP_FAILED; } } else if(psMiscInfo->sCacheOpCtl.eCacheOpType == PVRSRV_MISC_INFO_CPUCACHEOP_CLEAN) { if(psMiscInfo->sCacheOpCtl.ui32Length!=0) { if(!OSCleanCPUCacheRangeKM(psKernelMemInfo->sMemBlk.hOSMemHandle, 0, psMiscInfo->sCacheOpCtl.pvBaseVAddr, psMiscInfo->sCacheOpCtl.ui32Length)) { return PVRSRV_ERROR_CACHEOP_FAILED; } } } } } if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT) != 0UL) { PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo; PVRSRV_PER_PROCESS_DATA *psPerProc; psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GET_REF_COUNT_PRESENT; psPerProc = PVRSRVFindPerProcessData(); if(PVRSRVLookupHandle(psPerProc->psHandleBase, (IMG_PVOID *)&psKernelMemInfo, psMiscInfo->sGetRefCountCtl.u.psKernelMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVGetMiscInfoKM: " "Can't find kernel meminfo")); return PVRSRV_ERROR_INVALID_PARAMS; } psMiscInfo->sGetRefCountCtl.ui32RefCount = psKernelMemInfo->ui32RefCount; } if ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT) != 0UL) { psMiscInfo->ui32PageSize = HOST_PAGESIZE(); psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_GET_PAGE_SIZE_PRESENT; } #if defined(PVRSRV_RESET_ON_HWTIMEOUT) if((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_RESET_PRESENT) != 0UL) { PVR_LOG(("User requested OS reset")); OSPanic(); } #endif /* #if defined(PVRSRV_RESET_ON_HWTIMEOUT) */ #if defined(SUPPORT_PVRSRV_DEVICE_CLASS) if ((psMiscInfo->ui32StateRequest & PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT) != 0UL) { PVRSRVProcessQueues(IMG_TRUE); psMiscInfo->ui32StatePresent |= PVRSRV_MISC_INFO_FORCE_SWAP_TO_SYSTEM_PRESENT; } #endif /* defined(SUPPORT_PVRSRV_DEVICE_CLASS) */ return PVRSRV_OK; }