1 /**********************************************************************
2 Copyright (c) Imagination Technologies Ltd.
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 ******************************************************************************/
23 #include "services_headers.h"
27 DECLARE_LIST_FOR_EACH(PVRSRV_DEVICE_NODE);
29 #if defined(__linux__) && defined(__KERNEL__)
34 QueuePrintCommands (PVRSRV_QUEUE_INFO * psQueue, IMG_CHAR * buffer, size_t size)
38 IMG_SIZE_T ui32ReadOffset = psQueue->ui32ReadOffset;
39 IMG_SIZE_T ui32WriteOffset = psQueue->ui32WriteOffset;
40 PVRSRV_COMMAND * psCmd;
42 while (ui32ReadOffset != ui32WriteOffset)
44 psCmd= (PVRSRV_COMMAND *)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + ui32ReadOffset);
46 off = printAppend(buffer, size, off, "%p %p %5lu %6lu %3lu %5lu %2lu %2lu %3lu \n",
53 psCmd->ui32DstSyncCount,
54 psCmd->ui32SrcSyncCount,
57 ui32ReadOffset += psCmd->ui32CmdSize;
58 ui32ReadOffset &= psQueue->ui32QueueSize - 1;
62 off = printAppend(buffer, size, off, "%p <empty>\n", psQueue);
68 #ifdef PVR_PROC_USE_SEQ_FILE
70 void ProcSeqShowQueue(struct seq_file *sfile,void* el)
72 PVRSRV_QUEUE_INFO * psQueue = (PVRSRV_QUEUE_INFO*)el;
74 IMG_SIZE_T ui32ReadOffset;
75 IMG_SIZE_T ui32WriteOffset;
76 PVRSRV_COMMAND * psCmd;
78 if(el == PVR_PROC_SEQ_START_TOKEN)
82 "Queue CmdPtr Pid Command Size DevInd DSC SSC #Data ...\n");
86 ui32ReadOffset = psQueue->ui32ReadOffset;
87 ui32WriteOffset = psQueue->ui32WriteOffset;
89 while (ui32ReadOffset != ui32WriteOffset)
91 psCmd= (PVRSRV_COMMAND *)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + ui32ReadOffset);
93 seq_printf(sfile, "%p %p %5lu %6lu %3lu %5lu %2lu %2lu %3lu \n",
100 psCmd->ui32DstSyncCount,
101 psCmd->ui32SrcSyncCount,
102 psCmd->ui32DataSize);
104 ui32ReadOffset += psCmd->ui32CmdSize;
105 ui32ReadOffset &= psQueue->ui32QueueSize - 1;
110 seq_printf(sfile, "%p <empty>\n", psQueue);
113 void* ProcSeqOff2ElementQueue(struct seq_file * sfile, loff_t off)
115 PVRSRV_QUEUE_INFO * psQueue;
116 SYS_DATA * psSysData;
120 return PVR_PROC_SEQ_START_TOKEN;
124 SysAcquireData(&psSysData);
126 for (psQueue = psSysData->psQueueList; (((--off) > 0) && (psQueue != IMG_NULL)); psQueue = psQueue->psNextKM);
133 QueuePrintQueues (IMG_CHAR * buffer, size_t size, off_t off)
135 SYS_DATA * psSysData;
136 PVRSRV_QUEUE_INFO * psQueue;
138 SysAcquireData(&psSysData);
141 return printAppend (buffer, size, 0,
143 "Queue CmdPtr Pid Command Size DevInd DSC SSC #Data ...\n");
147 for (psQueue = psSysData->psQueueList; (((--off) > 0) && (psQueue != IMG_NULL)); psQueue = psQueue->psNextKM)
150 return psQueue ? QueuePrintCommands (psQueue, buffer, size) : END_OF_FILE;
154 #define GET_SPACE_IN_CMDQ(psQueue) \
155 (((psQueue->ui32ReadOffset - psQueue->ui32WriteOffset) \
156 + (psQueue->ui32QueueSize - 1)) & (psQueue->ui32QueueSize - 1))
158 #define UPDATE_QUEUE_WOFF(psQueue, ui32Size) \
159 psQueue->ui32WriteOffset = (psQueue->ui32WriteOffset + ui32Size) \
160 & (psQueue->ui32QueueSize - 1);
162 #define SYNCOPS_STALE(ui32OpsComplete, ui32OpsPending) \
163 (ui32OpsComplete >= ui32OpsPending)
166 DECLARE_LIST_FOR_EACH(PVRSRV_DEVICE_NODE);
168 static IMG_VOID QueueDumpCmdComplete(COMMAND_COMPLETE_DATA *psCmdCompleteData,
172 PVRSRV_SYNC_OBJECT *psSyncObject;
174 psSyncObject = bIsSrc ? psCmdCompleteData->psSrcSync : psCmdCompleteData->psDstSync;
176 if (psCmdCompleteData->bInUse)
178 PVR_LOG(("\t%s %lu: ROC DevVAddr:0x%lX ROP:0x%lx ROC:0x%lx, WOC DevVAddr:0x%lX WOP:0x%lx WOC:0x%lx",
179 bIsSrc ? "SRC" : "DEST", i,
180 psSyncObject[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
181 psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsPending,
182 psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsComplete,
183 psSyncObject[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
184 psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsPending,
185 psSyncObject[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete));
189 PVR_LOG(("\t%s %lu: (Not in use)", bIsSrc ? "SRC" : "DEST", i));
194 static IMG_VOID QueueDumpDebugInfo_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
196 if (psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY)
200 COMMAND_COMPLETE_DATA **ppsCmdCompleteData;
201 COMMAND_COMPLETE_DATA *psCmdCompleteData;
203 SysAcquireData(&psSysData);
205 ppsCmdCompleteData = psSysData->ppsCmdCompleteData[psDeviceNode->sDevId.ui32DeviceIndex];
207 if (ppsCmdCompleteData != IMG_NULL)
209 psCmdCompleteData = ppsCmdCompleteData[DC_FLIP_COMMAND];
211 PVR_LOG(("Command Complete Data for display device %lu:", psDeviceNode->sDevId.ui32DeviceIndex));
213 for (i = 0; i < psCmdCompleteData->ui32SrcSyncCount; i++)
215 QueueDumpCmdComplete(psCmdCompleteData, i, IMG_TRUE);
218 for (i = 0; i < psCmdCompleteData->ui32DstSyncCount; i++)
220 QueueDumpCmdComplete(psCmdCompleteData, i, IMG_FALSE);
225 PVR_LOG(("There is no Command Complete Data for display device %u", psDeviceNode->sDevId.ui32DeviceIndex));
231 IMG_VOID QueueDumpDebugInfo(IMG_VOID)
234 SysAcquireData(&psSysData);
235 List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList, QueueDumpDebugInfo_ForEachCb);
239 IMG_SIZE_T NearestPower2(IMG_SIZE_T ui32Value)
241 IMG_SIZE_T ui32Temp, ui32Result = 1;
246 ui32Temp = ui32Value - 1;
258 PVRSRV_ERROR IMG_CALLCONV PVRSRVCreateCommandQueueKM(IMG_SIZE_T ui32QueueSize,
259 PVRSRV_QUEUE_INFO **ppsQueueInfo)
261 PVRSRV_QUEUE_INFO *psQueueInfo;
262 IMG_SIZE_T ui32Power2QueueSize = NearestPower2(ui32QueueSize);
265 IMG_HANDLE hMemBlock;
267 SysAcquireData(&psSysData);
270 if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
271 sizeof(PVRSRV_QUEUE_INFO),
272 (IMG_VOID **)&psQueueInfo, &hMemBlock,
273 "Queue Info") != PVRSRV_OK)
275 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue struct"));
278 OSMemSet(psQueueInfo, 0, sizeof(PVRSRV_QUEUE_INFO));
280 psQueueInfo->hMemBlock[0] = hMemBlock;
281 psQueueInfo->ui32ProcessID = OSGetCurrentProcessIDKM();
284 if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
285 ui32Power2QueueSize + PVRSRV_MAX_CMD_SIZE,
286 &psQueueInfo->pvLinQueueKM, &hMemBlock,
287 "Command Queue") != PVRSRV_OK)
289 PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueueKM: Failed to alloc queue buffer"));
293 psQueueInfo->hMemBlock[1] = hMemBlock;
294 psQueueInfo->pvLinQueueUM = psQueueInfo->pvLinQueueKM;
297 PVR_ASSERT(psQueueInfo->ui32ReadOffset == 0);
298 PVR_ASSERT(psQueueInfo->ui32WriteOffset == 0);
300 psQueueInfo->ui32QueueSize = ui32Power2QueueSize;
303 if (psSysData->psQueueList == IMG_NULL)
305 eError = OSCreateResource(&psSysData->sQProcessResource);
306 if (eError != PVRSRV_OK)
313 if (OSLockResource(&psSysData->sQProcessResource,
314 KERNEL_ID) != PVRSRV_OK)
319 psQueueInfo->psNextKM = psSysData->psQueueList;
320 psSysData->psQueueList = psQueueInfo;
322 if (OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID) != PVRSRV_OK)
327 *ppsQueueInfo = psQueueInfo;
335 if(psQueueInfo->pvLinQueueKM)
337 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
338 psQueueInfo->ui32QueueSize,
339 psQueueInfo->pvLinQueueKM,
340 psQueueInfo->hMemBlock[1]);
341 psQueueInfo->pvLinQueueKM = IMG_NULL;
344 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
345 sizeof(PVRSRV_QUEUE_INFO),
347 psQueueInfo->hMemBlock[0]);
351 return PVRSRV_ERROR_GENERIC;
356 PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueueKM(PVRSRV_QUEUE_INFO *psQueueInfo)
358 PVRSRV_QUEUE_INFO *psQueue;
361 IMG_BOOL bTimeout = IMG_TRUE;
363 SysAcquireData(&psSysData);
365 psQueue = psSysData->psQueueList;
367 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
369 if(psQueueInfo->ui32ReadOffset == psQueueInfo->ui32WriteOffset)
371 bTimeout = IMG_FALSE;
374 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
375 } END_LOOP_UNTIL_TIMEOUT();
380 PVR_DPF((PVR_DBG_ERROR,"PVRSRVDestroyCommandQueueKM : Failed to empty queue"));
381 eError = PVRSRV_ERROR_CANNOT_FLUSH_QUEUE;
386 eError = OSLockResource(&psSysData->sQProcessResource,
388 if (eError != PVRSRV_OK)
393 if(psQueue == psQueueInfo)
395 psSysData->psQueueList = psQueueInfo->psNextKM;
397 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
398 NearestPower2(psQueueInfo->ui32QueueSize) + PVRSRV_MAX_CMD_SIZE,
399 psQueueInfo->pvLinQueueKM,
400 psQueueInfo->hMemBlock[1]);
401 psQueueInfo->pvLinQueueKM = IMG_NULL;
402 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
403 sizeof(PVRSRV_QUEUE_INFO),
405 psQueueInfo->hMemBlock[0]);
407 psQueueInfo = IMG_NULL;
413 if(psQueue->psNextKM == psQueueInfo)
415 psQueue->psNextKM = psQueueInfo->psNextKM;
417 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
418 psQueueInfo->ui32QueueSize,
419 psQueueInfo->pvLinQueueKM,
420 psQueueInfo->hMemBlock[1]);
421 psQueueInfo->pvLinQueueKM = IMG_NULL;
422 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
423 sizeof(PVRSRV_QUEUE_INFO),
425 psQueueInfo->hMemBlock[0]);
427 psQueueInfo = IMG_NULL;
430 psQueue = psQueue->psNextKM;
435 eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
436 if (eError != PVRSRV_OK)
440 eError = PVRSRV_ERROR_INVALID_PARAMS;
446 eError = OSUnlockResource(&psSysData->sQProcessResource, KERNEL_ID);
447 if (eError != PVRSRV_OK)
453 if (psSysData->psQueueList == IMG_NULL)
455 eError = OSDestroyResource(&psSysData->sQProcessResource);
456 if (eError != PVRSRV_OK)
469 PVRSRV_ERROR IMG_CALLCONV PVRSRVGetQueueSpaceKM(PVRSRV_QUEUE_INFO *psQueue,
470 IMG_SIZE_T ui32ParamSize,
473 IMG_BOOL bTimeout = IMG_TRUE;
476 ui32ParamSize = (ui32ParamSize+3) & 0xFFFFFFFC;
478 if (ui32ParamSize > PVRSRV_MAX_CMD_SIZE)
480 PVR_DPF((PVR_DBG_WARNING,"PVRSRVGetQueueSpace: max command size is %d bytes", PVRSRV_MAX_CMD_SIZE));
481 return PVRSRV_ERROR_CMD_TOO_BIG;
484 LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US)
486 if (GET_SPACE_IN_CMDQ(psQueue) > ui32ParamSize)
488 bTimeout = IMG_FALSE;
491 OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT);
492 } END_LOOP_UNTIL_TIMEOUT();
494 if (bTimeout == IMG_TRUE)
496 *ppvSpace = IMG_NULL;
498 return PVRSRV_ERROR_CANNOT_GET_QUEUE_SPACE;
502 *ppvSpace = (IMG_VOID *)((IMG_UINTPTR_T)psQueue->pvLinQueueUM + psQueue->ui32WriteOffset);
510 PVRSRV_ERROR IMG_CALLCONV PVRSRVInsertCommandKM(PVRSRV_QUEUE_INFO *psQueue,
511 PVRSRV_COMMAND **ppsCommand,
512 IMG_UINT32 ui32DevIndex,
513 IMG_UINT16 CommandType,
514 IMG_UINT32 ui32DstSyncCount,
515 PVRSRV_KERNEL_SYNC_INFO *apsDstSync[],
516 IMG_UINT32 ui32SrcSyncCount,
517 PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[],
518 IMG_SIZE_T ui32DataByteSize )
521 PVRSRV_COMMAND *psCommand;
522 IMG_SIZE_T ui32CommandSize;
526 ui32DataByteSize = (ui32DataByteSize + 3UL) & ~3UL;
529 ui32CommandSize = sizeof(PVRSRV_COMMAND)
530 + ((ui32DstSyncCount + ui32SrcSyncCount) * sizeof(PVRSRV_SYNC_OBJECT))
534 eError = PVRSRVGetQueueSpaceKM (psQueue, ui32CommandSize, (IMG_VOID**)&psCommand);
535 if(eError != PVRSRV_OK)
540 psCommand->ui32ProcessID = OSGetCurrentProcessIDKM();
543 psCommand->ui32CmdSize = ui32CommandSize;
544 psCommand->ui32DevIndex = ui32DevIndex;
545 psCommand->CommandType = CommandType;
546 psCommand->ui32DstSyncCount = ui32DstSyncCount;
547 psCommand->ui32SrcSyncCount = ui32SrcSyncCount;
550 psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand) + sizeof(PVRSRV_COMMAND));
553 psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psDstSync)
554 + (ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
556 psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psCommand->psSrcSync)
557 + (ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
558 psCommand->ui32DataSize = ui32DataByteSize;
561 for (i=0; i<ui32DstSyncCount; i++)
563 psCommand->psDstSync[i].psKernelSyncInfoKM = apsDstSync[i];
564 psCommand->psDstSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsDstSync[i], IMG_FALSE);
565 psCommand->psDstSync[i].ui32ReadOpsPending = PVRSRVGetReadOpsPending(apsDstSync[i], IMG_FALSE);
567 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Dst %lu RO-VA:0x%lx WO-VA:0x%lx ROP:0x%lx WOP:0x%lx",
568 i, psCommand->psDstSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
569 psCommand->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
570 psCommand->psDstSync[i].ui32ReadOpsPending,
571 psCommand->psDstSync[i].ui32WriteOpsPending));
575 for (i=0; i<ui32SrcSyncCount; i++)
577 psCommand->psSrcSync[i].psKernelSyncInfoKM = apsSrcSync[i];
578 psCommand->psSrcSync[i].ui32WriteOpsPending = PVRSRVGetWriteOpsPending(apsSrcSync[i], IMG_TRUE);
579 psCommand->psSrcSync[i].ui32ReadOpsPending = PVRSRVGetReadOpsPending(apsSrcSync[i], IMG_TRUE);
581 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInsertCommandKM: Src %lu RO-VA:0x%lx WO-VA:0x%lx ROP:0x%lx WOP:0x%lx",
582 i, psCommand->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
583 psCommand->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
584 psCommand->psSrcSync[i].ui32ReadOpsPending,
585 psCommand->psSrcSync[i].ui32WriteOpsPending));
589 *ppsCommand = psCommand;
596 PVRSRV_ERROR IMG_CALLCONV PVRSRVSubmitCommandKM(PVRSRV_QUEUE_INFO *psQueue,
597 PVRSRV_COMMAND *psCommand)
602 if (psCommand->ui32DstSyncCount > 0)
604 psCommand->psDstSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
605 + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND));
608 if (psCommand->ui32SrcSyncCount > 0)
610 psCommand->psSrcSync = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
611 + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)
612 + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
615 psCommand->pvData = (PVRSRV_SYNC_OBJECT*)(((IMG_UINTPTR_T)psQueue->pvLinQueueKM)
616 + psQueue->ui32WriteOffset + sizeof(PVRSRV_COMMAND)
617 + (psCommand->ui32DstSyncCount * sizeof(PVRSRV_SYNC_OBJECT))
618 + (psCommand->ui32SrcSyncCount * sizeof(PVRSRV_SYNC_OBJECT)));
621 UPDATE_QUEUE_WOFF(psQueue, psCommand->ui32CmdSize);
629 PVRSRV_ERROR PVRSRVProcessCommand(SYS_DATA *psSysData,
630 PVRSRV_COMMAND *psCommand,
633 PVRSRV_SYNC_OBJECT *psWalkerObj;
634 PVRSRV_SYNC_OBJECT *psEndObj;
636 COMMAND_COMPLETE_DATA *psCmdCompleteData;
637 PVRSRV_ERROR eError = PVRSRV_OK;
638 IMG_UINT32 ui32WriteOpsComplete;
639 IMG_UINT32 ui32ReadOpsComplete;
642 psWalkerObj = psCommand->psDstSync;
643 psEndObj = psWalkerObj + psCommand->ui32DstSyncCount;
644 while (psWalkerObj < psEndObj)
646 PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
648 ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
649 ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete;
651 if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
652 || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOpsPending))
655 !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
656 !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
658 return PVRSRV_ERROR_FAILED_DEPENDENCIES;
666 psWalkerObj = psCommand->psSrcSync;
667 psEndObj = psWalkerObj + psCommand->ui32SrcSyncCount;
668 while (psWalkerObj < psEndObj)
670 PVRSRV_SYNC_DATA *psSyncData = psWalkerObj->psKernelSyncInfoKM->psSyncData;
672 ui32ReadOpsComplete = psSyncData->ui32ReadOpsComplete;
673 ui32WriteOpsComplete = psSyncData->ui32WriteOpsComplete;
675 if ((ui32WriteOpsComplete != psWalkerObj->ui32WriteOpsPending)
676 || (ui32ReadOpsComplete != psWalkerObj->ui32ReadOpsPending))
679 SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) &&
680 SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
682 PVR_DPF((PVR_DBG_WARNING,
683 "PVRSRVProcessCommand: Stale syncops psSyncData:0x%x ui32WriteOpsComplete:0x%x ui32WriteOpsPending:0x%x",
684 psSyncData, ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending));
688 !SYNCOPS_STALE(ui32WriteOpsComplete, psWalkerObj->ui32WriteOpsPending) ||
689 !SYNCOPS_STALE(ui32ReadOpsComplete, psWalkerObj->ui32ReadOpsPending))
691 return PVRSRV_ERROR_FAILED_DEPENDENCIES;
698 if (psCommand->ui32DevIndex >= SYS_DEVICE_COUNT)
700 PVR_DPF((PVR_DBG_ERROR,
701 "PVRSRVProcessCommand: invalid DeviceType 0x%x",
702 psCommand->ui32DevIndex));
703 return PVRSRV_ERROR_INVALID_PARAMS;
707 psCmdCompleteData = psSysData->ppsCmdCompleteData[psCommand->ui32DevIndex][psCommand->CommandType];
708 if (psCmdCompleteData->bInUse)
711 return PVRSRV_ERROR_FAILED_DEPENDENCIES;
715 psCmdCompleteData->bInUse = IMG_TRUE;
718 psCmdCompleteData->ui32DstSyncCount = psCommand->ui32DstSyncCount;
719 for (i=0; i<psCommand->ui32DstSyncCount; i++)
721 psCmdCompleteData->psDstSync[i] = psCommand->psDstSync[i];
723 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Dst %lu RO-VA:0x%lx WO-VA:0x%lx ROP:0x%lx WOP:0x%lx",
724 i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
725 psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
726 psCmdCompleteData->psDstSync[i].ui32ReadOpsPending,
727 psCmdCompleteData->psDstSync[i].ui32WriteOpsPending));
731 psCmdCompleteData->ui32SrcSyncCount = psCommand->ui32SrcSyncCount;
732 for (i=0; i<psCommand->ui32SrcSyncCount; i++)
734 psCmdCompleteData->psSrcSync[i] = psCommand->psSrcSync[i];
736 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVProcessCommand: Src %lu RO-VA:0x%lx WO-VA:0x%lx ROP:0x%lx WOP:0x%lx",
737 i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
738 psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
739 psCmdCompleteData->psSrcSync[i].ui32ReadOpsPending,
740 psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending));
753 if (psSysData->ppfnCmdProcList[psCommand->ui32DevIndex][psCommand->CommandType]((IMG_HANDLE)psCmdCompleteData,
754 psCommand->ui32DataSize,
755 psCommand->pvData) == IMG_FALSE)
760 psCmdCompleteData->bInUse = IMG_FALSE;
761 eError = PVRSRV_ERROR_CMD_NOT_PROCESSED;
768 IMG_VOID PVRSRVProcessQueues_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
770 if (psDeviceNode->bReProcessDeviceCommandComplete &&
771 psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
773 (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
778 PVRSRV_ERROR PVRSRVProcessQueues(IMG_UINT32 ui32CallerID,
781 PVRSRV_QUEUE_INFO *psQueue;
783 PVRSRV_COMMAND *psCommand;
786 SysAcquireData(&psSysData);
789 psSysData->bReProcessQueues = IMG_FALSE;
792 eError = OSLockResource(&psSysData->sQProcessResource,
794 if(eError != PVRSRV_OK)
797 psSysData->bReProcessQueues = IMG_TRUE;
800 if(ui32CallerID == ISR_ID)
804 PVR_DPF((PVR_DBG_ERROR,"PVRSRVProcessQueues: Couldn't acquire queue processing lock for FLUSH"));
808 PVR_DPF((PVR_DBG_MESSAGE,"PVRSRVProcessQueues: Couldn't acquire queue processing lock"));
813 PVR_DPF((PVR_DBG_MESSAGE,"PVRSRVProcessQueues: Queue processing lock-acquire failed when called from the Services driver."));
814 PVR_DPF((PVR_DBG_MESSAGE," This is due to MISR queue processing being interrupted by the Services driver."));
820 psQueue = psSysData->psQueueList;
824 PVR_DPF((PVR_DBG_MESSAGE,"No Queues installed - cannot process commands"));
829 PVRSRVSetDCState(DC_STATE_FLUSH_COMMANDS);
834 while (psQueue->ui32ReadOffset != psQueue->ui32WriteOffset)
836 psCommand = (PVRSRV_COMMAND*)((IMG_UINTPTR_T)psQueue->pvLinQueueKM + psQueue->ui32ReadOffset);
838 if (PVRSRVProcessCommand(psSysData, psCommand, bFlush) == PVRSRV_OK)
841 UPDATE_QUEUE_ROFF(psQueue, psCommand->ui32CmdSize)
851 psQueue = psQueue->psNextKM;
856 PVRSRVSetDCState(DC_STATE_NO_FLUSH_COMMANDS);
860 List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
861 PVRSRVProcessQueues_ForEachCb);
865 OSUnlockResource(&psSysData->sQProcessResource, ui32CallerID);
868 if(psSysData->bReProcessQueues)
870 return PVRSRV_ERROR_PROCESSING_BLOCKED;
876 #if defined(SUPPORT_CUSTOM_SWAP_OPERATIONS)
878 IMG_VOID PVRSRVFreeCommandCompletePacketKM(IMG_HANDLE hCmdCookie,
879 IMG_BOOL bScheduleMISR)
881 COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie;
884 SysAcquireData(&psSysData);
887 psCmdCompleteData->bInUse = IMG_FALSE;
890 PVRSRVCommandCompleteCallbacks();
892 #if defined(SYS_USING_INTERRUPTS)
895 OSScheduleMISR(psSysData);
898 PVR_UNREFERENCED_PARAMETER(bScheduleMISR);
904 IMG_VOID PVRSRVCommandCompleteKM(IMG_HANDLE hCmdCookie,
905 IMG_BOOL bScheduleMISR)
908 COMMAND_COMPLETE_DATA *psCmdCompleteData = (COMMAND_COMPLETE_DATA *)hCmdCookie;
911 SysAcquireData(&psSysData);
914 for (i=0; i<psCmdCompleteData->ui32DstSyncCount; i++)
916 psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->psSyncData->ui32WriteOpsComplete++;
918 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Dst %lu RO-VA:0x%lx WO-VA:0x%lx ROP:0x%lx WOP:0x%lx",
919 i, psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
920 psCmdCompleteData->psDstSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
921 psCmdCompleteData->psDstSync[i].ui32ReadOpsPending,
922 psCmdCompleteData->psDstSync[i].ui32WriteOpsPending));
926 for (i=0; i<psCmdCompleteData->ui32SrcSyncCount; i++)
928 psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->psSyncData->ui32ReadOpsComplete++;
930 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVCommandCompleteKM: Src %lu RO-VA:0x%lx WO-VA:0x%lx ROP:0x%lx WOP:0x%lx",
931 i, psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sReadOpsCompleteDevVAddr.uiAddr,
932 psCmdCompleteData->psSrcSync[i].psKernelSyncInfoKM->sWriteOpsCompleteDevVAddr.uiAddr,
933 psCmdCompleteData->psSrcSync[i].ui32ReadOpsPending,
934 psCmdCompleteData->psSrcSync[i].ui32WriteOpsPending));
938 psCmdCompleteData->bInUse = IMG_FALSE;
941 PVRSRVCommandCompleteCallbacks();
943 #if defined(SYS_USING_INTERRUPTS)
946 OSScheduleMISR(psSysData);
949 PVR_UNREFERENCED_PARAMETER(bScheduleMISR);
954 IMG_VOID PVRSRVCommandCompleteCallbacks_ForEachCb(PVRSRV_DEVICE_NODE *psDeviceNode)
956 if(psDeviceNode->pfnDeviceCommandComplete != IMG_NULL)
959 (*psDeviceNode->pfnDeviceCommandComplete)(psDeviceNode);
963 IMG_VOID PVRSRVCommandCompleteCallbacks(IMG_VOID)
966 SysAcquireData(&psSysData);
969 List_PVRSRV_DEVICE_NODE_ForEach(psSysData->psDeviceNodeList,
970 PVRSRVCommandCompleteCallbacks_ForEachCb);
974 PVRSRV_ERROR PVRSRVRegisterCmdProcListKM(IMG_UINT32 ui32DevIndex,
975 PFN_CMD_PROC *ppfnCmdProcList,
976 IMG_UINT32 ui32MaxSyncsPerCmd[][2],
977 IMG_UINT32 ui32CmdCount)
982 IMG_SIZE_T ui32AllocSize;
983 PFN_CMD_PROC *ppfnCmdProc;
984 COMMAND_COMPLETE_DATA *psCmdCompleteData;
987 if(ui32DevIndex >= SYS_DEVICE_COUNT)
989 PVR_DPF((PVR_DBG_ERROR,
990 "PVRSRVRegisterCmdProcListKM: invalid DeviceType 0x%x",
992 return PVRSRV_ERROR_INVALID_PARAMS;
996 SysAcquireData(&psSysData);
999 eError = OSAllocMem( PVRSRV_OS_PAGEABLE_HEAP,
1000 ui32CmdCount * sizeof(PFN_CMD_PROC),
1001 (IMG_VOID **)&psSysData->ppfnCmdProcList[ui32DevIndex], IMG_NULL,
1002 "Internal Queue Info structure");
1003 if (eError != PVRSRV_OK)
1005 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc queue"));
1010 ppfnCmdProc = psSysData->ppfnCmdProcList[ui32DevIndex];
1013 for (i=0; i<ui32CmdCount; i++)
1015 ppfnCmdProc[i] = ppfnCmdProcList[i];
1019 ui32AllocSize = ui32CmdCount * sizeof(COMMAND_COMPLETE_DATA*);
1020 eError = OSAllocMem( PVRSRV_OS_NON_PAGEABLE_HEAP,
1022 (IMG_VOID **)&psSysData->ppsCmdCompleteData[ui32DevIndex], IMG_NULL,
1023 "Array of Pointers for Command Store");
1024 if (eError != PVRSRV_OK)
1026 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc CC data"));
1030 for (i=0; i<ui32CmdCount; i++)
1034 ui32AllocSize = sizeof(COMMAND_COMPLETE_DATA)
1035 + ((ui32MaxSyncsPerCmd[i][0]
1036 + ui32MaxSyncsPerCmd[i][1])
1037 * sizeof(PVRSRV_SYNC_OBJECT));
1039 eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
1041 (IMG_VOID **)&psSysData->ppsCmdCompleteData[ui32DevIndex][i],
1043 "Command Complete Data");
1044 if (eError != PVRSRV_OK)
1046 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterCmdProcListKM: Failed to alloc cmd %d",i));
1051 OSMemSet(psSysData->ppsCmdCompleteData[ui32DevIndex][i], 0x00, ui32AllocSize);
1053 psCmdCompleteData = psSysData->ppsCmdCompleteData[ui32DevIndex][i];
1056 psCmdCompleteData->psDstSync = (PVRSRV_SYNC_OBJECT*)
1057 (((IMG_UINTPTR_T)psCmdCompleteData)
1058 + sizeof(COMMAND_COMPLETE_DATA));
1059 psCmdCompleteData->psSrcSync = (PVRSRV_SYNC_OBJECT*)
1060 (((IMG_UINTPTR_T)psCmdCompleteData->psDstSync)
1061 + (sizeof(PVRSRV_SYNC_OBJECT) * ui32MaxSyncsPerCmd[i][0]));
1063 psCmdCompleteData->ui32AllocSize = ui32AllocSize;
1072 if(psSysData->ppsCmdCompleteData[ui32DevIndex] != IMG_NULL)
1074 for (i=0; i<ui32CmdCount; i++)
1076 if (psSysData->ppsCmdCompleteData[ui32DevIndex][i] != IMG_NULL)
1078 ui32AllocSize = sizeof(COMMAND_COMPLETE_DATA)
1079 + ((ui32MaxSyncsPerCmd[i][0]
1080 + ui32MaxSyncsPerCmd[i][1])
1081 * sizeof(PVRSRV_SYNC_OBJECT));
1082 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psSysData->ppsCmdCompleteData[ui32DevIndex][i], IMG_NULL);
1083 psSysData->ppsCmdCompleteData[ui32DevIndex][i] = IMG_NULL;
1086 ui32AllocSize = ui32CmdCount * sizeof(COMMAND_COMPLETE_DATA*);
1087 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psSysData->ppsCmdCompleteData[ui32DevIndex], IMG_NULL);
1088 psSysData->ppsCmdCompleteData[ui32DevIndex] = IMG_NULL;
1091 if(psSysData->ppfnCmdProcList[ui32DevIndex] != IMG_NULL)
1093 ui32AllocSize = ui32CmdCount * sizeof(PFN_CMD_PROC);
1094 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, ui32AllocSize, psSysData->ppfnCmdProcList[ui32DevIndex], IMG_NULL);
1095 psSysData->ppfnCmdProcList[ui32DevIndex] = IMG_NULL;
1103 PVRSRV_ERROR PVRSRVRemoveCmdProcListKM(IMG_UINT32 ui32DevIndex,
1104 IMG_UINT32 ui32CmdCount)
1106 SYS_DATA *psSysData;
1110 if(ui32DevIndex >= SYS_DEVICE_COUNT)
1112 PVR_DPF((PVR_DBG_ERROR,
1113 "PVRSRVRemoveCmdProcListKM: invalid DeviceType 0x%x",
1115 return PVRSRV_ERROR_INVALID_PARAMS;
1119 SysAcquireData(&psSysData);
1121 if(psSysData->ppsCmdCompleteData[ui32DevIndex] == IMG_NULL)
1123 PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveCmdProcListKM: Invalid command array"));
1124 return PVRSRV_ERROR_INVALID_PARAMS;
1128 for(i=0; i<ui32CmdCount; i++)
1131 if(psSysData->ppsCmdCompleteData[ui32DevIndex][i] != IMG_NULL)
1133 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
1134 psSysData->ppsCmdCompleteData[ui32DevIndex][i]->ui32AllocSize,
1135 psSysData->ppsCmdCompleteData[ui32DevIndex][i],
1137 psSysData->ppsCmdCompleteData[ui32DevIndex][i] = IMG_NULL;
1142 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
1143 ui32CmdCount * sizeof(COMMAND_COMPLETE_DATA*),
1144 psSysData->ppsCmdCompleteData[ui32DevIndex],
1146 psSysData->ppsCmdCompleteData[ui32DevIndex] = IMG_NULL;
1150 if(psSysData->ppfnCmdProcList[ui32DevIndex] != IMG_NULL)
1152 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
1153 ui32CmdCount * sizeof(PFN_CMD_PROC),
1154 psSysData->ppfnCmdProcList[ui32DevIndex],
1156 psSysData->ppfnCmdProcList[ui32DevIndex] = IMG_NULL;