static PVRSRV_ERROR _Create3DTransferContext(CONNECTION_DATA *psConnection, PVRSRV_DEVICE_NODE *psDeviceNode, DEVMEM_MEMDESC *psFWMemContextMemDesc, IMG_UINT32 ui32Priority, RGX_COMMON_CONTEXT_INFO *psInfo, RGX_SERVER_TQ_3D_DATA *ps3DData) { PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; PVRSRV_ERROR eError; /* Allocate device memory for the firmware GPU context suspend state. Note: the FW reads/writes the state to memory by accessing the GPU register interface. */ PDUMPCOMMENT("Allocate RGX firmware TQ/3D context suspend state"); eError = DevmemFwAllocate(psDevInfo, sizeof(RGXFWIF_3DCTX_STATE), RGX_FWCOMCTX_ALLOCFLAGS, "FirmwareTQ3DContext", &ps3DData->psFWContextStateMemDesc); if (eError != PVRSRV_OK) { goto fail_contextswitchstate; } eError = FWCommonContextAllocate(psConnection, psDeviceNode, "TQ_3D", IMG_NULL, 0, psFWMemContextMemDesc, ps3DData->psFWContextStateMemDesc, RGX_CCB_SIZE_LOG2, ui32Priority, psInfo, &ps3DData->psServerCommonContext); if (eError != PVRSRV_OK) { goto fail_contextalloc; } PDUMPCOMMENT("Dump 3D context suspend state buffer"); DevmemPDumpLoadMem(ps3DData->psFWContextStateMemDesc, 0, sizeof(RGXFWIF_3DCTX_STATE), PDUMP_FLAGS_CONTINUOUS); ps3DData->ui32Priority = ui32Priority; return PVRSRV_OK; fail_contextalloc: DevmemFwFree(ps3DData->psFWContextStateMemDesc); fail_contextswitchstate: PVR_ASSERT(eError != PVRSRV_OK); return eError; }
static void MMU_PDumpPageTables(struct MMU_HEAP *pMMUHeap, struct IMG_DEV_VIRTADDR DevVAddr, size_t uSize, IMG_BOOL bForUnmap, void *hUniqueTag) { u32 ui32NumPTEntries; u32 ui32PTIndex; u32 *pui32PTEntry; struct MMU_PT_INFO **ppsPTInfoList; u32 ui32PDIndex; u32 ui32PTDumpCount; ui32NumPTEntries = (uSize + SGX_MMU_PAGE_SIZE - 1) >> SGX_MMU_PAGE_SHIFT; ui32PDIndex = DevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; ui32PTIndex = (DevVAddr.uiAddr & SGX_MMU_PT_MASK) >> SGX_MMU_PAGE_SHIFT; PDUMPCOMMENT("Page table mods (num entries == %08X) %s", ui32NumPTEntries, bForUnmap ? "(for unmap)" : ""); while (ui32NumPTEntries > 0) { struct MMU_PT_INFO *psPTInfo = *ppsPTInfoList++; if (ui32NumPTEntries <= 1024 - ui32PTIndex) ui32PTDumpCount = ui32NumPTEntries; else ui32PTDumpCount = 1024 - ui32PTIndex; if (psPTInfo) { pui32PTEntry = (u32 *)psPTInfo->PTPageCpuVAddr; PDUMPPAGETABLE((void *)&pui32PTEntry[ui32PTIndex], ui32PTDumpCount * sizeof(u32), IMG_FALSE, PDUMP_PT_UNIQUETAG, hUniqueTag); } ui32NumPTEntries -= ui32PTDumpCount; ui32PTIndex = 0; } PDUMPCOMMENT("Finished page table mods %s", bForUnmap ? "(for unmap)" : ""); }
void PDumpEndInitPhase(void) { u32 i; PDUMPCOMMENT("End of Init Phase"); for (i = 0; i < PDUMP_NUM_STREAMS; i++) gpfnDbgDrv->pfnEndInitPhase(gsDBGPdumpState.psStream[i]); }
IMG_VOID SyncConnectionPDumpSyncBlocks(SYNC_CONNECTION_DATA *psSyncConnectionData) { OSLockAcquire(psSyncConnectionData->hLock); PDUMPCOMMENT("Dump client Sync Prim state"); dllist_foreach_node(&psSyncConnectionData->sListHead, _PDumpSyncBlock, IMG_NULL); OSLockRelease(psSyncConnectionData->hLock); }
/************************************************************************** * Function Name : PDumpStartInitPhaseKM * Inputs : None * Outputs : None * Returns : None * Description : Resume init phase state **************************************************************************/ PVRSRV_ERROR PDumpStartInitPhaseKM(IMG_VOID) { IMG_UINT32 i; if (gpfnDbgDrv) { PDUMPCOMMENT("Start Init Phase"); for(i=0; i < PDUMP_NUM_STREAMS; i++) { gpfnDbgDrv->pfnStartInitPhase(gsDBGPdumpState.psStream[i]); } } return PVRSRV_OK; }
void MMU_InsertHeap(struct MMU_CONTEXT *psMMUContext, struct MMU_HEAP *psMMUHeap) { u32 *pui32PDCpuVAddr = (u32 *)psMMUContext->pvPDCpuVAddr; u32 *pui32KernelPDCpuVAddr = (u32 *) psMMUHeap->psMMUContext->pvPDCpuVAddr; u32 ui32PDEntry; IMG_BOOL bInvalidateDirectoryCache = IMG_FALSE; pui32PDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); pui32KernelPDCpuVAddr += psMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); PDUMPCOMMENT("Page directory shared heap range copy"); for (ui32PDEntry = 0; ui32PDEntry < psMMUHeap->ui32PTPageCount; ui32PDEntry++) { PVR_ASSERT(pui32PDCpuVAddr[ui32PDEntry] == 0); pui32PDCpuVAddr[ui32PDEntry] = pui32KernelPDCpuVAddr[ui32PDEntry]; if (pui32PDCpuVAddr[ui32PDEntry]) { PDUMPPAGETABLE((void *) &pui32PDCpuVAddr[ui32PDEntry], sizeof(u32), IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); bInvalidateDirectoryCache = IMG_TRUE; } } if (bInvalidateDirectoryCache) MMU_InvalidateDirectoryCache(psMMUContext->psDevInfo); }
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 PVRSRVRGXCreateComputeContextKM(CONNECTION_DATA *psConnection, PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT32 ui32Priority, IMG_DEV_VIRTADDR sMCUFenceAddr, IMG_UINT32 ui32FrameworkCommandSize, IMG_PBYTE pbyFrameworkCommand, IMG_HANDLE hMemCtxPrivData, RGX_SERVER_COMPUTE_CONTEXT **ppsComputeContext) { PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; DEVMEM_MEMDESC *psFWMemContextMemDesc = RGXGetFWMemDescFromMemoryContextHandle(hMemCtxPrivData); RGX_SERVER_COMPUTE_CONTEXT *psComputeContext; RGX_COMMON_CONTEXT_INFO sInfo; PVRSRV_ERROR eError = PVRSRV_OK; /* Prepare cleanup struct */ *ppsComputeContext = IMG_NULL; psComputeContext = OSAllocMem(sizeof(*psComputeContext)); if (psComputeContext == IMG_NULL) { return PVRSRV_ERROR_OUT_OF_MEMORY; } OSMemSet(psComputeContext, 0, sizeof(*psComputeContext)); psComputeContext->psDeviceNode = psDeviceNode; /* Allocate cleanup sync */ eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext, &psComputeContext->psSync); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to allocate cleanup sync (0x%x)", eError)); goto fail_syncalloc; } /* Allocate device memory for the firmware GPU context suspend state. Note: the FW reads/writes the state to memory by accessing the GPU register interface. */ PDUMPCOMMENT("Allocate RGX firmware compute context suspend state"); eError = DevmemFwAllocate(psDevInfo, sizeof(RGXFWIF_COMPUTECTX_STATE), RGX_FWCOMCTX_ALLOCFLAGS, "ComputeContextState", &psComputeContext->psFWComputeContextStateMemDesc); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to allocate firmware GPU context suspend state (%u)", eError)); goto fail_contextsuspendalloc; } /* * Create the FW framework buffer */ eError = PVRSRVRGXFrameworkCreateKM(psDeviceNode, &psComputeContext->psFWFrameworkMemDesc, ui32FrameworkCommandSize); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to allocate firmware GPU framework state (%u)", eError)); goto fail_frameworkcreate; } /* Copy the Framework client data into the framework buffer */ eError = PVRSRVRGXFrameworkCopyCommand(psComputeContext->psFWFrameworkMemDesc, pbyFrameworkCommand, ui32FrameworkCommandSize); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to populate the framework buffer (%u)", eError)); goto fail_frameworkcopy; } sInfo.psFWFrameworkMemDesc = psComputeContext->psFWFrameworkMemDesc; sInfo.psMCUFenceAddr = &sMCUFenceAddr; eError = FWCommonContextAllocate(psConnection, psDeviceNode, "CDM", IMG_NULL, 0, psFWMemContextMemDesc, psComputeContext->psFWComputeContextStateMemDesc, RGX_CCB_SIZE_LOG2, ui32Priority, &sInfo, &psComputeContext->psServerCommonContext); if (eError != PVRSRV_OK) { goto fail_contextalloc; } { PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; dllist_add_to_tail(&(psDevInfo->sComputeCtxtListHead), &(psComputeContext->sListNode)); } *ppsComputeContext = psComputeContext; return PVRSRV_OK; fail_contextalloc: fail_frameworkcopy: DevmemFwFree(psComputeContext->psFWFrameworkMemDesc); fail_frameworkcreate: DevmemFwFree(psComputeContext->psFWComputeContextStateMemDesc); fail_contextsuspendalloc: SyncPrimFree(psComputeContext->psSync); fail_syncalloc: OSFreeMem(psComputeContext); return eError; }
PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) #endif { PVRSRV_ERROR eError; PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *) psCCBKick->hCCBKernelMemInfo; SGXMKIF_CMDTA_SHARED *psTACmd; IMG_UINT32 i; IMG_HANDLE hDevMemContext = IMG_NULL; #if defined(FIX_HW_BRN_31620) hDevMemContext = psCCBKick->hDevMemContext; #endif PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_ENTER, KICK_TOKEN_DOKICK); if (!CCB_OFFSET_IS_VALID(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset)) { PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: Invalid CCB offset")); PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, KICK_TOKEN_DOKICK); return PVRSRV_ERROR_INVALID_PARAMS; } /* override QAC warning about stricter alignment */ /* PRQA S 3305 1 */ psTACmd = CCB_DATA_FROM_OFFSET(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset); PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CMD_START, KICK_TOKEN_DOKICK); #if defined(TTRACE) if (psCCBKick->bFirstKickOrResume) { PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FLAGS, KICK_TOKEN_FIRST_KICK); } if (psCCBKick->bLastInScene) { PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FLAGS, KICK_TOKEN_LAST_KICK); } #endif PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CCB, KICK_TOKEN_CCB_OFFSET, psCCBKick->ui32CCBOffset); /* TA/3D dependency */ if (psCCBKick->hTA3DSyncInfo) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_TA3D_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psTACmd->sTA3DDependency.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->sTA3DDependency.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; if (psCCBKick->bTADependency) { psSyncInfo->psSyncData->ui32WriteOpsPending++; } } if (psCCBKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_TA_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psTACmd->sTATQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->sTATQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->ui32TATQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; psTACmd->ui32TATQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } if (psCCBKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_3D_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psTACmd->s3DTQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->s3DTQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->ui323DTQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; psTACmd->ui323DTQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } psTACmd->ui32NumTAStatusVals = psCCBKick->ui32NumTAStatusVals; if (psCCBKick->ui32NumTAStatusVals != 0) { /* Copy status vals over */ for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) { #if defined(SUPPORT_SGX_NEW_STATUS_VALS) psTACmd->sCtlTAStatusInfo[i] = psCCBKick->asTAStatusUpdate[i].sCtlStatus; #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->sCtlTAStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending; #endif } } psTACmd->ui32Num3DStatusVals = psCCBKick->ui32Num3DStatusVals; if (psCCBKick->ui32Num3DStatusVals != 0) { /* Copy status vals over */ for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) { #if defined(SUPPORT_SGX_NEW_STATUS_VALS) psTACmd->sCtl3DStatusInfo[i] = psCCBKick->as3DStatusUpdate[i].sCtlStatus; #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->sCtl3DStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending; #endif } } #if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) /* SRC and DST sync dependencies */ psTACmd->ui32NumTASrcSyncs = psCCBKick->ui32NumTASrcSyncs; for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; psTACmd->asTASrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->asTASrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; /* Get ui32ReadOpsPending snapshot and copy into the CCB - before incrementing. */ psTACmd->asTASrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; /* Copy ui32WriteOpsPending snapshot into the CCB. */ psTACmd->asTASrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } psTACmd->ui32NumTADstSyncs = psCCBKick->ui32NumTADstSyncs; for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; psTACmd->asTADstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->asTADstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; /* Get ui32ReadOpsPending snapshot and copy into the CCB */ psTACmd->asTADstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; /* Copy ui32WriteOpsPending snapshot into the CCB - before incrementing */ psTACmd->asTADstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; } psTACmd->ui32Num3DSrcSyncs = psCCBKick->ui32Num3DSrcSyncs; for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; psTACmd->as3DSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->as3DSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; /* Get ui32ReadOpsPending snapshot and copy into the CCB - before incrementing. */ psTACmd->as3DSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; /* Copy ui32WriteOpsPending snapshot into the CCB. */ psTACmd->as3DSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } #else /* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */ /* texture dependencies */ psTACmd->ui32NumSrcSyncs = psCCBKick->ui32NumSrcSyncs; for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_SRC_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psTACmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; /* Get ui32ReadOpsPending snapshot and copy into the CCB - before incrementing. */ psTACmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; /* Copy ui32WriteOpsPending snapshot into the CCB. */ psTACmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } #endif/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */ if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0) { PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo; SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM; IMG_UINT32 ui32NumDstSyncs = psCCBKick->ui32NumDstSyncObjects; PVR_ASSERT(((PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo)->uAllocSize >= (sizeof(SGXMKIF_HWDEVICE_SYNC_LIST) + (sizeof(PVRSRV_DEVICE_SYNC_OBJECT) * ui32NumDstSyncs))); psHWDeviceSyncList->ui32NumSyncObjects = ui32NumDstSyncs; #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { PDUMPCOMMENT("HWDeviceSyncList for TACmd\r\n"); PDUMPMEM(IMG_NULL, psHWDstSyncListMemInfo, 0, sizeof(SGXMKIF_HWDEVICE_SYNC_LIST), 0, MAKEUNIQUETAG(psHWDstSyncListMemInfo)); } #endif for (i=0; i<ui32NumDstSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i]; if (psSyncInfo) { psSyncInfo->psSyncData->ui64LastWrite = ui64KickCount; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_DST_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psHWDeviceSyncList->asSyncData[i].sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr; psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; psHWDeviceSyncList->asSyncData[i].ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending; #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { IMG_UINT32 ui32ModifiedValue; IMG_UINT32 ui32SyncOffset = offsetof(SGXMKIF_HWDEVICE_SYNC_LIST, asSyncData) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)); IMG_UINT32 ui32WOpsOffset = ui32SyncOffset + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal); IMG_UINT32 ui32ROpsOffset = ui32SyncOffset + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal); IMG_UINT32 ui32ROps2Offset = ui32SyncOffset + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOps2PendingVal); PDUMPCOMMENT("HWDeviceSyncObject for RT: %i\r\n", i); PDUMPMEM(IMG_NULL, psHWDstSyncListMemInfo, ui32SyncOffset, sizeof(PVRSRV_DEVICE_SYNC_OBJECT), 0, MAKEUNIQUETAG(psHWDstSyncListMemInfo)); if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) { /* * Init the ROpsComplete value to 0. */ PDUMPCOMMENT("Init RT ROpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); /* * Init the WOpsComplete value to 0. */ PDUMPCOMMENT("Init RT WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); } psSyncInfo->psSyncData->ui32LastOpDumpVal++; ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1; PDUMPCOMMENT("Modify RT %d WOpPendingVal in HWDevSyncList\r\n", i); PDUMPMEM(&ui32ModifiedValue, psHWDstSyncListMemInfo, ui32WOpsOffset, sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psHWDstSyncListMemInfo)); ui32ModifiedValue = 0; PDUMPCOMMENT("Modify RT %d ROpsPendingVal in HWDevSyncList\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psHWDstSyncListMemInfo, ui32ROpsOffset, sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psHWDstSyncListMemInfo)); /* * Force the ROps2Complete value to 0. */ PDUMPCOMMENT("Modify RT %d ROps2PendingVal in HWDevSyncList\r\n", i); PDUMPMEM(&ui32ModifiedValue, psHWDstSyncListMemInfo, ui32ROps2Offset, sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psHWDstSyncListMemInfo)); } #endif /* defined(PDUMP) */ } else { psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr.uiAddr = 0; psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr.uiAddr = 0; psHWDeviceSyncList->asSyncData[i].sReadOps2CompleteDevVAddr.uiAddr = 0; psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = 0; psHWDeviceSyncList->asSyncData[i].ui32ReadOps2PendingVal = 0; psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = 0; } } } /* NOTE: THIS MUST BE THE LAST THING WRITTEN TO THE TA COMMAND! Set the ready for so the uKernel will process the command. */ psTACmd->ui32CtrlFlags |= SGXMKIF_CMDTA_CTRLFLAGS_READY; #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { PDUMPCOMMENT("Shared part of TA command\r\n"); PDUMPMEM(psTACmd, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff, sizeof(SGXMKIF_CMDTA_SHARED), 0, MAKEUNIQUETAG(psCCBMemInfo)); #if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++) { IMG_UINT32 ui32ModifiedValue; psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) { /* * Init the ROpsComplete value to 0. */ PDUMPCOMMENT("Init RT TA-SRC ROpsComplete\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); /* * Init the WOpsComplete value to 0. */ PDUMPCOMMENT("Init RT TA-SRC WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); } psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1; PDUMPCOMMENT("Modify TA SrcSync %d ROpsPendingVal\r\n", i); PDUMPMEM(&ui32ModifiedValue, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Modify TA SrcSync %d WOpPendingVal\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); } for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++) { IMG_UINT32 ui32ModifiedValue; psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) { /* * Init the ROpsComplete value to 0. */ PDUMPCOMMENT("Init RT TA-DST ROpsComplete\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); /* * Init the WOpsComplete value to 0. */ PDUMPCOMMENT("Init RT TA-DST WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); } psSyncInfo->psSyncData->ui32LastOpDumpVal++; ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1; PDUMPCOMMENT("Modify TA DstSync %d WOpPendingVal\r\n", i); PDUMPMEM(&ui32ModifiedValue, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Modify TA DstSync %d ROpsPendingVal\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); } for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++) { IMG_UINT32 ui32ModifiedValue; psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) { /* * Init the ROpsComplete value to 0. */ PDUMPCOMMENT("Init RT 3D-SRC ROpsComplete\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); /* * Init the WOpsComplete value to 0. */ PDUMPCOMMENT("Init RT 3D-SRC WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); } psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1; PDUMPCOMMENT("Modify 3D SrcSync %d ROpsPendingVal\r\n", i); PDUMPMEM(&ui32ModifiedValue, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Modify 3D SrcSync %d WOpPendingVal\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); } #else/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++) { IMG_UINT32 ui32ModifiedValue; psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) { /* * Init the ROpsComplete value to 0. */ PDUMPCOMMENT("Init RT ROpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); /* * Init the WOpsComplete value to 0. */ PDUMPCOMMENT("Init RT WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); /* * Init the ROps2Complete value to 0. */ PDUMPCOMMENT("Init RT WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOps2Complete), sizeof(psSyncInfo->psSyncData->ui32ReadOps2Complete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); } psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1; PDUMPCOMMENT("Modify SrcSync %d ROpsPendingVal\r\n", i); PDUMPMEM(&ui32ModifiedValue, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Modify SrcSync %d WOpPendingVal\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); } if (psCCBKick->hTA3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo; PDUMPCOMMENT("Modify TA/3D dependency WOpPendingVal\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, sTA3DDependency.ui32WriteOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); if (psCCBKick->bTADependency) { psSyncInfo->psSyncData->ui32LastOpDumpVal++; } } if (psCCBKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; PDUMPCOMMENT("Modify TA/TQ ROpPendingVal\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui32TATQSyncReadOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; } if (psCCBKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; PDUMPCOMMENT("Modify 3D/TQ ROpPendingVal\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui323DTQSyncReadOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; } #endif/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */ for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) { #if !defined(SUPPORT_SGX_NEW_STATUS_VALS) psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; PDUMPCOMMENT("Modify TA status value in TA cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_CMDTA_SHARED, sCtlTAStatusInfo[i].ui32StatusValue), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); #endif } for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) { #if !defined(SUPPORT_SGX_NEW_STATUS_VALS) psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; PDUMPCOMMENT("Modify 3D status value in TA cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_CMDTA_SHARED, sCtl3DStatusInfo[i].ui32StatusValue), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); #endif } } #endif /* defined(PDUMP) */ PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CMD_END, KICK_TOKEN_DOKICK); eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TA, &psCCBKick->sCommand, KERNEL_ID, 0, hDevMemContext, psCCBKick->bLastInScene); if (eError == PVRSRV_ERROR_RETRY) { if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0) { for (i=0; i < psCCBKick->ui32NumDstSyncObjects; i++) { /* Client will retry, so undo the write ops pending increment done above. */ psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i]; if (psSyncInfo) { psSyncInfo->psSyncData->ui32WriteOpsPending--; #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { psSyncInfo->psSyncData->ui32LastOpDumpVal--; } #endif } } } #if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending--; } for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32WriteOpsPending--; } for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending--; } #else/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending--; } #endif/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */ if (psCCBKick->hTA3DSyncInfo) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo; psSyncInfo->psSyncData->ui32ReadOpsPending--; } if (psCCBKick->hTASyncInfo) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; psSyncInfo->psSyncData->ui32ReadOpsPending--; } if (psCCBKick->h3DSyncInfo) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32ReadOpsPending--; } PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, KICK_TOKEN_DOKICK); return eError; } else if (PVRSRV_OK != eError) { PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: SGXScheduleCCBCommandKM failed.")); PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, KICK_TOKEN_DOKICK); return eError; } #if defined(NO_HARDWARE) /* TA/3D dependency */ if (psCCBKick->hTA3DSyncInfo) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo; if (psCCBKick->bTADependency) { psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } } if (psCCBKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } if (psCCBKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } /* Copy status vals over */ for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) { #if defined(SUPPORT_SGX_NEW_STATUS_VALS) PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->asTAStatusUpdate[i].hKernelMemInfo; /* derive offset into meminfo and write the status value */ *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM + (psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr.uiAddr - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue; #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue; #endif } #if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) /* SRC and DST dependencies */ for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } #else/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */ /* texture dependencies */ for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } #endif/* SUPPORT_SGX_GENERALISED_SYNCOBJECTS */ if (psCCBKick->bTerminateOrAbort) { if (psCCBKick->ui32NumDstSyncObjects > 0) { PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo; SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM; for (i=0; i<psCCBKick->ui32NumDstSyncObjects; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i]; if (psSyncInfo) psSyncInfo->psSyncData->ui32WriteOpsComplete = psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal+1; } } /* Copy status vals over */ for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) { #if defined(SUPPORT_SGX_NEW_STATUS_VALS) PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->as3DStatusUpdate[i].hKernelMemInfo; /* derive offset into meminfo and write the status value */ *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM + (psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr.uiAddr - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue; #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue; #endif } } #endif PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, KICK_TOKEN_DOKICK); 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 PVRSRVRGXCreateTQ2DContextKM(PVRSRV_DEVICE_NODE *psDeviceNode, DEVMEM_MEMDESC *psTQ2DCCBMemDesc, DEVMEM_MEMDESC *psTQ2DCCBCtlMemDesc, RGX_TQ2D_CLEANUP_DATA **ppsCleanupData, DEVMEM_MEMDESC **ppsFWTQ2DContextMemDesc, IMG_UINT32 ui32Priority, IMG_UINT32 ui32FrameworkRegisterSize, IMG_PBYTE pbyFrameworkRegisters, IMG_HANDLE hMemCtxPrivData) { PVRSRV_ERROR eError = PVRSRV_OK; PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; RGXFWIF_FWCOMMONCONTEXT *psFWTQ2DContext; RGX_TQ2D_CLEANUP_DATA *psTmpCleanup; DEVMEM_MEMDESC *psFWFrameworkMemDesc; /* Prepare cleanup struct */ psTmpCleanup = OSAllocMem(sizeof(*psTmpCleanup)); if (psTmpCleanup == IMG_NULL) { return PVRSRV_ERROR_OUT_OF_MEMORY; } OSMemSet(psTmpCleanup, 0, sizeof(*psTmpCleanup)); *ppsCleanupData = psTmpCleanup; /* Allocate cleanup sync */ eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext, &psTmpCleanup->psCleanupSync); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to allocate cleanup sync (0x%x)", eError)); goto fail_syncalloc; } /* Allocate device memory for the firmware TQ 2D context. */ PDUMPCOMMENT("Allocate RGX firmware TQ 2D context"); eError = DevmemFwAllocate(psDevInfo, sizeof(*psFWTQ2DContext), RGX_FWCOMCTX_ALLOCFLAGS, ppsFWTQ2DContextMemDesc); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ2DContextKM: Failed to allocate firmware TQ 2D context (%u)", eError)); goto fail_contextalloc; } psTmpCleanup->psFWTQ2DContextMemDesc = *ppsFWTQ2DContextMemDesc; psTmpCleanup->psDeviceNode = psDeviceNode; /* Temporarily map the firmware TQ 2D context to the kernel. */ eError = DevmemAcquireCpuVirtAddr(*ppsFWTQ2DContextMemDesc, (IMG_VOID **)&psFWTQ2DContext); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ2DContextKM: Failed to map firmware TQ 2D context (%u)", eError)); goto fail_cpuvirtacquire; } /* * Create the FW framework buffer */ eError = PVRSRVRGXFrameworkCreateKM(psDeviceNode, & psFWFrameworkMemDesc, ui32FrameworkRegisterSize); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ2DContextKM: Failed to allocate firmware GPU framework state (%u)", eError)); goto fail_frameworkcreate; } psTmpCleanup->psFWFrameworkMemDesc = psFWFrameworkMemDesc; /* Copy the Framework client data into the framework buffer */ eError = PVRSRVRGXFrameworkCopyRegisters(psFWFrameworkMemDesc, pbyFrameworkRegisters, ui32FrameworkRegisterSize); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ2DContextKM: Failed to populate the framework buffer (%u)", eError)); goto fail_frameworkcopy; } eError = RGXInitFWCommonContext(psFWTQ2DContext, psTQ2DCCBMemDesc, psTQ2DCCBCtlMemDesc, hMemCtxPrivData, psFWFrameworkMemDesc, ui32Priority, IMG_NULL, & psTmpCleanup->sFWComContextCleanup); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ2DContextKM: Failed to init firmware common context (%u)", eError)); goto fail_contextinit; } /* * Dump the TQ2D and the memory contexts */ PDUMPCOMMENT("Dump FWTQ2DContext"); DevmemPDumpLoadMem(*ppsFWTQ2DContextMemDesc, 0, sizeof(*psFWTQ2DContext), PDUMP_FLAGS_CONTINUOUS); /* Release address acquired above. */ DevmemReleaseCpuVirtAddr(*ppsFWTQ2DContextMemDesc); return PVRSRV_OK; fail_contextinit: fail_frameworkcopy: DevmemFwFree(psFWFrameworkMemDesc); fail_frameworkcreate: DevmemReleaseCpuVirtAddr(*ppsFWTQ2DContextMemDesc); fail_cpuvirtacquire: DevmemFwFree(*ppsFWTQ2DContextMemDesc); fail_contextalloc: SyncPrimFree(psTmpCleanup->psCleanupSync); fail_syncalloc: OSFreeMem(psTmpCleanup); return eError; }
void MMU_Finalise(struct MMU_CONTEXT *psMMUContext) { u32 *pui32Tmp, i; struct SYS_DATA *psSysData; struct MMU_CONTEXT **ppsMMUContext; if (SysAcquireData(&psSysData) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "MMU_Finalise: ERROR call to SysAcquireData failed"); return; } PDUMPCOMMENT("Free page directory"); PDUMPFREEPAGETABLE(psMMUContext->pvPDCpuVAddr); pui32Tmp = (u32 *) psMMUContext->pvPDCpuVAddr; for (i = 0; i < SGX_MMU_PD_SIZE; i++) pui32Tmp[i] = 0; if (psMMUContext->psDeviceNode->psLocalDevMemArena == NULL) { OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, SGX_MMU_PAGE_SIZE, psMMUContext->pvPDCpuVAddr, psMMUContext->hPDOSMemHandle); } else { struct IMG_SYS_PHYADDR sSysPAddr; struct IMG_CPU_PHYADDR sCpuPAddr; sCpuPAddr = OSMapLinToCPUPhys(psMMUContext->pvPDCpuVAddr); sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr); OSUnMapPhysToLin((void __iomem __force *) psMMUContext->pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, psMMUContext->hPDOSMemHandle); RA_Free(psMMUContext->psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); } PVR_DPF(PVR_DBG_MESSAGE, "MMU_Finalise"); ppsMMUContext = (struct MMU_CONTEXT **) &psMMUContext->psDevInfo->pvMMUContextList; while (*ppsMMUContext) { if (*ppsMMUContext == psMMUContext) { *ppsMMUContext = psMMUContext->psNext; break; } ppsMMUContext = &((*ppsMMUContext)->psNext); } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct MMU_CONTEXT), psMMUContext, NULL); }
/* Reserve space in the CCB and fill in the command and client sync data */ PVRSRV_ERROR RGXCmdHelperAcquireCmdCCB(IMG_UINT32 ui32CmdCount, RGX_CCB_CMD_HELPER_DATA *asCmdHelperData, IMG_BOOL *pbKickRequired) { IMG_UINT32 ui32BeforeWOff = asCmdHelperData[0].psClientCCB->ui32HostWriteOffset; IMG_UINT32 ui32AllocSize = 0; IMG_UINT32 i; IMG_UINT8 *pui8StartPtr; PVRSRV_ERROR eError; *pbKickRequired = IMG_FALSE; /* Workout how much space we need for all the command(s) */ ui32AllocSize = RGXCmdHelperGetCommandSize(ui32CmdCount, asCmdHelperData); for (i = 0; i < ui32CmdCount; i++) { if (asCmdHelperData[0].bPDumpContinuous != asCmdHelperData[i].bPDumpContinuous) { PVR_DPF((PVR_DBG_ERROR, "%s: PDump continuous is not consistent (%s != %s) for command %d", __FUNCTION__, asCmdHelperData[0].bPDumpContinuous?"IMG_TRUE":"IMG_FALSE", asCmdHelperData[i].bPDumpContinuous?"IMG_TRUE":"IMG_FALSE", ui32CmdCount)); return PVRSRV_ERROR_INVALID_PARAMS; } } /* Acquire space in the CCB for all the command(s). */ eError = RGXAcquireCCB(asCmdHelperData[0].psClientCCB, ui32AllocSize, (IMG_PVOID *)&pui8StartPtr, asCmdHelperData[0].bPDumpContinuous); if (eError != PVRSRV_OK) { /* Failed so bail out and allow the client side to retry */ if (asCmdHelperData[0].psClientCCB->ui32HostWriteOffset != ui32BeforeWOff) { *pbKickRequired = IMG_TRUE; } return eError; } /* For each command fill in the fence, DM, and update command Note: We only fill in the client fences here, the server fences (and updates) will be filled in together at the end. This is because we might fail the kernel CCB alloc and would then have to rollback the server syncs if we took the operation here */ for (i = 0; i < ui32CmdCount; i++) { RGX_CCB_CMD_HELPER_DATA *psCmdHelperData = & asCmdHelperData[i]; IMG_UINT8 *pui8CmdPtr; IMG_UINT8 *pui8ServerFenceStart = 0; IMG_UINT8 *pui8ServerUpdateStart = 0; #if defined(PDUMP) IMG_UINT32 ui32CtxAddr = FWCommonContextGetFWAddress(asCmdHelperData->psClientCCB->psServerCommonContext).ui32Addr; IMG_UINT32 ui32CcbWoff = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(asCmdHelperData->psClientCCB->psServerCommonContext)); #endif if (psCmdHelperData->ui32ClientFenceCount+psCmdHelperData->ui32ClientUpdateCount != 0) { PDUMPCOMMENT("Start of %s client syncs for cmd[%d] on FWCtx %08x Woff 0x%x bytes", psCmdHelperData->psClientCCB->szName, i, ui32CtxAddr, ui32CcbWoff); } /* Create the fence command. */ if (psCmdHelperData->ui32FenceCmdSize) { RGXFWIF_CCB_CMD_HEADER *psHeader; IMG_UINT k; /* Fences are at the start of the command */ pui8CmdPtr = pui8StartPtr; psHeader = (RGXFWIF_CCB_CMD_HEADER *) pui8CmdPtr; psHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_FENCE; psHeader->ui32CmdSize = psCmdHelperData->ui32FenceCmdSize - sizeof(RGXFWIF_CCB_CMD_HEADER); pui8CmdPtr += sizeof(RGXFWIF_CCB_CMD_HEADER); /* Fill in the client fences */ for (k = 0; k < psCmdHelperData->ui32ClientFenceCount; k++) { RGXFWIF_UFO *psUFOPtr = (RGXFWIF_UFO *) pui8CmdPtr; psUFOPtr->puiAddrUFO = psCmdHelperData->pauiFenceUFOAddress[k]; psUFOPtr->ui32Value = psCmdHelperData->paui32FenceValue[k]; pui8CmdPtr += sizeof(RGXFWIF_UFO); #if defined SYNC_COMMAND_DEBUG PVR_DPF((PVR_DBG_ERROR, "%s client sync fence - 0x%x -> 0x%x", psCmdHelperData->psClientCCB->szName, psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value)); #endif PDUMPCOMMENT(".. %s client sync fence - 0x%x -> 0x%x", psCmdHelperData->psClientCCB->szName, psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value); } pui8ServerFenceStart = pui8CmdPtr; } /* jump over the Server fences */ pui8CmdPtr = pui8StartPtr + psCmdHelperData->ui32FenceCmdSize; /* Create the pre DM timestamp commands. Pre and Post timestamp commands are supposed to sandwich the DM cmd. The padding code with the CCB wrap upsets the FW if we don't have the task type bit cleared for POST_TIMESTAMPs. That's why we have 2 different cmd types. */ if (psCmdHelperData->ui32PreTimeStampCmdSize != 0) { RGXWriteTimestampCommand(& pui8CmdPtr, RGXFWIF_CCB_CMD_TYPE_PRE_TIMESTAMP, psCmdHelperData->pPreTimestampAddr); } /* Create the DM command */ if (psCmdHelperData->ui32DMCmdSize) { RGXFWIF_CCB_CMD_HEADER *psHeader; psHeader = (RGXFWIF_CCB_CMD_HEADER *) pui8CmdPtr; psHeader->eCmdType = psCmdHelperData->eType; psHeader->ui32CmdSize = psCmdHelperData->ui32DMCmdSize - sizeof(RGXFWIF_CCB_CMD_HEADER); pui8CmdPtr += sizeof(RGXFWIF_CCB_CMD_HEADER); OSMemCopy(pui8CmdPtr, psCmdHelperData->pui8DMCmd, psCmdHelperData->ui32CmdSize); pui8CmdPtr += psCmdHelperData->ui32CmdSize; } if (psCmdHelperData->ui32PostTimeStampCmdSize != 0) { RGXWriteTimestampCommand(& pui8CmdPtr, RGXFWIF_CCB_CMD_TYPE_POST_TIMESTAMP, psCmdHelperData->pPostTimestampAddr); } if (psCmdHelperData->ui32RMWUFOCmdSize != 0) { RGXFWIF_CCB_CMD_HEADER * psHeader; RGXFWIF_UFO * psUFO; psHeader = (RGXFWIF_CCB_CMD_HEADER *) pui8CmdPtr; psHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_RMW_UPDATE; psHeader->ui32CmdSize = psCmdHelperData->ui32RMWUFOCmdSize - sizeof(RGXFWIF_CCB_CMD_HEADER); pui8CmdPtr += sizeof(RGXFWIF_CCB_CMD_HEADER); psUFO = (RGXFWIF_UFO *) pui8CmdPtr; psUFO->puiAddrUFO = psCmdHelperData->pRMWUFOAddr; pui8CmdPtr += sizeof(RGXFWIF_UFO); } /* Create the update command. Note: We only fill in the client updates here, the server updates (and fences) will be filled in together at the end */ if (psCmdHelperData->ui32UpdateCmdSize) { RGXFWIF_CCB_CMD_HEADER *psHeader; IMG_UINT k; psHeader = (RGXFWIF_CCB_CMD_HEADER *) pui8CmdPtr; psHeader->eCmdType = RGXFWIF_CCB_CMD_TYPE_UPDATE; psHeader->ui32CmdSize = psCmdHelperData->ui32UpdateCmdSize - sizeof(RGXFWIF_CCB_CMD_HEADER); pui8CmdPtr += sizeof(RGXFWIF_CCB_CMD_HEADER); /* Fill in the client updates */ for (k = 0; k < psCmdHelperData->ui32ClientUpdateCount; k++) { RGXFWIF_UFO *psUFOPtr = (RGXFWIF_UFO *) pui8CmdPtr; psUFOPtr->puiAddrUFO = psCmdHelperData->pauiUpdateUFOAddress[k]; psUFOPtr->ui32Value = psCmdHelperData->paui32UpdateValue[k]; pui8CmdPtr += sizeof(RGXFWIF_UFO); #if defined SYNC_COMMAND_DEBUG PVR_DPF((PVR_DBG_ERROR, "%s client sync update - 0x%x -> 0x%x", psCmdHelperData->psClientCCB->szName, psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value)); #endif PDUMPCOMMENT(".. %s client sync update - 0x%x -> 0x%x", psCmdHelperData->psClientCCB->szName, psUFOPtr->puiAddrUFO.ui32Addr, psUFOPtr->ui32Value); } pui8ServerUpdateStart = pui8CmdPtr; } /* Save the server sync fence & update offsets for submit time */ psCmdHelperData->pui8ServerFenceStart = pui8ServerFenceStart; psCmdHelperData->pui8ServerUpdateStart = pui8ServerUpdateStart; /* Save start for sanity checking at submit time */ psCmdHelperData->pui8StartPtr = pui8StartPtr; /* Set the start pointer for the next iteration around the loop */ pui8StartPtr += psCmdHelperData->ui32FenceCmdSize + psCmdHelperData->ui32PreTimeStampCmdSize + psCmdHelperData->ui32DMCmdSize + psCmdHelperData->ui32PostTimeStampCmdSize + psCmdHelperData->ui32RMWUFOCmdSize + psCmdHelperData->ui32UpdateCmdSize; if (psCmdHelperData->ui32ClientFenceCount+psCmdHelperData->ui32ClientUpdateCount != 0) { PDUMPCOMMENT("End of %s client syncs for cmd[%d] on FWCtx %08x Woff 0x%x bytes", psCmdHelperData->psClientCCB->szName, i, ui32CtxAddr, ui32CcbWoff); } else { PDUMPCOMMENT("No %s client syncs for cmd[%d] on FWCtx %08x Woff 0x%x bytes", psCmdHelperData->psClientCCB->szName, i, ui32CtxAddr, ui32CcbWoff); } } *pbKickRequired = IMG_TRUE; return PVRSRV_OK; }
IMG_VOID PDumpInit(IMG_VOID) { IMG_UINT32 i; DBGKM_CONNECT_NOTIFIER sConnectNotifier; if (!gpfnDbgDrv) { DBGDrvGetServiceTable((IMG_VOID **)&gpfnDbgDrv); if (gpfnDbgDrv == IMG_NULL) { return; } sConnectNotifier.pfnConnectNotifier = &PDumpConnectionNotify; gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier); if(!gsDBGPdumpState.pszFile) { if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszFile, 0, "Filename string") != PVRSRV_OK) { goto init_failed; } } if(!gsDBGPdumpState.pszMsg) { if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszMsg, 0, "Message string") != PVRSRV_OK) { goto init_failed; } } if(!gsDBGPdumpState.pszScript) { if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszScript, 0, "Script string") != PVRSRV_OK) { goto init_failed; } } for(i=0; i < PDUMP_NUM_STREAMS; i++) { gsDBGPdumpState.psStream[i] = gpfnDbgDrv->pfnCreateStream(pszStreamName[i], DEBUG_CAPMODE_FRAMED, DEBUG_OUTMODE_STREAMENABLE, 0, 10); gpfnDbgDrv->pfnSetCaptureMode(gsDBGPdumpState.psStream[i],DEBUG_CAPMODE_FRAMED,0xFFFFFFFF, 0xFFFFFFFF, 1); gpfnDbgDrv->pfnSetFrame(gsDBGPdumpState.psStream[i],0); } PDUMPCOMMENT("Driver Product Name: %s", VS_PRODUCT_NAME); PDUMPCOMMENT("Driver Product Version: %s (%s)", PVRVERSION_STRING, PVRVERSION_FILE); PDUMPCOMMENT("Start of Init Phase"); } return; init_failed: if(gsDBGPdumpState.pszFile) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszFile, 0); gsDBGPdumpState.pszFile = IMG_NULL; } if(gsDBGPdumpState.pszScript) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszScript, 0); gsDBGPdumpState.pszScript = IMG_NULL; } if(gsDBGPdumpState.pszMsg) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszMsg, 0); gsDBGPdumpState.pszMsg = IMG_NULL; } sConnectNotifier.pfnConnectNotifier = 0; gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier); gpfnDbgDrv = IMG_NULL; }
static void _DeferredFreePageTable(struct MMU_HEAP *pMMUHeap, u32 ui32PTIndex) { u32 *pui32PDEntry; u32 i; u32 ui32PDIndex; struct SYS_DATA *psSysData; struct MMU_PT_INFO **ppsPTInfoList; if (SysAcquireData(&psSysData) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "_DeferredFreePageTables: " "ERROR call to SysAcquireData failed"); return; } ui32PDIndex = pMMUHeap->psDevArena->BaseDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; { PVR_ASSERT(ppsPTInfoList[ui32PTIndex] == NULL || ppsPTInfoList[ui32PTIndex]->ui32ValidPTECount == 0); } PDUMPCOMMENT("Free page table (page count == %08X)", pMMUHeap->ui32PTPageCount); if (ppsPTInfoList[ui32PTIndex] && ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr) PDUMPFREEPAGETABLE(ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr); switch (pMMUHeap->psDevArena->DevMemHeapType) { case DEVICE_MEMORY_HEAP_SHARED: case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: { struct MMU_CONTEXT *psMMUContext = (struct MMU_CONTEXT *) pMMUHeap->psMMUContext->psDevInfo->pvMMUContextList; while (psMMUContext) { pui32PDEntry = (u32 *) psMMUContext->pvPDCpuVAddr; pui32PDEntry += ui32PDIndex; pui32PDEntry[ui32PTIndex] = 0; PDUMPPAGETABLE((void *) &pui32PDEntry [ui32PTIndex], sizeof(u32), IMG_FALSE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); psMMUContext = psMMUContext->psNext; } break; } case DEVICE_MEMORY_HEAP_PERCONTEXT: case DEVICE_MEMORY_HEAP_KERNEL: { pui32PDEntry = (u32 *) pMMUHeap->psMMUContext->pvPDCpuVAddr; pui32PDEntry += ui32PDIndex; pui32PDEntry[ui32PTIndex] = 0; PDUMPPAGETABLE((void *) &pui32PDEntry[ui32PTIndex], sizeof(u32), IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); break; } default: { PVR_DPF(PVR_DBG_ERROR, "_DeferredFreePagetable: ERROR invalid heap type"); return; } } if (ppsPTInfoList[ui32PTIndex] != NULL) { if (ppsPTInfoList[ui32PTIndex]->PTPageCpuVAddr != NULL) { u32 *pui32Tmp; pui32Tmp = (u32 *) ppsPTInfoList[ui32PTIndex]-> PTPageCpuVAddr; for (i = 0; (i < pMMUHeap->ui32PTEntryCount) && (i < 1024); i++) pui32Tmp[i] = 0; if (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo-> psLocalDevMemArena == NULL) { OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, SGX_MMU_PAGE_SIZE, ppsPTInfoList[ui32PTIndex]-> PTPageCpuVAddr, ppsPTInfoList[ui32PTIndex]-> hPTPageOSMemHandle); } else { struct IMG_SYS_PHYADDR sSysPAddr; struct IMG_CPU_PHYADDR sCpuPAddr; sCpuPAddr = OSMapLinToCPUPhys(ppsPTInfoList [ui32PTIndex]-> PTPageCpuVAddr); sSysPAddr = SysCpuPAddrToSysPAddr(sCpuPAddr); OSUnMapPhysToLin((void __force __iomem *) ppsPTInfoList[ui32PTIndex]-> PTPageCpuVAddr, SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, ppsPTInfoList[ui32PTIndex]-> hPTPageOSMemHandle); RA_Free(pMMUHeap->psDevArena-> psDeviceMemoryHeapInfo-> psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); } pMMUHeap->ui32PTEntryCount -= i; } else { pMMUHeap->ui32PTEntryCount -= 1024; } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct MMU_PT_INFO), ppsPTInfoList[ui32PTIndex], NULL); ppsPTInfoList[ui32PTIndex] = NULL; } else { pMMUHeap->ui32PTEntryCount -= 1024; } PDUMPCOMMENT("Finished free page table (page count == %08X)", pMMUHeap->ui32PTPageCount); }
void PDumpInit(void) { u32 i = 0; if (!gpfnDbgDrv) { DBGDrvGetServiceTable((void **) &gpfnDbgDrv); if (gpfnDbgDrv == NULL) return; if (!gsDBGPdumpState.pszFile) if (OSAllocMem (PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (void **) &gsDBGPdumpState.pszFile, 0) != PVRSRV_OK) goto init_failed; if (!gsDBGPdumpState.pszMsg) if (OSAllocMem (PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (void **) &gsDBGPdumpState.pszMsg, 0) != PVRSRV_OK) goto init_failed; if (!gsDBGPdumpState.pszScript) if (OSAllocMem (PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (void **) &gsDBGPdumpState.pszScript, 0) != PVRSRV_OK) goto init_failed; for (i = 0; i < PDUMP_NUM_STREAMS; i++) { gsDBGPdumpState.psStream[i] = gpfnDbgDrv->pfnCreateStream(pszStreamName[i], DEBUG_CAPMODE_FRAMED, DEBUG_OUTMODE_STREAMENABLE, 0, 10); gpfnDbgDrv->pfnSetCaptureMode(gsDBGPdumpState. psStream[i], DEBUG_CAPMODE_FRAMED, 0xFFFFFFFF, 0xFFFFFFFF, 1); gpfnDbgDrv->pfnSetFrame(gsDBGPdumpState.psStream[i], 0); } PDUMPCOMMENT("Driver Product Name: %s", VS_PRODUCT_NAME); PDUMPCOMMENT("Driver Product Version: %s (%s)", PVRVERSION_STRING, PVRVERSION_FILE); PDUMPCOMMENT("Start of Init Phase"); } return; init_failed: if (gsDBGPdumpState.pszFile) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (void *) gsDBGPdumpState.pszFile, 0); gsDBGPdumpState.pszFile = NULL; } if (gsDBGPdumpState.pszScript) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (void *) gsDBGPdumpState.pszScript, 0); gsDBGPdumpState.pszScript = NULL; } if (gsDBGPdumpState.pszMsg) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (void *) gsDBGPdumpState.pszMsg, 0); gsDBGPdumpState.pszMsg = NULL; } gpfnDbgDrv = NULL; }
PVRSRV_ERROR SGXDoKickKM(void *hDevHandle, SGX_CCB_KICK * psCCBKick) { PVRSRV_ERROR eError; PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *) psCCBKick->hCCBKernelMemInfo; SGXMKIF_CMDTA_SHARED *psTACmd; u32 i; #if defined(SUPPORT_SGX_HWPERF) PVRSRV_DEVICE_NODE *psDeviceNode; PVRSRV_SGXDEV_INFO *psDevInfo; psDeviceNode = (PVRSRV_DEVICE_NODE *) hDevHandle; psDevInfo = (PVRSRV_SGXDEV_INFO *) psDeviceNode->pvDevice; #endif #if defined(SUPPORT_SGX_HWPERF) if (psCCBKick->bKickRender) { ++psDevInfo->ui32KickTARenderCounter; } ++psDevInfo->ui32KickTACounter; #endif if (!CCB_OFFSET_IS_VALID (SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset)) { PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: Invalid CCB offset")); return PVRSRV_ERROR_INVALID_PARAMS; } psTACmd = CCB_DATA_FROM_OFFSET(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset); if (psCCBKick->hTA3DSyncInfo) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->hTA3DSyncInfo; psTACmd->sTA3DDependency.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->sTA3DDependency.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; if (psCCBKick->bTADependency) { psSyncInfo->psSyncData->ui32WriteOpsPending++; } } if (psCCBKick->hTASyncInfo != NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->hTASyncInfo; psTACmd->sTATQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->sTATQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->ui32TATQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; psTACmd->ui32TATQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } if (psCCBKick->h3DSyncInfo != NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->h3DSyncInfo; psTACmd->s3DTQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->s3DTQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->ui323DTQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; psTACmd->ui323DTQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } psTACmd->ui32NumTAStatusVals = psCCBKick->ui32NumTAStatusVals; if (psCCBKick->ui32NumTAStatusVals != 0) { for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) { #if defined(SUPPORT_SGX_NEW_STATUS_VALS) psTACmd->sCtlTAStatusInfo[i] = psCCBKick->asTAStatusUpdate[i].sCtlStatus; #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ahTAStatusSyncInfo[i]; psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->sCtlTAStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending; #endif } } psTACmd->ui32Num3DStatusVals = psCCBKick->ui32Num3DStatusVals; if (psCCBKick->ui32Num3DStatusVals != 0) { for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) { #if defined(SUPPORT_SGX_NEW_STATUS_VALS) psTACmd->sCtl3DStatusInfo[i] = psCCBKick->as3DStatusUpdate[i].sCtlStatus; #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ah3DStatusSyncInfo[i]; psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->sCtl3DStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending; #endif } } #if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) psTACmd->ui32NumTASrcSyncs = psCCBKick->ui32NumTASrcSyncs; for (i = 0; i < psCCBKick->ui32NumTASrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ahTASrcKernelSyncInfo[i]; psTACmd->asTASrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->asTASrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->asTASrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; psTACmd->asTASrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } psTACmd->ui32NumTADstSyncs = psCCBKick->ui32NumTADstSyncs; for (i = 0; i < psCCBKick->ui32NumTADstSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ahTADstKernelSyncInfo[i]; psTACmd->asTADstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->asTADstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->asTADstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psTACmd->asTADstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; } psTACmd->ui32Num3DSrcSyncs = psCCBKick->ui32Num3DSrcSyncs; for (i = 0; i < psCCBKick->ui32Num3DSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ah3DSrcKernelSyncInfo[i]; psTACmd->as3DSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->as3DSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->as3DSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; psTACmd->as3DSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } #else psTACmd->ui32NumSrcSyncs = psCCBKick->ui32NumSrcSyncs; for (i = 0; i < psCCBKick->ui32NumSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ahSrcKernelSyncInfo[i]; psTACmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; psTACmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } #endif if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0) { PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo = (PVRSRV_KERNEL_MEM_INFO *) psCCBKick-> hKernelHWSyncListMemInfo; SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM; u32 ui32NumDstSyncs = psCCBKick->ui32NumDstSyncObjects; PVR_ASSERT(((PVRSRV_KERNEL_MEM_INFO *) psCCBKick-> hKernelHWSyncListMemInfo)->ui32AllocSize >= (sizeof(SGXMKIF_HWDEVICE_SYNC_LIST) + (sizeof(PVRSRV_DEVICE_SYNC_OBJECT) * ui32NumDstSyncs))); psHWDeviceSyncList->ui32NumSyncObjects = ui32NumDstSyncs; #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { PDUMPCOMMENT("HWDeviceSyncList for TACmd\r\n"); PDUMPMEM(NULL, psHWDstSyncListMemInfo, 0, sizeof(SGXMKIF_HWDEVICE_SYNC_LIST), 0, MAKEUNIQUETAG(psHWDstSyncListMemInfo)); } #endif for (i = 0; i < ui32NumDstSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> pahDstSyncHandles[i]; if (psSyncInfo) { psHWDeviceSyncList->asSyncData[i]. sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psHWDeviceSyncList->asSyncData[i]. sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psHWDeviceSyncList->asSyncData[i]. ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psHWDeviceSyncList->asSyncData[i]. ui32WriteOpsPendingVal = psSyncInfo->psSyncData-> ui32WriteOpsPending++; #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { u32 ui32ModifiedValue; u32 ui32SyncOffset = offsetof(SGXMKIF_HWDEVICE_SYNC_LIST, asSyncData) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)); u32 ui32WOpsOffset = ui32SyncOffset + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal); u32 ui32ROpsOffset = ui32SyncOffset + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal); PDUMPCOMMENT ("HWDeviceSyncObject for RT: %i\r\n", i); PDUMPMEM(NULL, psHWDstSyncListMemInfo, ui32SyncOffset, sizeof (PVRSRV_DEVICE_SYNC_OBJECT), 0, MAKEUNIQUETAG (psHWDstSyncListMemInfo)); if ((psSyncInfo->psSyncData-> ui32LastOpDumpVal == 0) && (psSyncInfo->psSyncData-> ui32LastReadOpDumpVal == 0)) { PDUMPCOMMENT ("Init RT ROpsComplete\r\n", i); PDUMPMEM(&psSyncInfo-> psSyncData-> ui32LastReadOpDumpVal, psSyncInfo-> psSyncDataMemInfoKM, offsetof (PVRSRV_SYNC_DATA, ui32ReadOpsComplete), sizeof(psSyncInfo-> psSyncData-> ui32ReadOpsComplete), 0, MAKEUNIQUETAG (psSyncInfo-> psSyncDataMemInfoKM)); PDUMPCOMMENT ("Init RT WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo-> psSyncData-> ui32LastOpDumpVal, psSyncInfo-> psSyncDataMemInfoKM, offsetof (PVRSRV_SYNC_DATA, ui32WriteOpsComplete), sizeof(psSyncInfo-> psSyncData-> ui32WriteOpsComplete), 0, MAKEUNIQUETAG (psSyncInfo-> psSyncDataMemInfoKM)); } psSyncInfo->psSyncData-> ui32LastOpDumpVal++; ui32ModifiedValue = psSyncInfo->psSyncData-> ui32LastOpDumpVal - 1; PDUMPCOMMENT ("Modify RT %d WOpPendingVal in HWDevSyncList\r\n", i); PDUMPMEM(&ui32ModifiedValue, psHWDstSyncListMemInfo, ui32WOpsOffset, sizeof(u32), 0, MAKEUNIQUETAG (psHWDstSyncListMemInfo)); ui32ModifiedValue = 0; PDUMPCOMMENT ("Modify RT %d ROpsPendingVal in HWDevSyncList\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData-> ui32LastReadOpDumpVal, psHWDstSyncListMemInfo, ui32ROpsOffset, sizeof(u32), 0, MAKEUNIQUETAG (psHWDstSyncListMemInfo)); } #endif } else { psHWDeviceSyncList->asSyncData[i]. sWriteOpsCompleteDevVAddr.uiAddr = 0; psHWDeviceSyncList->asSyncData[i]. sReadOpsCompleteDevVAddr.uiAddr = 0; psHWDeviceSyncList->asSyncData[i]. ui32ReadOpsPendingVal = 0; psHWDeviceSyncList->asSyncData[i]. ui32WriteOpsPendingVal = 0; } } } psTACmd->ui32CtrlFlags |= SGXMKIF_CMDTA_CTRLFLAGS_READY; #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { PDUMPCOMMENT("Shared part of TA command\r\n"); PDUMPMEM(psTACmd, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff, sizeof(SGXMKIF_CMDTA_SHARED), 0, MAKEUNIQUETAG(psCCBMemInfo)); #if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) for (i = 0; i < psCCBKick->ui32NumTASrcSyncs; i++) { u32 ui32ModifiedValue; psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ahTASrcKernelSyncInfo[i]; if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) { PDUMPCOMMENT("Init RT TA-SRC ROpsComplete\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData-> ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), sizeof(psSyncInfo->psSyncData-> ui32ReadOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo-> psSyncDataMemInfoKM)); PDUMPCOMMENT("Init RT TA-SRC WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData-> ui32LastOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), sizeof(psSyncInfo->psSyncData-> ui32WriteOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo-> psSyncDataMemInfoKM)); } psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1; PDUMPCOMMENT("Modify TA SrcSync %d ROpsPendingVal\r\n", i); PDUMPMEM(&ui32ModifiedValue, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Modify TA SrcSync %d WOpPendingVal\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo)); } for (i = 0; i < psCCBKick->ui32NumTADstSyncs; i++) { u32 ui32ModifiedValue; psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ahTADstKernelSyncInfo[i]; if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) { PDUMPCOMMENT("Init RT TA-DST ROpsComplete\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData-> ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), sizeof(psSyncInfo->psSyncData-> ui32ReadOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo-> psSyncDataMemInfoKM)); PDUMPCOMMENT("Init RT TA-DST WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData-> ui32LastOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), sizeof(psSyncInfo->psSyncData-> ui32WriteOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo-> psSyncDataMemInfoKM)); } psSyncInfo->psSyncData->ui32LastOpDumpVal++; ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1; PDUMPCOMMENT("Modify TA DstSync %d WOpPendingVal\r\n", i); PDUMPMEM(&ui32ModifiedValue, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Modify TA DstSync %d ROpsPendingVal\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo)); } for (i = 0; i < psCCBKick->ui32Num3DSrcSyncs; i++) { u32 ui32ModifiedValue; psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ah3DSrcKernelSyncInfo[i]; if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) { PDUMPCOMMENT("Init RT 3D-SRC ROpsComplete\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData-> ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), sizeof(psSyncInfo->psSyncData-> ui32ReadOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo-> psSyncDataMemInfoKM)); PDUMPCOMMENT("Init RT 3D-SRC WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData-> ui32LastOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), sizeof(psSyncInfo->psSyncData-> ui32WriteOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo-> psSyncDataMemInfoKM)); } psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1; PDUMPCOMMENT("Modify 3D SrcSync %d ROpsPendingVal\r\n", i); PDUMPMEM(&ui32ModifiedValue, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Modify 3D SrcSync %d WOpPendingVal\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo)); } #else for (i = 0; i < psCCBKick->ui32NumSrcSyncs; i++) { u32 ui32ModifiedValue; psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ahSrcKernelSyncInfo[i]; if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) { PDUMPCOMMENT("Init RT ROpsComplete\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData-> ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), sizeof(psSyncInfo->psSyncData-> ui32ReadOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo-> psSyncDataMemInfoKM)); PDUMPCOMMENT("Init RT WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData-> ui32LastOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), sizeof(psSyncInfo->psSyncData-> ui32WriteOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo-> psSyncDataMemInfoKM)); } psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1; PDUMPCOMMENT("Modify SrcSync %d ROpsPendingVal\r\n", i); PDUMPMEM(&ui32ModifiedValue, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Modify SrcSync %d WOpPendingVal\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo)); } #endif for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) { #if defined(SUPPORT_SGX_NEW_STATUS_VALS) PDUMPCOMMENT("Modify TA status value in TA cmd\r\n"); PDUMPMEM(&psCCBKick->asTAStatusUpdate[i]. ui32LastStatusUpdateDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, sCtlTAStatusInfo[i].ui32StatusValue), sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo)); #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ahTAStatusSyncInfo[i]; PDUMPCOMMENT("Modify TA status value in TA cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, sCtlTAStatusInfo[i].ui32StatusValue), sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo)); #endif } for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) { #if defined(SUPPORT_SGX_NEW_STATUS_VALS) PDUMPCOMMENT("Modify 3D status value in TA cmd\r\n"); PDUMPMEM(&psCCBKick->as3DStatusUpdate[i]. ui32LastStatusUpdateDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, sCtl3DStatusInfo[i].ui32StatusValue), sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo)); #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ah3DStatusSyncInfo[i]; PDUMPCOMMENT("Modify 3D status value in TA cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, sCtl3DStatusInfo[i].ui32StatusValue), sizeof(u32), 0, MAKEUNIQUETAG(psCCBMemInfo)); #endif } } #endif eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TA, &psCCBKick->sCommand, KERNEL_ID, 0); if (eError == PVRSRV_ERROR_RETRY) { if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0) { for (i = 0; i < psCCBKick->ui32NumDstSyncObjects; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> pahDstSyncHandles[i]; if (psSyncInfo) { psSyncInfo->psSyncData-> ui32WriteOpsPending--; #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { psSyncInfo->psSyncData-> ui32LastOpDumpVal--; } #endif } } } #if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) for (i = 0; i < psCCBKick->ui32NumTASrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ahTASrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending--; } for (i = 0; i < psCCBKick->ui32NumTADstSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ahTADstKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32WriteOpsPending--; } for (i = 0; i < psCCBKick->ui32Num3DSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ah3DSrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending--; } #else for (i = 0; i < psCCBKick->ui32NumSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ahSrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending--; } #endif return eError; } else if (PVRSRV_OK != eError) { PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: SGXScheduleCCBCommandKM failed.")); return eError; } #if defined(NO_HARDWARE) if (psCCBKick->hTA3DSyncInfo) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->hTA3DSyncInfo; if (psCCBKick->bTADependency) { psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } } if (psCCBKick->hTASyncInfo != NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->hTASyncInfo; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } if (psCCBKick->h3DSyncInfo != NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) { #if defined(SUPPORT_SGX_NEW_STATUS_VALS) PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO *) psCCBKick->asTAStatusUpdate[i]. hKernelMemInfo; *(u32 *) ((u32) psKernelMemInfo->pvLinAddrKM + (psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr.uiAddr - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue; #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ahTAStatusSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue; #endif } #if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) for (i = 0; i < psCCBKick->ui32NumTASrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ahTASrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } for (i = 0; i < psCCBKick->ui32NumTADstSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ahTADstKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } for (i = 0; i < psCCBKick->ui32Num3DSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ah3DSrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } #else for (i = 0; i < psCCBKick->ui32NumSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ahSrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } #endif if (psCCBKick->bTerminateOrAbort) { if (psCCBKick->ui32NumDstSyncObjects > 0) { PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo = (PVRSRV_KERNEL_MEM_INFO *) psCCBKick-> hKernelHWSyncListMemInfo; SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM; for (i = 0; i < psCCBKick->ui32NumDstSyncObjects; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> pahDstSyncHandles[i]; if (psSyncInfo) psSyncInfo->psSyncData-> ui32WriteOpsComplete = psHWDeviceSyncList->asSyncData[i]. ui32WriteOpsPendingVal + 1; } } for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) { #if defined(SUPPORT_SGX_NEW_STATUS_VALS) PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO *) psCCBKick-> as3DStatusUpdate[i].hKernelMemInfo; *(u32 *) ((u32) psKernelMemInfo->pvLinAddrKM + (psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr. uiAddr - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue; #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick-> ah3DStatusSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue; #endif } } #endif return eError; }
static IMG_BOOL _DeferredAllocPagetables(struct MMU_HEAP *pMMUHeap, struct IMG_DEV_VIRTADDR DevVAddr, u32 ui32Size) { u32 ui32PTPageCount; u32 ui32PDIndex; u32 i; u32 *pui32PDEntry; struct MMU_PT_INFO **ppsPTInfoList; struct SYS_DATA *psSysData; struct IMG_DEV_VIRTADDR sHighDevVAddr; PVR_ASSERT(DevVAddr.uiAddr < (1 << SGX_FEATURE_ADDRESS_SPACE_SIZE)); if (SysAcquireData(&psSysData) != PVRSRV_OK) return IMG_FALSE; ui32PDIndex = DevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); if ((UINT32_MAX_VALUE - DevVAddr.uiAddr) < (ui32Size + (1 << (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT)) - 1)) { sHighDevVAddr.uiAddr = UINT32_MAX_VALUE; } else { sHighDevVAddr.uiAddr = DevVAddr.uiAddr + ui32Size + (1 << (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT)) - 1; } ui32PTPageCount = sHighDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT); ui32PTPageCount -= ui32PDIndex; pui32PDEntry = (u32 *) pMMUHeap->psMMUContext->pvPDCpuVAddr; pui32PDEntry += ui32PDIndex; ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex]; PDUMPCOMMENT("Alloc page table (page count == %08X)", ui32PTPageCount); PDUMPCOMMENT("Page directory mods (page count == %08X)", ui32PTPageCount); for (i = 0; i < ui32PTPageCount; i++) { if (ppsPTInfoList[i] == NULL) { if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct MMU_PT_INFO), (void **) &ppsPTInfoList[i], NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "_DeferredAllocPagetables: " "ERROR call to OSAllocMem failed"); return IMG_FALSE; } OSMemSet(ppsPTInfoList[i], 0, sizeof(struct MMU_PT_INFO)); } if (ppsPTInfoList[i]->hPTPageOSMemHandle == NULL && ppsPTInfoList[i]->PTPageCpuVAddr == NULL) { struct IMG_CPU_PHYADDR sCpuPAddr; struct IMG_DEV_PHYADDR sDevPAddr; PVR_ASSERT(pui32PDEntry[i] == 0); if (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo-> psLocalDevMemArena == NULL) { if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, (void **)&ppsPTInfoList[i]-> PTPageCpuVAddr, &ppsPTInfoList[i]-> hPTPageOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "_DeferredAllocPagetables: " "ERROR call to OSAllocPages failed"); return IMG_FALSE; } if (ppsPTInfoList[i]->PTPageCpuVAddr) { sCpuPAddr = OSMapLinToCPUPhys(ppsPTInfoList[i]-> PTPageCpuVAddr); } else { sCpuPAddr = OSMemHandleToCpuPAddr( ppsPTInfoList[i]-> hPTPageOSMemHandle, 0); } sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); } else { struct IMG_SYS_PHYADDR sSysPAddr; if (RA_Alloc(pMMUHeap->psDevArena-> psDeviceMemoryHeapInfo->psLocalDevMemArena, SGX_MMU_PAGE_SIZE, NULL, 0, SGX_MMU_PAGE_SIZE, &(sSysPAddr.uiAddr)) != IMG_TRUE) { PVR_DPF(PVR_DBG_ERROR, "_DeferredAllocPagetables: " "ERROR call to RA_Alloc failed"); return IMG_FALSE; } sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); ppsPTInfoList[i]->PTPageCpuVAddr = (void __force *) OSMapPhysToLin(sCpuPAddr, SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, &ppsPTInfoList[i]-> hPTPageOSMemHandle); if (!ppsPTInfoList[i]->PTPageCpuVAddr) { PVR_DPF(PVR_DBG_ERROR, "_DeferredAllocPagetables: " "ERROR failed to map page tables"); return IMG_FALSE; } sDevPAddr = SysCpuPAddrToDevPAddr (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); } OSMemSet(ppsPTInfoList[i]->PTPageCpuVAddr, 0, SGX_MMU_PAGE_SIZE); PDUMPMALLOCPAGETABLE(ppsPTInfoList[i]->PTPageCpuVAddr, PDUMP_PT_UNIQUETAG); PDUMPPAGETABLE(ppsPTInfoList[i]->PTPageCpuVAddr, SGX_MMU_PAGE_SIZE, IMG_TRUE, PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG); switch (pMMUHeap->psDevArena->DevMemHeapType) { case DEVICE_MEMORY_HEAP_SHARED: case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: { struct MMU_CONTEXT *psMMUContext = (struct MMU_CONTEXT *)pMMUHeap-> psMMUContext->psDevInfo-> pvMMUContextList; while (psMMUContext) { pui32PDEntry = (u32 *)psMMUContext-> pvPDCpuVAddr; pui32PDEntry += ui32PDIndex; pui32PDEntry[i] = sDevPAddr.uiAddr | SGX_MMU_PDE_VALID; PDUMPPAGETABLE ((void *)&pui32PDEntry[i], sizeof(u32), IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); psMMUContext = psMMUContext->psNext; } break; } case DEVICE_MEMORY_HEAP_PERCONTEXT: case DEVICE_MEMORY_HEAP_KERNEL: { pui32PDEntry[i] = sDevPAddr.uiAddr | SGX_MMU_PDE_VALID; PDUMPPAGETABLE((void *)&pui32PDEntry[i], sizeof(u32), IMG_FALSE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); break; } default: { PVR_DPF(PVR_DBG_ERROR, "_DeferredAllocPagetables: " "ERROR invalid heap type"); return IMG_FALSE; } } MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext-> psDevInfo); } else { PVR_ASSERT(pui32PDEntry[i] != 0); } } return IMG_TRUE; }
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; }
/* * PVRSRVSubmitTQ3DKickKM */ IMG_EXPORT PVRSRV_ERROR PVRSRVRGXSubmitTransferKM(RGX_SERVER_TQ_CONTEXT *psTransferContext, IMG_UINT32 ui32PrepareCount, IMG_UINT32 *paui32ClientFenceCount, PRGXFWIF_UFO_ADDR **papauiClientFenceUFOAddress, IMG_UINT32 **papaui32ClientFenceValue, IMG_UINT32 *paui32ClientUpdateCount, PRGXFWIF_UFO_ADDR **papauiClientUpdateUFOAddress, IMG_UINT32 **papaui32ClientUpdateValue, IMG_UINT32 *paui32ServerSyncCount, IMG_UINT32 **papaui32ServerSyncFlags, SERVER_SYNC_PRIMITIVE ***papapsServerSyncs, IMG_UINT32 ui32NumFenceFDs, IMG_INT32 *paui32FenceFDs, IMG_UINT32 *paui32FWCommandSize, IMG_UINT8 **papaui8FWCommand, IMG_UINT32 *pui32TQPrepareFlags) { PVRSRV_DEVICE_NODE *psDeviceNode = psTransferContext->psDeviceNode; #if defined(WDDM) RGX_CCB_CMD_HELPER_DATA as3DCmdHelper[TQ_MAX_PREPARES_PER_SUBMIT]; RGX_CCB_CMD_HELPER_DATA as2DCmdHelper[TQ_MAX_PREPARES_PER_SUBMIT]; #endif RGX_CCB_CMD_HELPER_DATA *pas3DCmdHelper; RGX_CCB_CMD_HELPER_DATA *pas2DCmdHelper; IMG_UINT32 ui323DCmdCount = 0; IMG_UINT32 ui322DCmdCount = 0; IMG_BOOL bKick2D = IMG_FALSE; IMG_BOOL bKick3D = IMG_FALSE; IMG_BOOL bPDumpContinuous = IMG_FALSE; IMG_UINT32 i; IMG_UINT32 ui32IntClientFenceCount = 0; PRGXFWIF_UFO_ADDR *pauiIntFenceUFOAddress = IMG_NULL; IMG_UINT32 *paui32IntFenceValue = IMG_NULL; IMG_UINT32 ui32IntClientUpdateCount = 0; PRGXFWIF_UFO_ADDR *pauiIntUpdateUFOAddress = IMG_NULL; IMG_UINT32 *paui32IntUpdateValue = IMG_NULL; PVRSRV_ERROR eError; PVRSRV_ERROR eError2; #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) IMG_BOOL bSyncsMerged = IMG_FALSE; #endif if (ui32PrepareCount == 0) { return PVRSRV_ERROR_INVALID_PARAMS; } if (ui32NumFenceFDs != 0) { #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) /* Fence FD's are only valid in the 3D case with no batching */ if ((ui32PrepareCount !=1) && (!TQ_PREP_FLAGS_COMMAND_IS(pui32TQPrepareFlags[0], 3D))) { return PVRSRV_ERROR_INVALID_PARAMS; } #else /* We only support Fence FD's if built with PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC */ return PVRSRV_ERROR_INVALID_PARAMS; #endif } #if defined(WDDM) pas3DCmdHelper = &as3DCmdHelper; pas2DCmdHelper = &as2DCmdHelper; #else /* We can't allocate the required amount of stack space on all consumer architectures */ pas3DCmdHelper = OSAllocMem(sizeof(*pas3DCmdHelper) * ui32PrepareCount); if (pas3DCmdHelper == IMG_NULL) { eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto fail_alloc3dhelper; } pas2DCmdHelper = OSAllocMem(sizeof(*pas2DCmdHelper) * ui32PrepareCount); if (pas2DCmdHelper == IMG_NULL) { eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto fail_alloc2dhelper; } #endif /* Ensure we do the right thing for server syncs which cross call bounderies */ for (i=0;i<ui32PrepareCount;i++) { IMG_BOOL bHaveStartPrepare = pui32TQPrepareFlags[i] & TQ_PREP_FLAGS_START; IMG_BOOL bHaveEndPrepare = IMG_FALSE; if (bHaveStartPrepare) { IMG_UINT32 k; /* We've at the start of a transfer operation (which might be made up of multiple HW operations) so check if we also have then end of the transfer operation in the batch */ for (k=i;k<ui32PrepareCount;k++) { if (pui32TQPrepareFlags[k] & TQ_PREP_FLAGS_END) { bHaveEndPrepare = IMG_TRUE; break; } } if (!bHaveEndPrepare) { /* We don't have the complete command passed in this call so drop the update request. When we get called again with the last HW command in this transfer operation we'll do the update at that point. */ for (k=0;k<paui32ServerSyncCount[i];k++) { papaui32ServerSyncFlags[i][k] &= ~PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE; } } } } /* Init the command helper commands for all the prepares */ for (i=0;i<ui32PrepareCount;i++) { RGX_CLIENT_CCB *psClientCCB; RGX_SERVER_COMMON_CONTEXT *psServerCommonCtx; IMG_CHAR *pszCommandName; RGX_CCB_CMD_HELPER_DATA *psCmdHelper; RGXFWIF_CCB_CMD_TYPE eType; if (TQ_PREP_FLAGS_COMMAND_IS(pui32TQPrepareFlags[i], 3D)) { psServerCommonCtx = psTransferContext->s3DData.psServerCommonContext; psClientCCB = FWCommonContextGetClientCCB(psServerCommonCtx); pszCommandName = "TQ-3D"; psCmdHelper = &pas3DCmdHelper[ui323DCmdCount++]; eType = RGXFWIF_CCB_CMD_TYPE_TQ_3D; } else if (TQ_PREP_FLAGS_COMMAND_IS(pui32TQPrepareFlags[i], 2D)) { psServerCommonCtx = psTransferContext->s2DData.psServerCommonContext; psClientCCB = FWCommonContextGetClientCCB(psServerCommonCtx); pszCommandName = "TQ-2D"; psCmdHelper = &pas2DCmdHelper[ui322DCmdCount++]; eType = RGXFWIF_CCB_CMD_TYPE_TQ_2D; } else { eError = PVRSRV_ERROR_INVALID_PARAMS; goto fail_cmdtype; } if (i == 0) { bPDumpContinuous = ((pui32TQPrepareFlags[i] & TQ_PREP_FLAGS_PDUMPCONTINUOUS) == TQ_PREP_FLAGS_PDUMPCONTINUOUS); PDUMPCOMMENTWITHFLAGS((bPDumpContinuous) ? PDUMP_FLAGS_CONTINUOUS : 0, "%s Command Server Submit on FWCtx %08x", pszCommandName, FWCommonContextGetFWAddress(psServerCommonCtx).ui32Addr); } else { IMG_BOOL bNewPDumpContinuous = ((pui32TQPrepareFlags[i] & TQ_PREP_FLAGS_PDUMPCONTINUOUS) == TQ_PREP_FLAGS_PDUMPCONTINUOUS); if (bNewPDumpContinuous != bPDumpContinuous) { eError = PVRSRV_ERROR_INVALID_PARAMS; PVR_DPF((PVR_DBG_ERROR, "%s: Mixing of continuous and non-continuous command in a batch is not permitted", __FUNCTION__)); goto fail_pdumpcheck; } } #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) if (ui32NumFenceFDs) { IMG_UINT32 ui32NumFenceSyncs; PRGXFWIF_UFO_ADDR *puiFenceFWAddrs; IMG_UINT32 *pui32FenceValues; IMG_UINT32 ui32NumUpdateSyncs; PRGXFWIF_UFO_ADDR *puiUpdateFWAddrs; IMG_UINT32 *pui32UpdateValues; /* FIXME: We can't be taking the server sync operations here as we have no way to undo them should the acquire fail. If client/local syncs where used here would that remove the issue? */ eError = PVRFDSyncQueryFencesKM(ui32NumFenceFDs, paui32FenceFDs, IMG_TRUE, &ui32NumFenceSyncs, &puiFenceFWAddrs, &pui32FenceValues, &ui32NumUpdateSyncs, &puiUpdateFWAddrs, &pui32UpdateValues); if (eError != PVRSRV_OK) { goto fail_fdsync; } /* Merge the Android syncs and the client syncs together */ ui32IntClientFenceCount = paui32ClientFenceCount[i] + ui32NumFenceSyncs; pauiIntFenceUFOAddress = OSAllocMem(sizeof(*pauiIntFenceUFOAddress)* ui32IntClientFenceCount); if (pauiIntFenceUFOAddress == IMG_NULL) { /* Free memory created by PVRFDSyncQueryFencesKM */ OSFreeMem(puiFenceFWAddrs); OSFreeMem(pui32FenceValues); OSFreeMem(puiUpdateFWAddrs); OSFreeMem(pui32UpdateValues); goto fail_fenceUFOarray; } paui32IntFenceValue = OSAllocMem(sizeof(*paui32IntFenceValue)* ui32IntClientFenceCount); if (paui32IntFenceValue == IMG_NULL) { /* Free memory created by PVRFDSyncQueryFencesKM */ OSFreeMem(puiFenceFWAddrs); OSFreeMem(pui32FenceValues); OSFreeMem(puiUpdateFWAddrs); OSFreeMem(pui32UpdateValues); OSFreeMem(pauiIntFenceUFOAddress); goto fail_fencevaluearray; } ui32IntClientUpdateCount = paui32ClientUpdateCount[i] + ui32NumUpdateSyncs; pauiIntUpdateUFOAddress = OSAllocMem(sizeof(*pauiIntUpdateUFOAddress)* ui32IntClientUpdateCount); if (pauiIntUpdateUFOAddress == IMG_NULL) { /* Free memory created by PVRFDSyncQueryFencesKM */ OSFreeMem(puiFenceFWAddrs); OSFreeMem(pui32FenceValues); OSFreeMem(puiUpdateFWAddrs); OSFreeMem(pui32UpdateValues); OSFreeMem(pauiIntFenceUFOAddress); OSFreeMem(paui32IntFenceValue); goto fail_updateUFOarray; } paui32IntUpdateValue = OSAllocMem(sizeof(*paui32IntUpdateValue)* ui32IntClientUpdateCount); if (paui32IntUpdateValue == IMG_NULL) { /* Free memory created by PVRFDSyncQueryFencesKM */ OSFreeMem(puiFenceFWAddrs); OSFreeMem(pui32FenceValues); OSFreeMem(puiUpdateFWAddrs); OSFreeMem(pui32UpdateValues); OSFreeMem(pauiIntFenceUFOAddress); OSFreeMem(paui32IntFenceValue); OSFreeMem(pauiIntUpdateUFOAddress); goto fail_updatevaluearray; } SYNC_MERGE_CLIENT_FENCES(ui32IntClientFenceCount, pauiIntFenceUFOAddress, paui32IntFenceValue, ui32NumFenceSyncs, puiFenceFWAddrs, pui32FenceValues, paui32ClientFenceCount[i], papauiClientFenceUFOAddress[i], papaui32ClientFenceValue[i]); SYNC_MERGE_CLIENT_UPDATES(ui32IntClientUpdateCount, pauiIntUpdateUFOAddress, paui32IntUpdateValue, ui32NumUpdateSyncs, puiUpdateFWAddrs, pui32UpdateValues, paui32ClientUpdateCount[i], papauiClientUpdateUFOAddress[i], papaui32ClientUpdateValue[i]); if (ui32NumFenceSyncs || ui32NumUpdateSyncs) { PDUMPCOMMENT("(TQ) Android native fences in use: %u fence syncs, %u update syncs", ui32NumFenceSyncs, ui32NumUpdateSyncs); } /* Free the data created by PVRFDSyncQueryFencesKM as it has now been merged into *IntClient* */ OSFreeMem(puiFenceFWAddrs); OSFreeMem(pui32FenceValues); OSFreeMem(puiUpdateFWAddrs); OSFreeMem(pui32UpdateValues); bSyncsMerged = IMG_TRUE; } else #endif /* PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC */ { /* No client sync merging so just copy across the pointers */ ui32IntClientFenceCount = paui32ClientFenceCount[i]; pauiIntFenceUFOAddress = papauiClientFenceUFOAddress[i]; paui32IntFenceValue = papaui32ClientFenceValue[i]; ui32IntClientUpdateCount = paui32ClientUpdateCount[i]; pauiIntUpdateUFOAddress = papauiClientUpdateUFOAddress[i]; paui32IntUpdateValue = papaui32ClientUpdateValue[i]; } /* Create the command helper data for this command */ eError = RGXCmdHelperInitCmdCCB(psClientCCB, ui32IntClientFenceCount, pauiIntFenceUFOAddress, paui32IntFenceValue, ui32IntClientUpdateCount, pauiIntUpdateUFOAddress, paui32IntUpdateValue, paui32ServerSyncCount[i], papaui32ServerSyncFlags[i], papapsServerSyncs[i], paui32FWCommandSize[i], papaui8FWCommand[i], eType, bPDumpContinuous, pszCommandName, psCmdHelper); if (eError != PVRSRV_OK) { goto fail_initcmd; } } /* Acquire space for all the commands in one go */ if (ui323DCmdCount) { eError = RGXCmdHelperAcquireCmdCCB(ui323DCmdCount, &pas3DCmdHelper[0], &bKick3D); if (eError != PVRSRV_OK) { if (bKick3D) { ui323DCmdCount = 0; ui322DCmdCount = 0; } else { goto fail_3dcmdacquire; } } } if (ui322DCmdCount) { eError = RGXCmdHelperAcquireCmdCCB(ui322DCmdCount, &pas2DCmdHelper[0], &bKick2D); if (eError != PVRSRV_OK) { if (bKick2D || bKick3D) { ui323DCmdCount = 0; ui322DCmdCount = 0; } else { goto fail_2dcmdacquire; } } } /* We should acquire the kernel CCB(s) space here as the schedule could fail and we would have to roll back all the syncs */ /* Only do the command helper release (which takes the server sync operations if the acquire succeeded */ if (ui323DCmdCount) { RGXCmdHelperReleaseCmdCCB(ui323DCmdCount, &pas3DCmdHelper[0], "TQ_3D", FWCommonContextGetFWAddress(psTransferContext->s3DData.psServerCommonContext).ui32Addr); } if (ui322DCmdCount) { RGXCmdHelperReleaseCmdCCB(ui322DCmdCount, &pas2DCmdHelper[0], "TQ_2D", FWCommonContextGetFWAddress(psTransferContext->s2DData.psServerCommonContext).ui32Addr); } /* Even if we failed to acquire the client CCB space we might still need to kick the HW to process a padding packet to release space for us next time round */ if (bKick3D) { RGXFWIF_KCCB_CMD s3DKCCBCmd; /* Construct the kernel 3D CCB command. */ s3DKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK; s3DKCCBCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psTransferContext->s3DData.psServerCommonContext); s3DKCCBCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psTransferContext->s3DData.psServerCommonContext)); s3DKCCBCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0; LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) { eError2 = RGXScheduleCommand(psDeviceNode->pvDevice, RGXFWIF_DM_3D, &s3DKCCBCmd, sizeof(s3DKCCBCmd), bPDumpContinuous); if (eError2 != PVRSRV_ERROR_RETRY) { break; } OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); } END_LOOP_UNTIL_TIMEOUT(); } if (bKick2D) { RGXFWIF_KCCB_CMD s2DKCCBCmd; /* Construct the kernel 3D CCB command. */ s2DKCCBCmd.eCmdType = RGXFWIF_KCCB_CMD_KICK; s2DKCCBCmd.uCmdData.sCmdKickData.psContext = FWCommonContextGetFWAddress(psTransferContext->s2DData.psServerCommonContext); s2DKCCBCmd.uCmdData.sCmdKickData.ui32CWoffUpdate = RGXGetHostWriteOffsetCCB(FWCommonContextGetClientCCB(psTransferContext->s2DData.psServerCommonContext)); s2DKCCBCmd.uCmdData.sCmdKickData.ui32NumCleanupCtl = 0; LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) { eError2 = RGXScheduleCommand(psDeviceNode->pvDevice, RGXFWIF_DM_2D, &s2DKCCBCmd, sizeof(s2DKCCBCmd), bPDumpContinuous); if (eError2 != PVRSRV_ERROR_RETRY) { break; } OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); } END_LOOP_UNTIL_TIMEOUT(); } /* * Now check eError (which may have returned an error from our earlier calls * to RGXCmdHelperAcquireCmdCCB) - we needed to process any flush command first * so we check it now... */ if (eError != PVRSRV_OK ) { goto fail_2dcmdacquire; } #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) /* Free the merged sync memory if required */ if (bSyncsMerged) { OSFreeMem(pauiIntFenceUFOAddress); OSFreeMem(paui32IntFenceValue); OSFreeMem(pauiIntUpdateUFOAddress); OSFreeMem(paui32IntUpdateValue); } #if defined(NO_HARDWARE) for (i = 0; i < ui32NumFenceFDs; i++) { eError = PVRFDSyncNoHwUpdateFenceKM(paui32FenceFDs[i]); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "%s: Failed nohw update on fence fd=%d (%s)", __func__, paui32FenceFDs[i], PVRSRVGetErrorStringKM(eError))); } } #endif #endif #if !defined(WDDM) OSFreeMem(pas2DCmdHelper); OSFreeMem(pas3DCmdHelper); #endif return PVRSRV_OK; /* No resources are created in this function so there is nothing to free unless we had to merge syncs. If we fail after the client CCB acquire there is still nothing to do as only the client CCB release will modify the client CCB */ fail_2dcmdacquire: fail_3dcmdacquire: fail_initcmd: #if defined(PVR_ANDROID_NATIVE_WINDOW_HAS_SYNC) if (bSyncsMerged) { OSFreeMem(pauiIntFenceUFOAddress); OSFreeMem(paui32IntFenceValue); OSFreeMem(pauiIntUpdateUFOAddress); OSFreeMem(paui32IntUpdateValue); } fail_updatevaluearray: fail_updateUFOarray: fail_fencevaluearray: fail_fenceUFOarray: fail_fdsync: #endif fail_pdumpcheck: fail_cmdtype: PVR_ASSERT(eError != PVRSRV_OK); #if !defined(WDDM) OSFreeMem(pas2DCmdHelper); fail_alloc2dhelper: OSFreeMem(pas3DCmdHelper); fail_alloc3dhelper: #endif return eError; }
PVRSRV_ERROR RGXCreateCCB(PVRSRV_DEVICE_NODE *psDeviceNode, IMG_UINT32 ui32CCBSizeLog2, CONNECTION_DATA *psConnectionData, const IMG_CHAR *pszName, RGX_SERVER_COMMON_CONTEXT *psServerCommonContext, RGX_CLIENT_CCB **ppsClientCCB, DEVMEM_MEMDESC **ppsClientCCBMemDesc, DEVMEM_MEMDESC **ppsClientCCBCtrlMemDesc) { PVRSRV_ERROR eError; DEVMEM_FLAGS_T uiClientCCBMemAllocFlags, uiClientCCBCtlMemAllocFlags; IMG_UINT32 ui32AllocSize = (1U << ui32CCBSizeLog2); RGX_CLIENT_CCB *psClientCCB; psClientCCB = OSAllocMem(sizeof(*psClientCCB)); if (psClientCCB == IMG_NULL) { eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto fail_alloc; } psClientCCB->psServerCommonContext = psServerCommonContext; uiClientCCBMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(META_CACHED) | PVRSRV_MEMALLOCFLAG_GPU_READABLE | PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | PVRSRV_MEMALLOCFLAG_CPU_READABLE | PVRSRV_MEMALLOCFLAG_UNCACHED | PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE; uiClientCCBCtlMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | PVRSRV_MEMALLOCFLAG_GPU_READABLE | PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | PVRSRV_MEMALLOCFLAG_CPU_READABLE | PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | PVRSRV_MEMALLOCFLAG_UNCACHED | PVRSRV_MEMALLOCFLAG_ZERO_ON_ALLOC | PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE; PDUMPCOMMENT("Allocate RGXFW cCCB"); eError = DevmemFwAllocateExportable(psDeviceNode, ui32AllocSize, uiClientCCBMemAllocFlags, "FirmwareClientCCB", &psClientCCB->psClientCCBMemDesc); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateCCBKM: Failed to allocate RGX client CCB (%s)", PVRSRVGetErrorStringKM(eError))); goto fail_alloc_ccb; } eError = DevmemAcquireCpuVirtAddr(psClientCCB->psClientCCBMemDesc, (IMG_VOID **) &psClientCCB->pui8ClientCCB); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateCCBKM: Failed to map RGX client CCB (%s)", PVRSRVGetErrorStringKM(eError))); goto fail_map_ccb; } PDUMPCOMMENT("Allocate RGXFW cCCB control"); eError = DevmemFwAllocateExportable(psDeviceNode, sizeof(RGXFWIF_CCCB_CTL), uiClientCCBCtlMemAllocFlags, "FirmwareClientCCBControl", &psClientCCB->psClientCCBCtrlMemDesc); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateCCBKM: Failed to allocate RGX client CCB control (%s)", PVRSRVGetErrorStringKM(eError))); goto fail_alloc_ccbctrl; } eError = DevmemAcquireCpuVirtAddr(psClientCCB->psClientCCBCtrlMemDesc, (IMG_VOID **) &psClientCCB->psClientCCBCtrl); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateCCBKM: Failed to map RGX client CCB (%s)", PVRSRVGetErrorStringKM(eError))); goto fail_map_ccbctrl; } psClientCCB->psClientCCBCtrl->ui32WriteOffset = 0; psClientCCB->psClientCCBCtrl->ui32ReadOffset = 0; psClientCCB->psClientCCBCtrl->ui32DepOffset = 0; psClientCCB->psClientCCBCtrl->ui32WrapMask = ui32AllocSize - 1; OSStringCopy(psClientCCB->szName, pszName); PDUMPCOMMENT("cCCB control"); DevmemPDumpLoadMem(psClientCCB->psClientCCBCtrlMemDesc, 0, sizeof(RGXFWIF_CCCB_CTL), PDUMP_FLAGS_CONTINUOUS); PVR_ASSERT(eError == PVRSRV_OK); psClientCCB->ui32HostWriteOffset = 0; psClientCCB->ui32LastPDumpWriteOffset = 0; psClientCCB->ui32Size = ui32AllocSize; #if defined REDUNDANT_SYNCS_DEBUG psClientCCB->ui32UpdateWriteIndex = 0; OSMemSet(psClientCCB->asFenceUpdateList, 0, sizeof(psClientCCB->asFenceUpdateList)); #endif eError = PDumpRegisterTransitionCallback(psConnectionData->psPDumpConnectionData, _RGXCCBPDumpTransition, psClientCCB, &psClientCCB->hTransition); if (eError != PVRSRV_OK) { goto fail_pdumpreg; } /* Note: Due to resman the connection structure could be freed before the client CCB so rather then saving off the connection structure save the PDump specific memory which is refcounted to ensure it's not freed too early */ psClientCCB->psPDumpConnectionData = psConnectionData->psPDumpConnectionData; PDUMPCOMMENT("New RGXFW cCCB(%s@%p) created", psClientCCB->szName, psClientCCB); *ppsClientCCB = psClientCCB; *ppsClientCCBMemDesc = psClientCCB->psClientCCBMemDesc; *ppsClientCCBCtrlMemDesc = psClientCCB->psClientCCBCtrlMemDesc; return PVRSRV_OK; fail_pdumpreg: DevmemReleaseCpuVirtAddr(psClientCCB->psClientCCBCtrlMemDesc); fail_map_ccbctrl: DevmemFwFree(psClientCCB->psClientCCBCtrlMemDesc); fail_alloc_ccbctrl: DevmemReleaseCpuVirtAddr(psClientCCB->psClientCCBMemDesc); fail_map_ccb: DevmemFwFree(psClientCCB->psClientCCBMemDesc); fail_alloc_ccb: OSFreeMem(psClientCCB); fail_alloc: PVR_ASSERT(eError != PVRSRV_OK); return eError; }
IMG_EXPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA *psPerProc, IMG_HANDLE hDevMemContext, IMG_HANDLE hDeviceClassBuffer, PVRSRV_KERNEL_MEM_INFO **ppsMemInfo, IMG_HANDLE *phOSMapInfo) { PVRSRV_ERROR eError; PVRSRV_DEVICE_NODE* psDeviceNode; PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL; PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer; IMG_SYS_PHYADDR *psSysPAddr; IMG_VOID *pvCPUVAddr, *pvPageAlignedCPUVAddr; IMG_BOOL bPhysContig; BM_CONTEXT *psBMContext; DEVICE_MEMORY_INFO *psDevMemoryInfo; DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap; IMG_HANDLE hDevMemHeap = IMG_NULL; IMG_SIZE_T ui32ByteSize; IMG_SIZE_T ui32Offset; IMG_SIZE_T ui32PageSize = HOST_PAGESIZE(); BM_HANDLE hBuffer; PVRSRV_MEMBLK *psMemBlock; IMG_BOOL bBMError; IMG_UINT32 i; PVRSRV_DC_MAPINFO *psDCMapInfo = IMG_NULL; if(!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo || !hDevMemContext) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: invalid parameters")); return PVRSRV_ERROR_INVALID_PARAMS; } if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_MAPINFO), (IMG_VOID **)&psDCMapInfo, IMG_NULL, "PVRSRV_DC_MAPINFO") != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for psDCMapInfo")); return PVRSRV_ERROR_OUT_OF_MEMORY; } OSMemSet(psDCMapInfo, 0, sizeof(PVRSRV_DC_MAPINFO)); psDeviceClassBuffer = (PVRSRV_DEVICECLASS_BUFFER*)hDeviceClassBuffer; eError = psDeviceClassBuffer->pfnGetBufferAddr(psDeviceClassBuffer->hExtDevice, psDeviceClassBuffer->hExtBuffer, &psSysPAddr, &ui32ByteSize, &pvCPUVAddr, phOSMapInfo, &bPhysContig, &psDCMapInfo->ui32TilingStride); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to get buffer address")); goto ErrorExitPhase1; } psBMContext = (BM_CONTEXT*)psDeviceClassBuffer->hDevMemContext; psDeviceNode = psBMContext->psDeviceNode; psDevMemoryInfo = &psDeviceNode->sDevMemoryInfo; psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap; for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++) { if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID) { if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT) { hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]); } else { hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap; } break; } } if(hDevMemHeap == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to find mapping heap")); eError = PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE; goto ErrorExitPhase1; } ui32Offset = ((IMG_UINTPTR_T)pvCPUVAddr) & (ui32PageSize - 1); pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvCPUVAddr - ui32Offset); eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), (IMG_VOID **)&psMemInfo, IMG_NULL, "Kernel Memory Info"); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for block")); goto ErrorExitPhase1; } OSMemSet(psMemInfo, 0, sizeof(*psMemInfo)); psMemBlock = &(psMemInfo->sMemBlk); bBMError = BM_Wrap(hDevMemHeap, ui32ByteSize, ui32Offset, bPhysContig, psSysPAddr, pvPageAlignedCPUVAddr, &psMemInfo->ui32Flags, &hBuffer); if (!bBMError) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: BM_Wrap Failed")); eError = PVRSRV_ERROR_BAD_MAPPING; goto ErrorExitPhase2; } psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer); psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer); psMemBlock->hBuffer = (IMG_HANDLE)hBuffer; psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer); psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr; psMemInfo->ui32AllocSize = ui32ByteSize; psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo; psMemInfo->pvSysBackupBuffer = IMG_NULL; psDCMapInfo->psMemInfo = psMemInfo; #if defined(SUPPORT_MEMORY_TILING) psDCMapInfo->psDeviceNode = psDeviceNode; if(psDCMapInfo->ui32TilingStride > 0) { eError = psDeviceNode->pfnAllocMemTilingRange(psDeviceNode, psMemInfo, psDCMapInfo->ui32TilingStride, &psDCMapInfo->ui32RangeIndex); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: AllocMemTilingRange failed")); goto ErrorExitPhase3; } } #endif psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext, RESMAN_TYPE_DEVICECLASSMEM_MAPPING, psDCMapInfo, 0, &UnmapDeviceClassMemoryCallBack); psMemInfo->ui32RefCount++; psMemInfo->memType = PVRSRV_MEMTYPE_DEVICECLASS; *ppsMemInfo = psMemInfo; #if defined(SUPPORT_PDUMP_MULTI_PROCESS) PDUMPCOMMENT("Dump display surface"); PDUMPMEM(IMG_NULL, psMemInfo, ui32Offset, psMemInfo->ui32AllocSize, PDUMP_FLAGS_CONTINUOUS, ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping); #endif return PVRSRV_OK; #if defined(SUPPORT_MEMORY_TILING) ErrorExitPhase3: if(psMemInfo) { FreeDeviceMem(psMemInfo); psMemInfo = IMG_NULL; } #endif ErrorExitPhase2: if(psMemInfo) { OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL); } ErrorExitPhase1: if(psDCMapInfo) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psDCMapInfo, IMG_NULL); } return eError; }
/************************************************************************** * Function Name : PDumpInit * Outputs : None * Returns : * Description : Reset connection to vldbgdrv * Then try to connect to PDUMP streams **************************************************************************/ IMG_VOID PDumpInit(IMG_VOID) { IMG_UINT32 i; DBGKM_CONNECT_NOTIFIER sConnectNotifier; /* If we tried this earlier, then we might have connected to the driver * But if pdump.exe was running then the stream connected would fail */ if (!gpfnDbgDrv) { DBGDrvGetServiceTable(&gpfnDbgDrv); // If something failed then no point in trying to connect streams if (gpfnDbgDrv == IMG_NULL) { return; } /* * Pass the connection notify callback */ sConnectNotifier.pfnConnectNotifier = &PDumpConnectionNotify; gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier); if(!gsDBGPdumpState.pszFile) { if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszFile, 0, "Filename string") != PVRSRV_OK) { goto init_failed; } } if(!gsDBGPdumpState.pszMsg) { if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszMsg, 0, "Message string") != PVRSRV_OK) { goto init_failed; } } if(!gsDBGPdumpState.pszScript) { if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID *)&gsDBGPdumpState.pszScript, 0, "Script string") != PVRSRV_OK) { goto init_failed; } } for(i=0; i < PDUMP_NUM_STREAMS; i++) { gsDBGPdumpState.psStream[i] = gpfnDbgDrv->pfnCreateStream(pszStreamName[i], DEBUG_CAPMODE_FRAMED, DEBUG_OUTMODE_STREAMENABLE, 0, 10); gpfnDbgDrv->pfnSetCaptureMode(gsDBGPdumpState.psStream[i],DEBUG_CAPMODE_FRAMED,0xFFFFFFFF, 0xFFFFFFFF, 1); gpfnDbgDrv->pfnSetFrame(gsDBGPdumpState.psStream[i],0); } PDUMPCOMMENT("Driver Product Name: %s", VS_PRODUCT_NAME); PDUMPCOMMENT("Driver Product Version: %s (%s)", PVRVERSION_STRING, PVRVERSION_FAMILY); PDUMPCOMMENT("Start of Init Phase"); } return; init_failed: if(gsDBGPdumpState.pszFile) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_FILENAME_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszFile, 0); gsDBGPdumpState.pszFile = IMG_NULL; } if(gsDBGPdumpState.pszScript) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_SCRIPT_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszScript, 0); gsDBGPdumpState.pszScript = IMG_NULL; } if(gsDBGPdumpState.pszMsg) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, SZ_MSG_SIZE_MAX, (IMG_PVOID) gsDBGPdumpState.pszMsg, 0); gsDBGPdumpState.pszMsg = IMG_NULL; } /* * Remove the connection notify callback */ sConnectNotifier.pfnConnectNotifier = 0; gpfnDbgDrv->pfnSetConnectNotifier(sConnectNotifier); gpfnDbgDrv = IMG_NULL; }
enum PVRSRV_ERROR MMU_Initialise(struct PVRSRV_DEVICE_NODE *psDeviceNode, struct MMU_CONTEXT **ppsMMUContext, struct IMG_DEV_PHYADDR *psPDDevPAddr) { u32 *pui32Tmp; u32 i; void *pvPDCpuVAddr; struct IMG_DEV_PHYADDR sPDDevPAddr; struct IMG_CPU_PHYADDR sCpuPAddr; struct IMG_SYS_PHYADDR sSysPAddr; struct MMU_CONTEXT *psMMUContext; void *hPDOSMemHandle; struct SYS_DATA *psSysData; struct PVRSRV_SGXDEV_INFO *psDevInfo; PVR_DPF(PVR_DBG_MESSAGE, "MMU_Initialise"); if (SysAcquireData(&psSysData) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: ERROR call to SysAcquireData failed"); return PVRSRV_ERROR_GENERIC; } if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct MMU_CONTEXT), (void **) &psMMUContext, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: ERROR call to OSAllocMem failed"); return PVRSRV_ERROR_GENERIC; } OSMemSet(psMMUContext, 0, sizeof(struct MMU_CONTEXT)); psDevInfo = (struct PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice; psMMUContext->psDevInfo = psDevInfo; psMMUContext->psDeviceNode = psDeviceNode; if (psDeviceNode->psLocalDevMemArena == NULL) { if (OSAllocPages (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, &pvPDCpuVAddr, &hPDOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: " "ERROR call to OSAllocPages failed"); goto err1; } if (pvPDCpuVAddr) sCpuPAddr = OSMapLinToCPUPhys(pvPDCpuVAddr); else sCpuPAddr = OSMemHandleToCpuPAddr(hPDOSMemHandle, 0); sPDDevPAddr = SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr); } else { if (RA_Alloc(psDeviceNode->psLocalDevMemArena, SGX_MMU_PAGE_SIZE, NULL, 0, SGX_MMU_PAGE_SIZE, &(sSysPAddr.uiAddr)) != IMG_TRUE) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: " "ERROR call to RA_Alloc failed"); goto err1; } sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); sPDDevPAddr = SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr); pvPDCpuVAddr = (void __force *) OSMapPhysToLin(sCpuPAddr, SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, &hPDOSMemHandle); if (!pvPDCpuVAddr) { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: " "ERROR failed to map page tables"); goto err2; } } PDUMPCOMMENT("Alloc page directory"); PDUMPMALLOCPAGETABLE(pvPDCpuVAddr, PDUMP_PD_UNIQUETAG); if (pvPDCpuVAddr) { pui32Tmp = (u32 *) pvPDCpuVAddr; } else { PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: pvPDCpuVAddr invalid"); goto err3; } for (i = 0; i < SGX_MMU_PD_SIZE; i++) pui32Tmp[i] = 0; PDUMPCOMMENT("Page directory contents"); PDUMPPAGETABLE(pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, IMG_TRUE, PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG); psMMUContext->pvPDCpuVAddr = pvPDCpuVAddr; psMMUContext->sPDDevPAddr = sPDDevPAddr; psMMUContext->hPDOSMemHandle = hPDOSMemHandle; *ppsMMUContext = psMMUContext; *psPDDevPAddr = sPDDevPAddr; psMMUContext->psNext = (struct MMU_CONTEXT *) psDevInfo->pvMMUContextList; psDevInfo->pvMMUContextList = (void *) psMMUContext; return PVRSRV_OK; err3: if (psDeviceNode->psLocalDevMemArena) OSUnMapPhysToLin((void __iomem __force *)pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, hPDOSMemHandle); err2: if (!psDeviceNode->psLocalDevMemArena) OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY, SGX_MMU_PAGE_SIZE, pvPDCpuVAddr, hPDOSMemHandle); else RA_Free(psDeviceNode->psLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); err1: OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct MMU_CONTEXT), psMMUContext, NULL); return PVRSRV_ERROR_GENERIC; }
PVRSRV_ERROR SGXDoKickKM(IMG_HANDLE hDevHandle, SGX_CCB_KICK *psCCBKick) #endif { PVRSRV_ERROR eError; PVRSRV_KERNEL_SYNC_INFO *psSyncInfo; PVRSRV_KERNEL_MEM_INFO *psCCBMemInfo = (PVRSRV_KERNEL_MEM_INFO *) psCCBKick->hCCBKernelMemInfo; SGXMKIF_CMDTA_SHARED *psTACmd; IMG_UINT32 i; IMG_HANDLE hDevMemContext = IMG_NULL; #if defined(FIX_HW_BRN_31620) hDevMemContext = psCCBKick->hDevMemContext; #endif PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_ENTER, KICK_TOKEN_DOKICK); if (!CCB_OFFSET_IS_VALID(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset)) { PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: Invalid CCB offset")); PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, KICK_TOKEN_DOKICK); return PVRSRV_ERROR_INVALID_PARAMS; } psTACmd = CCB_DATA_FROM_OFFSET(SGXMKIF_CMDTA_SHARED, psCCBMemInfo, psCCBKick, ui32CCBOffset); PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CMD_START, KICK_TOKEN_DOKICK); PVR_TTRACE_UI32(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CCB, KICK_TOKEN_CCB_OFFSET, psCCBKick->ui32CCBOffset); if (psCCBKick->hTA3DSyncInfo) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_TA3D_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psTACmd->sTA3DDependency.sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->sTA3DDependency.ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; if (psCCBKick->bTADependency) { psSyncInfo->psSyncData->ui32WriteOpsPending++; } } if (psCCBKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_TA_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psTACmd->sTATQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->sTATQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->ui32TATQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; psTACmd->ui32TATQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } if (psCCBKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_3D_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psTACmd->s3DTQSyncReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->s3DTQSyncWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->ui323DTQSyncReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; psTACmd->ui323DTQSyncWriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } psTACmd->ui32NumTAStatusVals = psCCBKick->ui32NumTAStatusVals; if (psCCBKick->ui32NumTAStatusVals != 0) { for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) { #if defined(SUPPORT_SGX_NEW_STATUS_VALS) psTACmd->sCtlTAStatusInfo[i] = psCCBKick->asTAStatusUpdate[i].sCtlStatus; #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->sCtlTAStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending; #endif } } psTACmd->ui32Num3DStatusVals = psCCBKick->ui32Num3DStatusVals; if (psCCBKick->ui32Num3DStatusVals != 0) { for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) { #if defined(SUPPORT_SGX_NEW_STATUS_VALS) psTACmd->sCtl3DStatusInfo[i] = psCCBKick->as3DStatusUpdate[i].sCtlStatus; #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->sCtl3DStatusInfo[i].ui32StatusValue = psSyncInfo->psSyncData->ui32ReadOpsPending; #endif } } #if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) psTACmd->ui32NumTASrcSyncs = psCCBKick->ui32NumTASrcSyncs; for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; psTACmd->asTASrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->asTASrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->asTASrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; psTACmd->asTASrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } psTACmd->ui32NumTADstSyncs = psCCBKick->ui32NumTADstSyncs; for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; psTACmd->asTADstSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->asTADstSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->asTADstSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psTACmd->asTADstSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; } psTACmd->ui32Num3DSrcSyncs = psCCBKick->ui32Num3DSrcSyncs; for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; psTACmd->as3DSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->as3DSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->as3DSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; psTACmd->as3DSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } #else psTACmd->ui32NumSrcSyncs = psCCBKick->ui32NumSrcSyncs; for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_SRC_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psTACmd->asSrcSyncs[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psTACmd->asSrcSyncs[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psTACmd->asSrcSyncs[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending++; psTACmd->asSrcSyncs[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending; } #endif if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0) { PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo; SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM; IMG_UINT32 ui32NumDstSyncs = psCCBKick->ui32NumDstSyncObjects; PVR_ASSERT(((PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo)->uAllocSize >= (sizeof(SGXMKIF_HWDEVICE_SYNC_LIST) + (sizeof(PVRSRV_DEVICE_SYNC_OBJECT) * ui32NumDstSyncs))); psHWDeviceSyncList->ui32NumSyncObjects = ui32NumDstSyncs; #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { PDUMPCOMMENT("HWDeviceSyncList for TACmd\r\n"); PDUMPMEM(IMG_NULL, psHWDstSyncListMemInfo, 0, sizeof(SGXMKIF_HWDEVICE_SYNC_LIST), 0, MAKEUNIQUETAG(psHWDstSyncListMemInfo)); } #endif for (i=0; i<ui32NumDstSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i]; if (psSyncInfo) { PVR_TTRACE_SYNC_OBJECT(PVRSRV_TRACE_GROUP_KICK, KICK_TOKEN_DST_SYNC, psSyncInfo, PVRSRV_SYNCOP_SAMPLE); psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr = psSyncInfo->sWriteOpsCompleteDevVAddr; psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr = psSyncInfo->sReadOpsCompleteDevVAddr; psHWDeviceSyncList->asSyncData[i].sReadOps2CompleteDevVAddr = psSyncInfo->sReadOps2CompleteDevVAddr; psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = psSyncInfo->psSyncData->ui32ReadOpsPending; psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = psSyncInfo->psSyncData->ui32WriteOpsPending++; psHWDeviceSyncList->asSyncData[i].ui32ReadOps2PendingVal = psSyncInfo->psSyncData->ui32ReadOps2Pending; #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { IMG_UINT32 ui32ModifiedValue; IMG_UINT32 ui32SyncOffset = offsetof(SGXMKIF_HWDEVICE_SYNC_LIST, asSyncData) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)); IMG_UINT32 ui32WOpsOffset = ui32SyncOffset + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal); IMG_UINT32 ui32ROpsOffset = ui32SyncOffset + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal); IMG_UINT32 ui32ROps2Offset = ui32SyncOffset + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOps2PendingVal); PDUMPCOMMENT("HWDeviceSyncObject for RT: %i\r\n", i); PDUMPMEM(IMG_NULL, psHWDstSyncListMemInfo, ui32SyncOffset, sizeof(PVRSRV_DEVICE_SYNC_OBJECT), 0, MAKEUNIQUETAG(psHWDstSyncListMemInfo)); if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) { PDUMPCOMMENT("Init RT ROpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); PDUMPCOMMENT("Init RT WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); } psSyncInfo->psSyncData->ui32LastOpDumpVal++; ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1; PDUMPCOMMENT("Modify RT %d WOpPendingVal in HWDevSyncList\r\n", i); PDUMPMEM(&ui32ModifiedValue, psHWDstSyncListMemInfo, ui32WOpsOffset, sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psHWDstSyncListMemInfo)); ui32ModifiedValue = 0; PDUMPCOMMENT("Modify RT %d ROpsPendingVal in HWDevSyncList\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psHWDstSyncListMemInfo, ui32ROpsOffset, sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psHWDstSyncListMemInfo)); PDUMPCOMMENT("Modify RT %d ROps2PendingVal in HWDevSyncList\r\n", i); PDUMPMEM(&ui32ModifiedValue, psHWDstSyncListMemInfo, ui32ROps2Offset, sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psHWDstSyncListMemInfo)); } #endif } else { psHWDeviceSyncList->asSyncData[i].sWriteOpsCompleteDevVAddr.uiAddr = 0; psHWDeviceSyncList->asSyncData[i].sReadOpsCompleteDevVAddr.uiAddr = 0; psHWDeviceSyncList->asSyncData[i].sReadOps2CompleteDevVAddr.uiAddr = 0; psHWDeviceSyncList->asSyncData[i].ui32ReadOpsPendingVal = 0; psHWDeviceSyncList->asSyncData[i].ui32ReadOps2PendingVal = 0; psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal = 0; } } } psTACmd->ui32CtrlFlags |= SGXMKIF_CMDTA_CTRLFLAGS_READY; #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { PDUMPCOMMENT("Shared part of TA command\r\n"); PDUMPMEM(psTACmd, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff, sizeof(SGXMKIF_CMDTA_SHARED), 0, MAKEUNIQUETAG(psCCBMemInfo)); #if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++) { IMG_UINT32 ui32ModifiedValue; psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) { PDUMPCOMMENT("Init RT TA-SRC ROpsComplete\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); PDUMPCOMMENT("Init RT TA-SRC WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); } psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1; PDUMPCOMMENT("Modify TA SrcSync %d ROpsPendingVal\r\n", i); PDUMPMEM(&ui32ModifiedValue, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Modify TA SrcSync %d WOpPendingVal\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTASrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); } for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++) { IMG_UINT32 ui32ModifiedValue; psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) { PDUMPCOMMENT("Init RT TA-DST ROpsComplete\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); PDUMPCOMMENT("Init RT TA-DST WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); } psSyncInfo->psSyncData->ui32LastOpDumpVal++; ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastOpDumpVal - 1; PDUMPCOMMENT("Modify TA DstSync %d WOpPendingVal\r\n", i); PDUMPMEM(&ui32ModifiedValue, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Modify TA DstSync %d ROpsPendingVal\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asTADstSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); } for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++) { IMG_UINT32 ui32ModifiedValue; psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) { PDUMPCOMMENT("Init RT 3D-SRC ROpsComplete\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); PDUMPCOMMENT("Init RT 3D-SRC WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); } psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1; PDUMPCOMMENT("Modify 3D SrcSync %d ROpsPendingVal\r\n", i); PDUMPMEM(&ui32ModifiedValue, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Modify 3D SrcSync %d WOpPendingVal\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, as3DSrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); } #else for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++) { IMG_UINT32 ui32ModifiedValue; psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; if ((psSyncInfo->psSyncData->ui32LastOpDumpVal == 0) && (psSyncInfo->psSyncData->ui32LastReadOpDumpVal == 0)) { PDUMPCOMMENT("Init RT ROpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete), sizeof(psSyncInfo->psSyncData->ui32ReadOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); PDUMPCOMMENT("Init RT WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete), sizeof(psSyncInfo->psSyncData->ui32WriteOpsComplete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); PDUMPCOMMENT("Init RT WOpsComplete\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psSyncInfo->psSyncDataMemInfoKM, offsetof(PVRSRV_SYNC_DATA, ui32ReadOps2Complete), sizeof(psSyncInfo->psSyncData->ui32ReadOps2Complete), 0, MAKEUNIQUETAG(psSyncInfo->psSyncDataMemInfoKM)); } psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; ui32ModifiedValue = psSyncInfo->psSyncData->ui32LastReadOpDumpVal - 1; PDUMPCOMMENT("Modify SrcSync %d ROpsPendingVal\r\n", i); PDUMPMEM(&ui32ModifiedValue, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32ReadOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); PDUMPCOMMENT("Modify SrcSync %d WOpPendingVal\r\n", i); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, asSrcSyncs) + (i * sizeof(PVRSRV_DEVICE_SYNC_OBJECT)) + offsetof(PVRSRV_DEVICE_SYNC_OBJECT, ui32WriteOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); } if (psCCBKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; PDUMPCOMMENT("Modify TA/TQ ROpPendingVal\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui32TATQSyncReadOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; } if (psCCBKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; PDUMPCOMMENT("Modify 3D/TQ ROpPendingVal\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastReadOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + offsetof(SGXMKIF_CMDTA_SHARED, ui323DTQSyncReadOpsPendingVal), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); psSyncInfo->psSyncData->ui32LastReadOpDumpVal++; } #endif for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) { #if !defined(SUPPORT_SGX_NEW_STATUS_VALS) psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; PDUMPCOMMENT("Modify TA status value in TA cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_CMDTA_SHARED, sCtlTAStatusInfo[i].ui32StatusValue), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); #endif } for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) { #if !defined(SUPPORT_SGX_NEW_STATUS_VALS) psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; PDUMPCOMMENT("Modify 3D status value in TA cmd\r\n"); PDUMPMEM(&psSyncInfo->psSyncData->ui32LastOpDumpVal, psCCBMemInfo, psCCBKick->ui32CCBDumpWOff + (IMG_UINT32)offsetof(SGXMKIF_CMDTA_SHARED, sCtl3DStatusInfo[i].ui32StatusValue), sizeof(IMG_UINT32), 0, MAKEUNIQUETAG(psCCBMemInfo)); #endif } } #endif PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_CMD_END, KICK_TOKEN_DOKICK); eError = SGXScheduleCCBCommandKM(hDevHandle, SGXMKIF_CMD_TA, &psCCBKick->sCommand, KERNEL_ID, 0, hDevMemContext, psCCBKick->bLastInScene); if (eError == PVRSRV_ERROR_RETRY) { if (psCCBKick->bFirstKickOrResume && psCCBKick->ui32NumDstSyncObjects > 0) { for (i=0; i < psCCBKick->ui32NumDstSyncObjects; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i]; if (psSyncInfo) { psSyncInfo->psSyncData->ui32WriteOpsPending--; #if defined(PDUMP) if (PDumpIsCaptureFrameKM()) { psSyncInfo->psSyncData->ui32LastOpDumpVal--; } #endif } } } #if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending--; } for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32WriteOpsPending--; } for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending--; } #else for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsPending--; } #endif PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, KICK_TOKEN_DOKICK); return eError; } else if (PVRSRV_OK != eError) { PVR_DPF((PVR_DBG_ERROR, "SGXDoKickKM: SGXScheduleCCBCommandKM failed.")); PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, KICK_TOKEN_DOKICK); return eError; } #if defined(NO_HARDWARE) if (psCCBKick->hTA3DSyncInfo) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTA3DSyncInfo; if (psCCBKick->bTADependency) { psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } } if (psCCBKick->hTASyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->hTASyncInfo; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } if (psCCBKick->h3DSyncInfo != IMG_NULL) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->h3DSyncInfo; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } for (i = 0; i < psCCBKick->ui32NumTAStatusVals; i++) { #if defined(SUPPORT_SGX_NEW_STATUS_VALS) PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->asTAStatusUpdate[i].hKernelMemInfo; *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM + (psTACmd->sCtlTAStatusInfo[i].sStatusDevAddr.uiAddr - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue; #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ahTAStatusSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtlTAStatusInfo[i].ui32StatusValue; #endif } #if defined(SUPPORT_SGX_GENERALISED_SYNCOBJECTS) for (i=0; i<psCCBKick->ui32NumTASrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTASrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } for (i=0; i<psCCBKick->ui32NumTADstSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahTADstKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32WriteOpsComplete = psSyncInfo->psSyncData->ui32WriteOpsPending; } for (i=0; i<psCCBKick->ui32Num3DSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ah3DSrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } #else for (i=0; i<psCCBKick->ui32NumSrcSyncs; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *) psCCBKick->ahSrcKernelSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psSyncInfo->psSyncData->ui32ReadOpsPending; } #endif if (psCCBKick->bTerminateOrAbort) { if (psCCBKick->ui32NumDstSyncObjects > 0) { PVRSRV_KERNEL_MEM_INFO *psHWDstSyncListMemInfo = (PVRSRV_KERNEL_MEM_INFO *)psCCBKick->hKernelHWSyncListMemInfo; SGXMKIF_HWDEVICE_SYNC_LIST *psHWDeviceSyncList = psHWDstSyncListMemInfo->pvLinAddrKM; for (i=0; i<psCCBKick->ui32NumDstSyncObjects; i++) { psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->pahDstSyncHandles[i]; if (psSyncInfo) psSyncInfo->psSyncData->ui32WriteOpsComplete = psHWDeviceSyncList->asSyncData[i].ui32WriteOpsPendingVal+1; } } for (i = 0; i < psCCBKick->ui32Num3DStatusVals; i++) { #if defined(SUPPORT_SGX_NEW_STATUS_VALS) PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = (PVRSRV_KERNEL_MEM_INFO*)psCCBKick->as3DStatusUpdate[i].hKernelMemInfo; *(IMG_UINT32*)((IMG_UINTPTR_T)psKernelMemInfo->pvLinAddrKM + (psTACmd->sCtl3DStatusInfo[i].sStatusDevAddr.uiAddr - psKernelMemInfo->sDevVAddr.uiAddr)) = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue; #else psSyncInfo = (PVRSRV_KERNEL_SYNC_INFO *)psCCBKick->ah3DStatusSyncInfo[i]; psSyncInfo->psSyncData->ui32ReadOpsComplete = psTACmd->sCtl3DStatusInfo[i].ui32StatusValue; #endif } } #endif PVR_TTRACE(PVRSRV_TRACE_GROUP_KICK, PVRSRV_TRACE_CLASS_FUNCTION_EXIT, KICK_TOKEN_DOKICK); return eError; }
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; }
/* * RGXRegisterMemoryContext */ PVRSRV_ERROR RGXRegisterMemoryContext(PVRSRV_DEVICE_NODE *psDeviceNode, MMU_CONTEXT *psMMUContext, IMG_HANDLE *hPrivData) { PVRSRV_ERROR eError; PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; DEVMEM_FLAGS_T uiFWMemContextMemAllocFlags; RGXFWIF_FWMEMCONTEXT *psFWMemContext; DEVMEM_MEMDESC *psFWMemContextMemDesc; SERVER_MMU_CONTEXT *psServerMMUContext; if (psDevInfo->psKernelMMUCtx == IMG_NULL) { /* * This must be the creation of the Kernel memory context. Take a copy * of the MMU context for use when programming the BIF. */ psDevInfo->psKernelMMUCtx = psMMUContext; } else { psServerMMUContext = OSAllocMem(sizeof(*psServerMMUContext)); if (psServerMMUContext == IMG_NULL) { eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto fail_alloc_server_ctx; } psServerMMUContext->psDevInfo = psDevInfo; /* * This FW MemContext is only mapped into kernel for initialisation purposes. * Otherwise this allocation is only used by the FW. * Therefore the GPU cache doesn't need coherency, * and write-combine is suffice on the CPU side (WC buffer will be flushed at any kick) */ uiFWMemContextMemAllocFlags = PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(PMMETA_PROTECT) | PVRSRV_MEMALLOCFLAG_DEVICE_FLAG(META_CACHED) | PVRSRV_MEMALLOCFLAG_GPU_READABLE | PVRSRV_MEMALLOCFLAG_GPU_WRITEABLE | PVRSRV_MEMALLOCFLAG_GPU_CACHE_INCOHERENT | PVRSRV_MEMALLOCFLAG_CPU_READABLE | PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE | PVRSRV_MEMALLOCFLAG_KERNEL_CPU_MAPPABLE; /* Allocate device memory for the firmware memory context for the new application. */ PDUMPCOMMENT("Allocate RGX firmware memory context"); /* FIXME: why cache-consistent? */ eError = DevmemFwAllocate(psDevInfo, sizeof(*psFWMemContext), uiFWMemContextMemAllocFlags, "FirmwareMemoryContext", &psFWMemContextMemDesc); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"RGXRegisterMemoryContext: Failed to allocate firmware memory context (%u)", eError)); goto fail_alloc_fw_ctx; } /* Temporarily map the firmware memory context to the kernel. */ eError = DevmemAcquireCpuVirtAddr(psFWMemContextMemDesc, (IMG_VOID **)&psFWMemContext); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"RGXRegisterMemoryContext: Failed to map firmware memory context (%u)", eError)); goto fail_acquire_cpu_addr; } /* * Write the new memory context's page catalogue into the firmware memory * context for the client. */ eError = MMU_AcquireBaseAddr(psMMUContext, &psFWMemContext->sPCDevPAddr); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"RGXRegisterMemoryContext: Failed to acquire Page Catalogue address (%u)", eError)); DevmemReleaseCpuVirtAddr(psFWMemContextMemDesc); goto fail_acquire_base_addr; } /* * Set default values for the rest of the structure. */ psFWMemContext->uiPageCatBaseRegID = -1; psFWMemContext->uiBreakpointAddr = 0; psFWMemContext->uiBPHandlerAddr = 0; psFWMemContext->uiBreakpointCtl = 0; #if defined(SUPPORT_GPUVIRT_VALIDATION) { IMG_UINT32 ui32OSid = 0, ui32OSidReg = 0; MMU_GetOSids(psMMUContext, &ui32OSid, &ui32OSidReg); psFWMemContext->ui32OSid = ui32OSidReg; } #endif #if defined(PDUMP) { IMG_CHAR aszName[PMR_MAX_MEMSPNAME_SYMB_ADDR_LENGTH_DEFAULT]; IMG_DEVMEM_OFFSET_T uiOffset = 0; /* * Dump the Mem context allocation */ DevmemPDumpLoadMem(psFWMemContextMemDesc, 0, sizeof(*psFWMemContext), PDUMP_FLAGS_CONTINUOUS); /* * Obtain a symbolic addr of the mem context structure */ eError = DevmemPDumpPageCatBaseToSAddr(psFWMemContextMemDesc, &uiOffset, aszName, PMR_MAX_MEMSPNAME_SYMB_ADDR_LENGTH_DEFAULT); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"RGXRegisterMemoryContext: Failed to generate a Dump Page Catalogue address (%u)", eError)); DevmemReleaseCpuVirtAddr(psFWMemContextMemDesc); goto fail_pdump_cat_base_addr; } /* * Dump the Page Cat tag in the mem context (symbolic address) */ eError = MMU_PDumpWritePageCatBase(psMMUContext, aszName, uiOffset, 8, /* 64-bit register write */ 0, 0, 0); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"RGXRegisterMemoryContext: Failed to acquire Page Catalogue address (%u)", eError)); DevmemReleaseCpuVirtAddr(psFWMemContextMemDesc); goto fail_pdump_cat_base; } } #endif /* * Release kernel address acquired above. */ DevmemReleaseCpuVirtAddr(psFWMemContextMemDesc); /* * Store the process information for this device memory context * for use with the host page-fault analysis. */ psServerMMUContext->uiPID = OSGetCurrentProcessID(); psServerMMUContext->psMMUContext = psMMUContext; psServerMMUContext->psFWMemContextMemDesc = psFWMemContextMemDesc; if (OSSNPrintf(psServerMMUContext->szProcessName, RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME, "%s", OSGetCurrentProcessName()) == RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME) { psServerMMUContext->szProcessName[RGXMEM_SERVER_MMU_CONTEXT_MAX_NAME-1] = '\0'; } OSWRLockAcquireWrite(psDevInfo->hMemoryCtxListLock); dllist_add_to_tail(&psDevInfo->sMemoryContextList, &psServerMMUContext->sNode); OSWRLockReleaseWrite(psDevInfo->hMemoryCtxListLock); MMU_SetDeviceData(psMMUContext, psFWMemContextMemDesc); *hPrivData = psServerMMUContext; } return PVRSRV_OK; #if defined(PDUMP) fail_pdump_cat_base: fail_pdump_cat_base_addr: MMU_ReleaseBaseAddr(IMG_NULL); #endif fail_acquire_base_addr: /* Done before jumping to the fail point as the release is done before exit */ fail_acquire_cpu_addr: DevmemFwFree(psServerMMUContext->psFWMemContextMemDesc); fail_alloc_fw_ctx: OSFreeMem(psServerMMUContext); fail_alloc_server_ctx: PVR_ASSERT(eError != PVRSRV_OK); 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 PVRSRVAllocSyncInfoKM(IMG_HANDLE hDevCookie, IMG_HANDLE hDevMemContext, PVRSRV_KERNEL_SYNC_INFO **ppsKernelSyncInfo) { IMG_HANDLE hSyncDevMemHeap; DEVICE_MEMORY_INFO *psDevMemoryInfo; BM_CONTEXT *pBMContext; PVRSRV_ERROR eError; PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo; PVRSRV_SYNC_DATA *psSyncData; eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), (IMG_VOID **)&psKernelSyncInfo, IMG_NULL, "Kernel Synchronization Info"); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory")); return PVRSRV_ERROR_OUT_OF_MEMORY; } psKernelSyncInfo->ui32RefCount = 0; #ifdef CONFIG_PVR_TRACE_CMD INIT_LIST_HEAD(&psKernelSyncInfo->link); psKernelSyncInfo->counter_digest = 0; #endif pBMContext = (BM_CONTEXT*)hDevMemContext; psDevMemoryInfo = &pBMContext->psDeviceNode->sDevMemoryInfo; hSyncDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[psDevMemoryInfo->ui32SyncHeapID].hDevMemHeap; eError = AllocDeviceMem(hDevCookie, hSyncDevMemHeap, PVRSRV_MEM_CACHE_CONSISTENT, sizeof(PVRSRV_SYNC_DATA), sizeof(IMG_UINT32), &psKernelSyncInfo->psSyncDataMemInfoKM); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSyncInfoKM: Failed to alloc memory")); OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_SYNC_INFO), psKernelSyncInfo, IMG_NULL); return PVRSRV_ERROR_OUT_OF_MEMORY; } psKernelSyncInfo->psSyncData = psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM; psSyncData = psKernelSyncInfo->psSyncData; psSyncData->ui32WriteOpsPending = 0; psSyncData->ui32WriteOpsComplete = 0; psSyncData->ui32ReadOpsPending = 0; psSyncData->ui32ReadOpsComplete = 0; psSyncData->ui32LastOpDumpVal = 0; psSyncData->ui32LastReadOpDumpVal = 0; #if defined(PDUMP) PDUMPCOMMENT("Allocating kernel sync object"); PDUMPMEM(psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM, psKernelSyncInfo->psSyncDataMemInfoKM, 0, psKernelSyncInfo->psSyncDataMemInfoKM->ui32AllocSize, PDUMP_FLAGS_CONTINUOUS, MAKEUNIQUETAG(psKernelSyncInfo->psSyncDataMemInfoKM)); #endif psKernelSyncInfo->sWriteOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32WriteOpsComplete); psKernelSyncInfo->sReadOpsCompleteDevVAddr.uiAddr = psKernelSyncInfo->psSyncDataMemInfoKM->sDevVAddr.uiAddr + offsetof(PVRSRV_SYNC_DATA, ui32ReadOpsComplete); psKernelSyncInfo->psSyncDataMemInfoKM->psKernelSyncInfo = IMG_NULL; *ppsKernelSyncInfo = psKernelSyncInfo; return PVRSRV_OK; }
/* * PVRSRVRGXCreateTQ3DContextKM */ IMG_EXPORT PVRSRV_ERROR PVRSRVRGXCreateTQ3DContextKM(PVRSRV_DEVICE_NODE *psDeviceNode, DEVMEM_MEMDESC *psTQ3DCCBMemDesc, DEVMEM_MEMDESC *psTQ3DCCBCtlMemDesc, RGX_TQ3D_CLEANUP_DATA **ppsCleanupData, DEVMEM_MEMDESC **ppsFWTQ3DContextMemDesc, DEVMEM_MEMDESC **ppsFWTQ3DContextStateMemDesc, IMG_UINT32 ui32Priority, IMG_DEV_VIRTADDR sMCUFenceAddr, IMG_UINT32 ui32FrameworkRegisterSize, IMG_PBYTE pbyFrameworkRegisters, IMG_HANDLE hMemCtxPrivData) { PVRSRV_ERROR eError = PVRSRV_OK; PVRSRV_RGXDEV_INFO *psDevInfo = psDeviceNode->pvDevice; RGXFWIF_FWCOMMONCONTEXT *psFWTQ3DContext; RGX_TQ3D_CLEANUP_DATA *psTmpCleanup; DEVMEM_MEMDESC *psFWFrameworkMemDesc; /* Prepare cleanup struct */ psTmpCleanup = OSAllocMem(sizeof(*psTmpCleanup)); if (psTmpCleanup == IMG_NULL) { return PVRSRV_ERROR_OUT_OF_MEMORY; } OSMemSet(psTmpCleanup, 0, sizeof(*psTmpCleanup)); *ppsCleanupData = psTmpCleanup; /* Allocate cleanup sync */ eError = SyncPrimAlloc(psDeviceNode->hSyncPrimContext, &psTmpCleanup->psCleanupSync); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateComputeContextKM: Failed to allocate cleanup sync (0x%x)", eError)); goto fail_syncalloc; } /* Allocate device memory for the firmware TQ 3D context. */ PDUMPCOMMENT("Allocate RGX firmware TQ 3D context"); eError = DevmemFwAllocate(psDevInfo, sizeof(*psFWTQ3DContext), RGX_FWCOMCTX_ALLOCFLAGS, ppsFWTQ3DContextMemDesc); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ3DContextKM: Failed to allocate firmware TQ 3D context (%u)", eError)); goto fail_contextalloc; } psTmpCleanup->psFWTQ3DContextMemDesc = *ppsFWTQ3DContextMemDesc; psTmpCleanup->psDeviceNode = psDeviceNode; /* Temporarily map the firmware TQ 3D context to the kernel. */ eError = DevmemAcquireCpuVirtAddr(*ppsFWTQ3DContextMemDesc, (IMG_VOID **)&psFWTQ3DContext); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ3DContextKM: Failed to map firmware TQ 3D context (%u)", eError)); goto fail_cpuvirtacquire; } /* Allocate device memory for the firmware GPU context suspend state. Note: the FW reads/writes the state to memory by accessing the GPU register interface. */ PDUMPCOMMENT("Allocate RGX firmware TQ/3D context suspend state"); eError = DevmemFwAllocate(psDevInfo, sizeof(RGXFWIF_3DCTX_STATE), RGX_FWCOMCTX_ALLOCFLAGS, ppsFWTQ3DContextStateMemDesc); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ3DContextKM: Failed to allocate firmware GPU context suspend state (%u)", eError)); goto fail_contextsuspendalloc; } psTmpCleanup->psFWTQ3DContextStateMemDesc = *ppsFWTQ3DContextStateMemDesc; /* * Create the FW framework buffer */ eError = PVRSRVRGXFrameworkCreateKM(psDeviceNode, & psFWFrameworkMemDesc, ui32FrameworkRegisterSize); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ3DContextKM: Failed to allocate firmware GPU framework state (%u)", eError)); goto fail_frameworkcreate; } psTmpCleanup->psFWFrameworkMemDesc = psFWFrameworkMemDesc; /* Copy the Framework client data into the framework buffer */ eError = PVRSRVRGXFrameworkCopyRegisters(psFWFrameworkMemDesc, pbyFrameworkRegisters, ui32FrameworkRegisterSize); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ3DContextKM: Failed to populate the framework buffer (%u)", eError)); goto fail_frameworkcopy; } /* Init TQ/3D FW common context */ eError = RGXInitFWCommonContext(psFWTQ3DContext, psTQ3DCCBMemDesc, psTQ3DCCBCtlMemDesc, hMemCtxPrivData, psFWFrameworkMemDesc, ui32Priority, &sMCUFenceAddr, &psTmpCleanup->sFWComContextCleanup); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRGXCreateTQ3DContextKM: Failed to init firmware common context (%u)", eError)); goto fail_contextinit; } /* * Set the firmware GPU context state buffer. * * The common context stores a dword pointer (FW) so we can cast the generic buffer to * the correct 3D (3D/TQ = normal 3D) state structure type in the FW. */ RGXSetFirmwareAddress(&psFWTQ3DContext->psContextState, *ppsFWTQ3DContextStateMemDesc, 0, RFW_FWADDR_FLAG_NONE); /* * Dump the TQ3D and the memory contexts */ PDUMPCOMMENT("Dump FWTQ3DContext"); DevmemPDumpLoadMem(*ppsFWTQ3DContextMemDesc, 0, sizeof(*psFWTQ3DContext), PDUMP_FLAGS_CONTINUOUS); /* * Dump the FW TQ/3D context suspend state buffer */ PDUMPCOMMENT("Dump FWTQ3DContextState"); DevmemPDumpLoadMem(*ppsFWTQ3DContextStateMemDesc, 0, sizeof(RGXFWIF_3DCTX_STATE), PDUMP_FLAGS_CONTINUOUS); /* Release address acquired above. */ DevmemReleaseCpuVirtAddr(*ppsFWTQ3DContextMemDesc); return PVRSRV_OK; fail_contextinit: fail_frameworkcopy: DevmemFwFree(psFWFrameworkMemDesc); fail_frameworkcreate: DevmemFwFree(*ppsFWTQ3DContextStateMemDesc); fail_contextsuspendalloc: DevmemReleaseCpuVirtAddr(*ppsFWTQ3DContextMemDesc); fail_cpuvirtacquire: DevmemFwFree(*ppsFWTQ3DContextMemDesc); fail_contextalloc: SyncPrimFree(psTmpCleanup->psCleanupSync); fail_syncalloc: OSFreeMem(psTmpCleanup); return eError; }