1 /*************************************************************************/ /*!
3 @Title Services synchronisation interface
4 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description Implements client side code for services synchronisation
7 @License Dual MIT/GPLv2
9 The contents of this file are subject to the MIT license as set out below.
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
18 The above copyright notice and this permission notice shall be included in
19 all copies or substantial portions of the Software.
21 Alternatively, the contents of this file may be used under the terms of
22 the GNU General Public License Version 2 ("GPL") in which case the provisions
23 of GPL are applicable instead of those above.
25 If you wish to allow use of your version of this file only under the terms of
26 GPL, and not to allow others to use your version of this file under the terms
27 of the MIT license, indicate your decision by deleting the provisions above
28 and replace them with the notice and other provisions required by GPL as set
29 out in the file called "GPL-COPYING" included in this distribution. If you do
30 not delete the provisions above, a recipient may use your version of this file
31 under the terms of either the MIT license or GPL.
33 This License is also included in this distribution in the file called
36 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
37 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
39 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
40 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
41 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
42 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43 */ /**************************************************************************/
45 #include "img_types.h"
46 #include "client_sync_bridge.h"
49 #include "devicemem.h"
50 #include "devicemem_pdump.h"
51 #include "pvr_debug.h"
54 #include "sync_internal.h"
56 #include "pvr_debug.h"
58 #if defined(__KERNEL__)
63 #define SYNC_BLOCK_LIST_CHUNCK_SIZE 10
66 This defines the maximum amount of synchronisation memory
67 that can be allocated per SyncPrim context.
68 In reality this number is meaningless as we would run out
69 of synchronisation memory before we reach this limit, but
70 we need to provide a size to the span RA.
72 #define MAX_SYNC_MEM (4 * 1024 * 1024)
74 typedef struct _SYNC_BLOCK_LIST_
76 IMG_UINT32 ui32BlockCount; /*!< Number of contexts in the list */
77 IMG_UINT32 ui32BlockListSize; /*!< Size of the array contexts */
78 SYNC_PRIM_BLOCK **papsSyncPrimBlock; /*!< Array of syncprim blocks */
81 typedef struct _SYNC_OP_COOKIE_
83 IMG_UINT32 ui32SyncCount;
84 IMG_UINT32 ui32ClientSyncCount;
85 IMG_UINT32 ui32ServerSyncCount;
86 IMG_BOOL bHaveServerSync;
88 IMG_HANDLE hServerCookie;
90 SYNC_BLOCK_LIST *psSyncBlockList;
91 PVRSRV_CLIENT_SYNC_PRIM **papsSyncPrim;
94 If this changes update the calculation of ui32ClientAllocSize
96 IMG_UINT32 *paui32SyncBlockIndex;
97 IMG_UINT32 *paui32Index;
98 IMG_UINT32 *paui32Flags;
99 IMG_UINT32 *paui32FenceValue;
100 IMG_UINT32 *paui32UpdateValue;
104 If this changes update the calculation of ui32ServerAllocSize
106 IMG_HANDLE *pahServerSync;
107 IMG_UINT32 *paui32ServerFlags;
111 Internal interfaces for management of synchronisation block memory
114 AllocSyncPrimitiveBlock(SYNC_PRIM_CONTEXT *psContext,
115 SYNC_PRIM_BLOCK **ppsSyncBlock)
117 SYNC_PRIM_BLOCK *psSyncBlk;
118 DEVMEM_SERVER_EXPORTCOOKIE hServerExportCookie;
119 DEVMEM_EXPORTCOOKIE sExportCookie;
122 psSyncBlk = OSAllocMem(sizeof(SYNC_PRIM_BLOCK));
123 if (psSyncBlk == IMG_NULL)
125 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
128 psSyncBlk->psContext = psContext;
130 /* Allocate sync prim block */
131 eError = BridgeAllocSyncPrimitiveBlock(psContext->hBridge,
132 psContext->hDeviceNode,
133 &psSyncBlk->hServerSyncPrimBlock,
134 &psSyncBlk->ui32FirmwareAddr,
135 &psSyncBlk->ui32SyncBlockSize,
136 &hServerExportCookie);
137 if (eError != PVRSRV_OK)
139 goto fail_blockalloc;
142 /* Make it mappable by the client */
143 eError = DevmemMakeServerExportClientExport(psContext->hBridge,
146 if (eError != PVRSRV_OK)
151 /* Get CPU mapping of the memory block */
152 eError = DevmemImport(psContext->hBridge,
154 PVRSRV_MEMALLOCFLAG_CPU_READABLE,
155 &psSyncBlk->hMemDesc);
158 Regardless of success or failure we "undo" the export
160 DevmemUnmakeServerExportClientExport(psContext->hBridge,
163 if (eError != PVRSRV_OK)
168 eError = DevmemAcquireCpuVirtAddr(psSyncBlk->hMemDesc,
169 (IMG_PVOID *) &psSyncBlk->pui32LinAddr);
170 if (eError != PVRSRV_OK)
175 *ppsSyncBlock = psSyncBlk;
179 DevmemFree(psSyncBlk->hMemDesc);
182 BridgeFreeSyncPrimitiveBlock(psContext->hBridge,
183 psSyncBlk->hServerSyncPrimBlock);
185 OSFreeMem(psSyncBlk);
191 FreeSyncPrimitiveBlock(SYNC_PRIM_BLOCK *psSyncBlk)
193 SYNC_PRIM_CONTEXT *psContext = psSyncBlk->psContext;
195 DevmemReleaseCpuVirtAddr(psSyncBlk->hMemDesc);
196 DevmemFree(psSyncBlk->hMemDesc);
197 BridgeFreeSyncPrimitiveBlock(psContext->hBridge,
198 psSyncBlk->hServerSyncPrimBlock);
199 OSFreeMem(psSyncBlk);
203 SyncPrimBlockImport(RA_PERARENA_HANDLE hArena,
207 RA_LENGTH_T *puiActualSize,
208 RA_PERISPAN_HANDLE *phImport)
210 SYNC_PRIM_CONTEXT *psContext = hArena;
211 SYNC_PRIM_BLOCK *psSyncBlock = IMG_NULL;
212 RA_LENGTH_T uiSpanSize;
215 PVR_UNREFERENCED_PARAMETER(uFlags);
217 PVR_ASSERT(hArena != IMG_NULL);
219 /* Check we've not be called with an unexpected size */
220 PVR_ASSERT(uSize == sizeof(IMG_UINT32));
223 Ensure the synprim context doesn't go away while we have sync blocks
226 OSLockAcquire(psContext->hLock);
227 psContext->ui32RefCount++;
228 OSLockRelease(psContext->hLock);
230 /* Allocate the block of memory */
231 eError = AllocSyncPrimitiveBlock(psContext, &psSyncBlock);
232 if (eError != PVRSRV_OK)
234 PVR_DPF((PVR_DBG_ERROR, "Failed to allocation syncprim block (%d)", eError));
235 goto fail_syncblockalloc;
238 /* Allocate a span for it */
239 bRet = RA_Alloc(psContext->psSpanRA,
240 psSyncBlock->ui32SyncBlockSize,
242 psSyncBlock->ui32SyncBlockSize,
243 &psSyncBlock->uiSpanBase,
246 if (bRet == IMG_FALSE)
252 There is no reason the span RA should return an allocation larger
255 PVR_ASSERT(uiSpanSize == psSyncBlock->ui32SyncBlockSize);
257 *puiBase = psSyncBlock->uiSpanBase;
258 *puiActualSize = psSyncBlock->ui32SyncBlockSize;
259 *phImport = psSyncBlock;
263 FreeSyncPrimitiveBlock(psSyncBlock);
265 OSLockAcquire(psContext->hLock);
266 psContext->ui32RefCount--;
267 OSLockRelease(psContext->hLock);
273 SyncPrimBlockUnimport(RA_PERARENA_HANDLE hArena,
275 RA_PERISPAN_HANDLE hImport)
277 SYNC_PRIM_CONTEXT *psContext = hArena;
278 SYNC_PRIM_BLOCK *psSyncBlock = hImport;
280 PVR_ASSERT(psContext != IMG_NULL);
281 PVR_ASSERT(psSyncBlock != IMG_NULL);
283 PVR_ASSERT(uiBase == psSyncBlock->uiSpanBase);
285 /* Free the span this import is using */
286 RA_Free(psContext->psSpanRA, uiBase);
288 /* Free the syncpim block */
289 FreeSyncPrimitiveBlock(psSyncBlock);
291 /* Drop our reference to the syncprim context */
292 OSLockAcquire(psContext->hLock);
293 psContext->ui32RefCount--;
294 OSLockRelease(psContext->hLock);
297 static INLINE IMG_UINT32 SyncPrimGetOffset(SYNC_PRIM *psSyncInt)
301 PVR_ASSERT(psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL);
304 ui64Temp = psSyncInt->u.sLocal.uiSpanAddr - psSyncInt->u.sLocal.psSyncBlock->uiSpanBase;
305 PVR_ASSERT(ui64Temp<IMG_UINT32_MAX);
306 return (IMG_UINT32)ui64Temp;
309 static IMG_VOID SyncPrimGetCPULinAddr(SYNC_PRIM *psSyncInt)
311 SYNC_PRIM_BLOCK *psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
313 psSyncInt->sCommon.pui32LinAddr = psSyncBlock->pui32LinAddr +
314 (SyncPrimGetOffset(psSyncInt)/sizeof(IMG_UINT32));
317 static IMG_VOID SyncPrimLocalFree(SYNC_PRIM *psSyncInt)
319 SYNC_PRIM_BLOCK *psSyncBlock;
320 SYNC_PRIM_CONTEXT *psContext;
322 PVR_ASSERT(psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL);
323 psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
324 psContext = psSyncBlock->psContext;
326 RA_Free(psContext->psSubAllocRA, psSyncInt->u.sLocal.uiSpanAddr);
329 static IMG_VOID SyncPrimServerFree(SYNC_PRIM *psSyncInt)
333 eError = BridgeServerSyncFree(psSyncInt->u.sServer.hBridge,
334 psSyncInt->u.sServer.hServerSync);
335 if (eError != PVRSRV_OK)
337 /* Doesn't matter if the free fails as resman will cleanup */
338 PVR_DPF((PVR_DBG_ERROR, "SyncPrimServerFree failed"));
342 static IMG_UINT32 SyncPrimGetFirmwareAddrLocal(SYNC_PRIM *psSyncInt)
344 SYNC_PRIM_BLOCK *psSyncBlock;
346 psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
347 return psSyncBlock->ui32FirmwareAddr + SyncPrimGetOffset(psSyncInt);
350 static IMG_UINT32 SyncPrimGetFirmwareAddrServer(SYNC_PRIM *psSyncInt)
352 return psSyncInt->u.sServer.ui32FirmwareAddr;
355 #if !defined(__KERNEL__)
356 static SYNC_BRIDGE_HANDLE _SyncPrimGetBridgeHandleLocal(SYNC_PRIM *psSyncInt)
358 return psSyncInt->u.sLocal.psSyncBlock->psContext->hBridge;
361 static SYNC_BRIDGE_HANDLE _SyncPrimGetBridgeHandleServer(SYNC_PRIM *psSyncInt)
363 return psSyncInt->u.sServer.hBridge;
366 static SYNC_BRIDGE_HANDLE _SyncPrimGetBridgeHandle(PVRSRV_CLIENT_SYNC_PRIM *psSync)
368 SYNC_PRIM *psSyncInt;
369 PVR_ASSERT(psSync != IMG_NULL);
370 psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
372 if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
374 return _SyncPrimGetBridgeHandleLocal(psSyncInt);
376 else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
378 return _SyncPrimGetBridgeHandleServer(psSyncInt);
382 PVR_DPF((PVR_DBG_ERROR, "_SyncPrimGetBridgeHandle: Invalid sync type"));
384 Either the client has given us a bad pointer or there is an
387 PVR_ASSERT(IMG_FALSE);
394 Internal interfaces for management of syncprim block lists
396 static SYNC_BLOCK_LIST *_SyncPrimBlockListCreate(IMG_VOID)
398 SYNC_BLOCK_LIST *psBlockList;
400 psBlockList = OSAllocMem(sizeof(SYNC_BLOCK_LIST) +
401 (sizeof(SYNC_PRIM_BLOCK *)
402 * SYNC_BLOCK_LIST_CHUNCK_SIZE));
408 psBlockList->ui32BlockCount = 0;
409 psBlockList->ui32BlockListSize = SYNC_BLOCK_LIST_CHUNCK_SIZE;
411 psBlockList->papsSyncPrimBlock = OSAllocMem(sizeof(SYNC_PRIM_BLOCK *)
412 * SYNC_BLOCK_LIST_CHUNCK_SIZE);
413 if (!psBlockList->papsSyncPrimBlock)
415 OSFreeMem(psBlockList);
419 OSMemSet(psBlockList->papsSyncPrimBlock,
421 sizeof(SYNC_PRIM_BLOCK *) * psBlockList->ui32BlockListSize);
426 static PVRSRV_ERROR _SyncPrimBlockListAdd(SYNC_BLOCK_LIST *psBlockList,
427 SYNC_PRIM_BLOCK *psSyncPrimBlock)
431 /* Check the context isn't already on the list */
432 for (i=0;i<psBlockList->ui32BlockCount;i++)
434 if (psBlockList->papsSyncPrimBlock[i] == psSyncPrimBlock)
440 /* Check we have space for a new item */
441 if (psBlockList->ui32BlockCount == psBlockList->ui32BlockListSize)
443 SYNC_PRIM_BLOCK **papsNewSyncPrimBlock;
445 papsNewSyncPrimBlock = OSAllocMem(sizeof(SYNC_PRIM_BLOCK *) *
446 (psBlockList->ui32BlockCount +
447 SYNC_BLOCK_LIST_CHUNCK_SIZE));
448 if (!papsNewSyncPrimBlock)
450 return PVRSRV_ERROR_OUT_OF_MEMORY;
453 OSMemSet(psBlockList->papsSyncPrimBlock,
455 sizeof(SYNC_PRIM_BLOCK *) * psBlockList->ui32BlockListSize);
456 OSMemCopy(papsNewSyncPrimBlock,
457 psBlockList->papsSyncPrimBlock,
458 sizeof(SYNC_PRIM_CONTEXT *) *
459 psBlockList->ui32BlockCount);
461 OSFreeMem(psBlockList->papsSyncPrimBlock);
463 psBlockList->papsSyncPrimBlock = papsNewSyncPrimBlock;
464 psBlockList->ui32BlockListSize += SYNC_BLOCK_LIST_CHUNCK_SIZE;
467 /* Add the context to the list */
468 psBlockList->papsSyncPrimBlock[psBlockList->ui32BlockCount++] = psSyncPrimBlock;
472 static PVRSRV_ERROR _SyncPrimBlockListBlockToIndex(SYNC_BLOCK_LIST *psBlockList,
473 SYNC_PRIM_BLOCK *psSyncPrimBlock,
474 IMG_UINT32 *pui32Index)
478 for (i=0;i<psBlockList->ui32BlockCount;i++)
480 if (psBlockList->papsSyncPrimBlock[i] == psSyncPrimBlock)
487 return PVRSRV_ERROR_INVALID_PARAMS;
490 static PVRSRV_ERROR _SyncPrimBlockListHandleArrayCreate(SYNC_BLOCK_LIST *psBlockList,
491 IMG_UINT32 *pui32BlockHandleCount,
492 IMG_HANDLE **ppahHandleList)
494 IMG_HANDLE *pahHandleList;
497 pahHandleList = OSAllocMem(sizeof(IMG_HANDLE) *
498 psBlockList->ui32BlockCount);
501 return PVRSRV_ERROR_OUT_OF_MEMORY;
504 for (i=0;i<psBlockList->ui32BlockCount;i++)
506 pahHandleList[i] = psBlockList->papsSyncPrimBlock[i]->hServerSyncPrimBlock;
509 *ppahHandleList = pahHandleList;
510 *pui32BlockHandleCount = psBlockList->ui32BlockCount;
515 static IMG_VOID _SyncPrimBlockListHandleArrayDestroy(IMG_HANDLE *pahHandleList)
517 OSFreeMem(pahHandleList);
520 static IMG_UINT32 _SyncPrimBlockListGetClientValue(SYNC_BLOCK_LIST *psBlockList,
521 IMG_UINT32 ui32BlockIndex,
522 IMG_UINT32 ui32Index)
524 return psBlockList->papsSyncPrimBlock[ui32BlockIndex]->pui32LinAddr[ui32Index];
527 static IMG_VOID _SyncPrimBlockListDestroy(SYNC_BLOCK_LIST *psBlockList)
529 OSFreeMem(psBlockList->papsSyncPrimBlock);
530 OSFreeMem(psBlockList);
533 static INLINE IMG_UINT32 _Log2(IMG_UINT32 ui32Align)
535 IMG_UINT32 ui32Log2Align = 0;
536 while (!(ui32Align & 1))
539 ui32Align = ui32Align >> 1;
541 PVR_ASSERT(ui32Align == 1);
543 return ui32Log2Align;
550 IMG_INTERNAL PVRSRV_ERROR
551 SyncPrimContextCreate(SYNC_BRIDGE_HANDLE hBridge,
552 IMG_HANDLE hDeviceNode,
553 PSYNC_PRIM_CONTEXT *phSyncPrimContext)
555 SYNC_PRIM_CONTEXT *psContext;
558 psContext = OSAllocMem(sizeof(SYNC_PRIM_CONTEXT));
559 if (psContext == IMG_NULL)
561 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
565 psContext->hBridge = hBridge;
566 psContext->hDeviceNode = hDeviceNode;
568 eError = OSLockCreate(&psContext->hLock, LOCK_TYPE_PASSIVE);
569 if ( eError != PVRSRV_OK)
571 goto fail_lockcreate;
574 OSSNPrintf(psContext->azName, SYNC_PRIM_NAME_SIZE, "Sync Prim RA-%p", psContext);
575 OSSNPrintf(psContext->azSpanName, SYNC_PRIM_NAME_SIZE, "Sync Prim span RA-%p", psContext);
578 Create the RA for sub-allocations of the SynPrim's
581 The import size doesn't matter here as the server will pass
582 back the blocksize when does the import which overrides
583 what we specify here.
586 psContext->psSubAllocRA = RA_Create(psContext->azName,
587 /* Params for imports */
588 _Log2(sizeof(IMG_UINT32)),
591 SyncPrimBlockUnimport,
593 if (psContext->psSubAllocRA == IMG_NULL)
595 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
600 Create the span-management RA
602 The RA requires that we work with linear spans. For our use
603 here we don't require this behaviour as we're always working
604 within offsets of blocks (imports). However, we need to keep
605 the RA happy so we create the "span" management RA which
606 ensures that all are imports are added to the RA in a linear
609 psContext->psSpanRA = RA_Create(psContext->azSpanName,
610 /* Params for imports */
616 if (psContext->psSpanRA == IMG_NULL)
618 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
622 if (!RA_Add(psContext->psSpanRA, 0, MAX_SYNC_MEM, 0, IMG_NULL))
624 RA_Delete(psContext->psSpanRA);
625 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
629 psContext->ui32RefCount = 1;
631 *phSyncPrimContext = psContext;
634 RA_Delete(psContext->psSubAllocRA);
636 OSLockDestroy(psContext->hLock);
638 OSFreeMem(psContext);
643 IMG_INTERNAL IMG_VOID SyncPrimContextDestroy(PSYNC_PRIM_CONTEXT hSyncPrimContext)
645 SYNC_PRIM_CONTEXT *psContext = hSyncPrimContext;
646 IMG_BOOL bDoRefCheck = IMG_TRUE;
649 #if defined(__KERNEL__)
650 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
651 if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
653 bDoRefCheck = IMG_FALSE;
656 OSLockAcquire(psContext->hLock);
657 if (--psContext->ui32RefCount != 0)
659 PVR_DPF((PVR_DBG_ERROR, "SyncPrimContextDestroy: Refcount non-zero: %d", psContext->ui32RefCount));
668 If we fail above then we won't release the lock. However, if that
669 happens things have already gone very wrong and we bail to save
670 freeing memory which might still be in use and holding this lock
671 will show up if anyone is trying to use this context after it has
674 OSLockRelease(psContext->hLock);
676 RA_Delete(psContext->psSpanRA);
677 RA_Delete(psContext->psSubAllocRA);
678 OSLockDestroy(psContext->hLock);
679 OSFreeMem(psContext);
682 IMG_INTERNAL PVRSRV_ERROR SyncPrimAlloc(PSYNC_PRIM_CONTEXT hSyncPrimContext,
683 PVRSRV_CLIENT_SYNC_PRIM **ppsSync,
684 const IMG_CHAR *pszClassName)
686 SYNC_PRIM_CONTEXT *psContext = hSyncPrimContext;
687 SYNC_PRIM_BLOCK *psSyncBlock;
688 SYNC_PRIM *psNewSync;
690 RA_BASE_T uiSpanAddr;
692 psNewSync = OSAllocMem(sizeof(SYNC_PRIM));
693 if (psNewSync == IMG_NULL)
695 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
699 if (!RA_Alloc(psContext->psSubAllocRA,
705 (RA_PERISPAN_HANDLE *) &psSyncBlock))
707 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
710 psNewSync->eType = SYNC_PRIM_TYPE_LOCAL;
711 psNewSync->u.sLocal.uiSpanAddr = uiSpanAddr;
712 psNewSync->u.sLocal.psSyncBlock = psSyncBlock;
713 SyncPrimGetCPULinAddr(psNewSync);
714 *ppsSync = &psNewSync->sCommon;
716 #if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
718 IMG_CHAR szClassName[SYNC_MAX_CLASS_NAME_LEN];
721 /* Copy the class name annotation into a fixed-size array */
722 OSStringNCopy(szClassName, pszClassName, SYNC_MAX_CLASS_NAME_LEN - 1);
723 szClassName[SYNC_MAX_CLASS_NAME_LEN - 1] = 0;
727 /* No class name annotation */
730 /* record this sync */
731 eError = BridgeSyncRecordAdd(
732 psSyncBlock->psContext->hBridge,
733 &psNewSync->u.sLocal.hRecord,
734 psSyncBlock->hServerSyncPrimBlock,
735 psSyncBlock->ui32FirmwareAddr,
736 SyncPrimGetOffset(psNewSync),
737 #if defined(__KERNEL__)
742 OSStringNLength(szClassName, SYNC_MAX_CLASS_NAME_LEN),
746 PVR_UNREFERENCED_PARAMETER(pszClassName);
747 #endif /* if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) */
752 OSFreeMem(psNewSync);
754 PVR_ASSERT(eError != PVRSRV_OK);
759 IMG_INTERNAL IMG_VOID SyncPrimFree(PVRSRV_CLIENT_SYNC_PRIM *psSync)
761 SYNC_PRIM *psSyncInt;
763 PVR_ASSERT(psSync != IMG_NULL);
764 psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
766 if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
768 #if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
770 /* remove this sync record */
771 eError = BridgeSyncRecordRemoveByHandle(
772 psSyncInt->u.sLocal.psSyncBlock->psContext->hBridge,
773 psSyncInt->u.sLocal.hRecord);
774 PVR_ASSERT(PVRSRV_OK == eError);
776 SyncPrimLocalFree(psSyncInt);
778 else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
780 SyncPrimServerFree(psSyncInt);
784 PVR_DPF((PVR_DBG_ERROR, "SyncPrimFree: Invalid sync type"));
786 Either the client has given us a bad pointer or there is an
789 PVR_ASSERT(IMG_FALSE);
793 OSFreeMem(psSyncInt);
797 _SyncPrimSetValue(SYNC_PRIM *psSyncInt, IMG_UINT32 ui32Value)
801 if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
803 SYNC_PRIM_BLOCK *psSyncBlock;
804 SYNC_PRIM_CONTEXT *psContext;
806 psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
807 psContext = psSyncBlock->psContext;
809 eError = BridgeSyncPrimSet(psContext->hBridge,
810 psSyncBlock->hServerSyncPrimBlock,
811 SyncPrimGetOffset(psSyncInt)/sizeof(IMG_UINT32),
813 PVR_ASSERT(eError == PVRSRV_OK);
817 eError = BridgeServerSyncPrimSet(psSyncInt->u.sServer.hBridge,
818 psSyncInt->u.sServer.hServerSync,
820 PVR_ASSERT(eError == PVRSRV_OK);
825 #if defined(NO_HARDWARE)
826 IMG_INTERNAL IMG_VOID
827 SyncPrimNoHwUpdate(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value)
829 SYNC_PRIM *psSyncInt;
831 PVR_ASSERT(psSync != IMG_NULL);
832 psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
834 /* There is no check for the psSyncInt to be LOCAL as this call
835 substitutes the Firmware updating a sync and that sync could
838 _SyncPrimSetValue(psSyncInt, ui32Value);
842 IMG_INTERNAL IMG_VOID
843 SyncPrimSet(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value)
845 SYNC_PRIM *psSyncInt;
847 PVR_ASSERT(psSync != IMG_NULL);
848 psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
850 if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
852 PVR_DPF((PVR_DBG_ERROR, "SyncPrimSet: Invalid sync type"));
853 /*PVR_ASSERT(IMG_FALSE);*/
857 _SyncPrimSetValue(psSyncInt, ui32Value);
860 SyncPrimPDump(psSync);
865 IMG_INTERNAL IMG_UINT32 SyncPrimGetFirmwareAddr(PVRSRV_CLIENT_SYNC_PRIM *psSync)
867 SYNC_PRIM *psSyncInt;
868 PVR_ASSERT(psSync != IMG_NULL);
869 psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
871 if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
873 return SyncPrimGetFirmwareAddrLocal(psSyncInt);
875 else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
877 return SyncPrimGetFirmwareAddrServer(psSyncInt);
881 PVR_DPF((PVR_DBG_ERROR, "SyncPrimGetFirmwareAddr: Invalid sync type"));
883 Either the client has given us a bad pointer or there is an
886 PVR_ASSERT(IMG_FALSE);
891 #if !defined(__KERNEL__)
892 IMG_INTERNAL PVRSRV_ERROR SyncPrimDumpSyncs(IMG_UINT32 ui32SyncCount, PVRSRV_CLIENT_SYNC_PRIM **papsSync, const IMG_CHAR *pcszExtraInfo)
894 #if defined(PVRSRV_NEED_PVR_DPF)
895 SYNC_PRIM *psSyncInt;
896 PVRSRV_CLIENT_SYNC_PRIM **papsServerSync;
897 IMG_UINT32 ui32ServerSyncs = 0;
898 IMG_UINT32 *pui32UID = IMG_NULL;
899 IMG_UINT32 *pui32FWAddr = IMG_NULL;
900 IMG_UINT32 *pui32CurrentOp = IMG_NULL;
901 IMG_UINT32 *pui32NextOp = IMG_NULL;
903 PVRSRV_ERROR eError = PVRSRV_OK;
905 papsServerSync = OSAllocMem(ui32SyncCount * sizeof(PVRSRV_CLIENT_SYNC_PRIM *));
908 return PVRSRV_ERROR_OUT_OF_MEMORY;
911 for (i = 0; i < ui32SyncCount; i++)
913 psSyncInt = IMG_CONTAINER_OF(papsSync[i], SYNC_PRIM, sCommon);
914 if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
916 PVR_DPF((PVR_DBG_ERROR, "%s: sync=local fw=0x%x curr=0x%04x",
918 SyncPrimGetFirmwareAddrLocal(psSyncInt),
919 *psSyncInt->sCommon.pui32LinAddr));
921 else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
923 papsServerSync[ui32ServerSyncs++] = papsSync[i];
927 PVR_DPF((PVR_DBG_ERROR, "SyncPrimDumpSyncs: Invalid sync type"));
929 Either the client has given us a bad pointer or there is an
932 PVR_ASSERT(IMG_FALSE);
933 eError = PVRSRV_ERROR_INVALID_PARAMS;
938 if (ui32ServerSyncs > 0)
940 pui32UID = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
943 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
946 pui32FWAddr = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
949 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
952 pui32CurrentOp = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
955 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
958 pui32NextOp = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
961 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
964 eError = SyncPrimServerGetStatus(ui32ServerSyncs, papsServerSync,
969 if (eError != PVRSRV_OK)
971 PVR_DPF((PVR_DBG_ERROR, "SyncPrimDumpSyncs: Error querying server sync status (%d)",
975 for (i = 0; i < ui32ServerSyncs; i++)
977 PVR_DPF((PVR_DBG_ERROR, "%s: sync=server fw=0x%x curr=0x%04x next=0x%04x id=%u%s",
983 (pui32NextOp[i] - pui32CurrentOp[i] == 1) ? " *" :
984 (pui32NextOp[i] - pui32CurrentOp[i] > 1) ? " **" :
990 OSFreeMem(papsServerSync);
997 OSFreeMem(pui32FWAddr);
1001 OSFreeMem(pui32CurrentOp);
1005 OSFreeMem(pui32NextOp);
1009 PVR_UNREFERENCED_PARAMETER(ui32SyncCount);
1010 PVR_UNREFERENCED_PARAMETER(papsSync);
1011 PVR_UNREFERENCED_PARAMETER(pcszExtraInfo);
1018 PVRSRV_ERROR SyncPrimOpCreate(IMG_UINT32 ui32SyncCount,
1019 PVRSRV_CLIENT_SYNC_PRIM **papsSyncPrim,
1020 PSYNC_OP_COOKIE *ppsCookie)
1022 SYNC_OP_COOKIE *psNewCookie;
1023 SYNC_BLOCK_LIST *psSyncBlockList;
1024 IMG_UINT32 ui32ServerSyncCount = 0;
1025 IMG_UINT32 ui32ClientSyncCount = 0;
1026 IMG_UINT32 ui32ServerAllocSize;
1027 IMG_UINT32 ui32ClientAllocSize;
1028 IMG_UINT32 ui32TotalAllocSize;
1029 IMG_UINT32 ui32ServerIndex = 0;
1030 IMG_UINT32 ui32ClientIndex = 0;
1032 IMG_UINT32 ui32SyncBlockCount;
1034 IMG_HANDLE *pahHandleList;
1036 PVRSRV_ERROR eError;
1038 psSyncBlockList = _SyncPrimBlockListCreate();
1040 if (!psSyncBlockList)
1042 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1046 for (i=0;i<ui32SyncCount;i++)
1048 if (SyncPrimIsServerSync(papsSyncPrim[i]))
1050 ui32ServerSyncCount++;
1054 SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[i];
1056 ui32ClientSyncCount++;
1057 eError = _SyncPrimBlockListAdd(psSyncBlockList, psSync->u.sLocal.psSyncBlock);
1058 if (eError != PVRSRV_OK)
1065 ui32ServerAllocSize = ui32ServerSyncCount * (sizeof(IMG_HANDLE) + sizeof(IMG_UINT32));
1066 ui32ClientAllocSize = ui32ClientSyncCount * (5 * sizeof(IMG_UINT32));
1067 ui32TotalAllocSize = sizeof(SYNC_OP_COOKIE) +
1068 (sizeof(PVRSRV_CLIENT_SYNC_PRIM *) * ui32SyncCount) +
1069 ui32ServerAllocSize +
1070 ui32ClientAllocSize;
1072 psNewCookie = OSAllocMem(ui32TotalAllocSize);
1073 pcPtr = (IMG_CHAR *) psNewCookie;
1077 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1081 /* Setup the pointers */
1082 pcPtr += sizeof(SYNC_OP_COOKIE);
1083 psNewCookie->papsSyncPrim = (PVRSRV_CLIENT_SYNC_PRIM **) pcPtr;
1085 pcPtr += sizeof(PVRSRV_CLIENT_SYNC_PRIM *) * ui32SyncCount;
1086 psNewCookie->paui32SyncBlockIndex = (IMG_UINT32 *) pcPtr;
1088 pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
1089 psNewCookie->paui32Index = (IMG_UINT32 *) pcPtr;
1091 pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
1092 psNewCookie->paui32Flags = (IMG_UINT32 *) pcPtr;
1094 pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
1095 psNewCookie->paui32FenceValue = (IMG_UINT32 *) pcPtr;
1097 pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
1098 psNewCookie->paui32UpdateValue = (IMG_UINT32 *) pcPtr;
1100 pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
1101 psNewCookie->pahServerSync =(IMG_HANDLE *) pcPtr;
1102 pcPtr += sizeof(IMG_HANDLE) * ui32ServerSyncCount;
1104 psNewCookie->paui32ServerFlags =(IMG_UINT32 *) pcPtr;
1105 pcPtr += sizeof(IMG_UINT32) * ui32ServerSyncCount;
1107 /* Check the pointer setup went ok */
1108 PVR_ASSERT(pcPtr == (((IMG_CHAR *) psNewCookie) + ui32TotalAllocSize));
1110 psNewCookie->ui32SyncCount = ui32SyncCount;
1111 psNewCookie->ui32ServerSyncCount = ui32ServerSyncCount;
1112 psNewCookie->ui32ClientSyncCount = ui32ClientSyncCount;
1113 psNewCookie->psSyncBlockList = psSyncBlockList;
1116 Get the bridge handle from the 1st sync.
1118 Note: We assume the all syncs have been created with the same
1119 services connection.
1121 if (SyncPrimIsServerSync(papsSyncPrim[0]))
1123 SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[0];
1125 hBridge = psSync->u.sServer.hBridge;
1129 SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[0];
1131 hBridge = psSync->u.sLocal.psSyncBlock->psContext->hBridge;
1134 psNewCookie->hBridge = hBridge;
1136 if (ui32ServerSyncCount)
1138 psNewCookie->bHaveServerSync = IMG_TRUE;
1142 psNewCookie->bHaveServerSync = IMG_FALSE;
1145 /* Fill in the server and client sync data */
1146 for (i=0;i<ui32SyncCount;i++)
1148 SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[i];
1150 if (SyncPrimIsServerSync(papsSyncPrim[i]))
1152 psNewCookie->pahServerSync[ui32ServerIndex] = psSync->u.sServer.hServerSync;
1158 /* Location of sync */
1159 eError = _SyncPrimBlockListBlockToIndex(psSyncBlockList,
1160 psSync->u.sLocal.psSyncBlock,
1161 &psNewCookie->paui32SyncBlockIndex[ui32ClientIndex]);
1162 if (eError != PVRSRV_OK)
1167 /* Workout the index to sync */
1168 psNewCookie->paui32Index[ui32ClientIndex] =
1169 SyncPrimGetOffset(psSync)/sizeof(IMG_UINT32);
1174 psNewCookie->papsSyncPrim[i] = papsSyncPrim[i];
1177 eError = _SyncPrimBlockListHandleArrayCreate(psSyncBlockList,
1178 &ui32SyncBlockCount,
1180 if (eError !=PVRSRV_OK)
1186 Create the server side cookie. Here we pass in all the unchanging
1187 data so we only need to pass in the minimum at takeop time
1189 eError = BridgeSyncPrimOpCreate(hBridge,
1192 psNewCookie->ui32ClientSyncCount,
1193 psNewCookie->paui32SyncBlockIndex,
1194 psNewCookie->paui32Index,
1195 psNewCookie->ui32ServerSyncCount,
1196 psNewCookie->pahServerSync,
1197 &psNewCookie->hServerCookie);
1199 /* Free the handle list regardless of error */
1200 _SyncPrimBlockListHandleArrayDestroy(pahHandleList);
1202 if (eError != PVRSRV_OK)
1207 *ppsCookie = psNewCookie;
1211 OSFreeMem(psNewCookie);
1213 _SyncPrimBlockListDestroy(psSyncBlockList);
1219 PVRSRV_ERROR SyncPrimOpTake(PSYNC_OP_COOKIE psCookie,
1220 IMG_UINT32 ui32SyncCount,
1221 PVRSRV_CLIENT_SYNC_PRIM_OP *pasSyncOp)
1223 PVRSRV_ERROR eError;
1224 IMG_UINT32 ui32ServerIndex = 0;
1225 IMG_UINT32 ui32ClientIndex = 0;
1228 /* Copy client sync operations */
1229 for (i=0;i<ui32SyncCount;i++)
1232 Sanity check the client passes in the same syncs as the
1233 ones we got at create time
1235 if (psCookie->papsSyncPrim[i] != pasSyncOp[i].psSync)
1237 return PVRSRV_ERROR_INVALID_PARAMS;
1240 if (SyncPrimIsServerSync(pasSyncOp[i].psSync))
1242 psCookie->paui32ServerFlags[ui32ServerIndex] =
1243 pasSyncOp[i].ui32Flags;
1249 /* Client operation information */
1250 psCookie->paui32Flags[ui32ClientIndex] =
1251 pasSyncOp[i].ui32Flags;
1252 psCookie->paui32FenceValue[ui32ClientIndex] =
1253 pasSyncOp[i].ui32FenceValue;
1254 psCookie->paui32UpdateValue[ui32ClientIndex] =
1255 pasSyncOp[i].ui32UpdateValue;
1261 eError = BridgeSyncPrimOpTake(psCookie->hBridge,
1262 psCookie->hServerCookie,
1263 psCookie->ui32ClientSyncCount,
1264 psCookie->paui32Flags,
1265 psCookie->paui32FenceValue,
1266 psCookie->paui32UpdateValue,
1267 psCookie->ui32ServerSyncCount,
1268 psCookie->paui32ServerFlags);
1274 PVRSRV_ERROR SyncPrimOpReady(PSYNC_OP_COOKIE psCookie,
1277 PVRSRV_ERROR eError;
1278 PVR_ASSERT(psCookie != IMG_NULL);
1281 If we have a server sync we have no choice
1282 but to do the check in the server
1284 if (psCookie->bHaveServerSync)
1286 eError = BridgeSyncPrimOpReady(psCookie->hBridge,
1287 psCookie->hServerCookie,
1289 if (eError != PVRSRV_OK)
1291 PVR_DPF((PVR_DBG_ERROR,
1292 "%s: Failed to do sync check in server (Error = %d)",
1293 __FUNCTION__, eError));
1300 IMG_UINT32 ui32SnapShot;
1301 IMG_BOOL bReady = IMG_TRUE;
1303 for (i=0;i<psCookie->ui32ClientSyncCount;i++)
1305 if ((psCookie->paui32Flags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK) == 0)
1310 ui32SnapShot = _SyncPrimBlockListGetClientValue(psCookie->psSyncBlockList,
1311 psCookie->paui32SyncBlockIndex[i],
1312 psCookie->paui32Index[i]);
1313 if (ui32SnapShot != psCookie->paui32FenceValue[i])
1325 PVR_ASSERT(eError != PVRSRV_OK);
1330 PVRSRV_ERROR SyncPrimOpComplete(PSYNC_OP_COOKIE psCookie)
1332 PVRSRV_ERROR eError;
1334 eError = BridgeSyncPrimOpComplete(psCookie->hBridge,
1335 psCookie->hServerCookie);
1341 IMG_VOID SyncPrimOpDestroy(PSYNC_OP_COOKIE psCookie)
1343 PVRSRV_ERROR eError;
1345 eError = BridgeSyncPrimOpDestroy(psCookie->hBridge,
1346 psCookie->hServerCookie);
1347 PVR_ASSERT(eError == PVRSRV_OK);
1349 _SyncPrimBlockListDestroy(psCookie->psSyncBlockList);
1350 OSFreeMem(psCookie);
1354 PVRSRV_ERROR SyncPrimOpResolve(PSYNC_OP_COOKIE psCookie,
1355 IMG_UINT32 *pui32SyncCount,
1356 PVRSRV_CLIENT_SYNC_PRIM_OP **ppsSyncOp)
1358 IMG_UINT32 ui32ServerIndex = 0;
1359 IMG_UINT32 ui32ClientIndex = 0;
1360 PVRSRV_CLIENT_SYNC_PRIM_OP *psSyncOps;
1363 psSyncOps = OSAllocMem(sizeof(PVRSRV_CLIENT_SYNC_PRIM_OP) *
1364 psCookie->ui32SyncCount);
1367 return PVRSRV_ERROR_OUT_OF_MEMORY;
1370 for (i=0; i<psCookie->ui32SyncCount; i++)
1372 psSyncOps[i].psSync = psCookie->papsSyncPrim[i];
1373 if (SyncPrimIsServerSync(psCookie->papsSyncPrim[i]))
1375 psSyncOps[i].ui32FenceValue = 0;
1376 psSyncOps[i].ui32UpdateValue = 0;
1377 psSyncOps[i].ui32Flags = psCookie->paui32ServerFlags[ui32ServerIndex];
1382 psSyncOps[i].ui32FenceValue = psCookie->paui32FenceValue[ui32ClientIndex];
1383 psSyncOps[i].ui32UpdateValue = psCookie->paui32UpdateValue[ui32ClientIndex];
1384 psSyncOps[i].ui32Flags = psCookie->paui32Flags[ui32ClientIndex];
1389 *ppsSyncOp = psSyncOps;
1390 *pui32SyncCount = psCookie->ui32SyncCount;
1395 #if !defined(__KERNEL__)
1397 PVRSRV_ERROR SyncPrimServerAlloc(SYNC_BRIDGE_HANDLE hBridge,
1398 IMG_HANDLE hDeviceNode,
1399 PVRSRV_CLIENT_SYNC_PRIM **ppsSync,
1400 const IMG_CHAR *pszClassName
1401 PVR_DBG_FILELINE_PARAM)
1403 IMG_CHAR szClassName[SYNC_MAX_CLASS_NAME_LEN];
1404 SYNC_PRIM *psNewSync;
1405 PVRSRV_ERROR eError;
1407 #if !defined(PVR_SYNC_PRIM_ALLOC_TRACE)
1408 PVR_DBG_FILELINE_UNREF();
1410 psNewSync = OSAllocMem(sizeof(SYNC_PRIM));
1411 if (psNewSync == IMG_NULL)
1413 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1416 OSMemSet(psNewSync, 0, sizeof(SYNC_PRIM));
1420 /* Copy the class name annotation into a fixed-size array */
1421 OSStringNCopy(szClassName, pszClassName, SYNC_MAX_CLASS_NAME_LEN - 1);
1422 szClassName[SYNC_MAX_CLASS_NAME_LEN - 1] = 0;
1426 /* No class name annotation */
1430 eError = BridgeServerSyncAlloc(hBridge,
1432 &psNewSync->u.sServer.hServerSync,
1433 &psNewSync->u.sServer.ui32FirmwareAddr,
1434 OSStringNLength(szClassName, SYNC_MAX_CLASS_NAME_LEN),
1437 if (eError != PVRSRV_OK)
1442 #if defined(PVR_SYNC_PRIM_ALLOC_TRACE)
1443 PVR_DPF((PVR_DBG_WARNING, "Allocated sync=server fw=0x%x [%p]" PVR_DBG_FILELINE_FMT,
1444 psNewSync->u.sServer.ui32FirmwareAddr, &psNewSync->sCommon PVR_DBG_FILELINE_ARG));
1447 psNewSync->eType = SYNC_PRIM_TYPE_SERVER;
1448 psNewSync->u.sServer.hBridge = hBridge;
1449 *ppsSync = &psNewSync->sCommon;
1453 OSFreeMem(psNewSync);
1459 PVRSRV_ERROR SyncPrimServerGetStatus(IMG_UINT32 ui32SyncCount,
1460 PVRSRV_CLIENT_SYNC_PRIM **papsSync,
1461 IMG_UINT32 *pui32UID,
1462 IMG_UINT32 *pui32FWAddr,
1463 IMG_UINT32 *pui32CurrentOp,
1464 IMG_UINT32 *pui32NextOp)
1466 PVRSRV_ERROR eError;
1468 SYNC_BRIDGE_HANDLE hBridge = _SyncPrimGetBridgeHandle(papsSync[0]);
1469 IMG_HANDLE *pahServerHandle;
1471 pahServerHandle = OSAllocMem(sizeof(IMG_HANDLE) * ui32SyncCount);
1472 if (pahServerHandle == IMG_NULL)
1474 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1479 Check that all the sync we've been passed are server syncs
1480 and that they all are on the same connection.
1482 for (i=0;i<ui32SyncCount;i++)
1484 SYNC_PRIM *psIntSync = IMG_CONTAINER_OF(papsSync[i], SYNC_PRIM, sCommon);
1486 if (!SyncPrimIsServerSync(papsSync[i]))
1488 eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
1492 if (hBridge != _SyncPrimGetBridgeHandle(papsSync[i]))
1494 PVR_DPF((PVR_DBG_ERROR, "SyncServerGetStatus: Sync connection is different\n"));
1495 eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
1499 pahServerHandle[i] = psIntSync->u.sServer.hServerSync;
1502 eError = BridgeServerSyncGetStatus(hBridge,
1509 OSFreeMem(pahServerHandle);
1511 if (eError != PVRSRV_OK)
1518 OSFreeMem(pahServerHandle);
1520 PVR_ASSERT(eError != PVRSRV_OK);
1527 IMG_BOOL SyncPrimIsServerSync(PVRSRV_CLIENT_SYNC_PRIM *psSync)
1529 SYNC_PRIM *psSyncInt;
1531 PVR_ASSERT(psSync != IMG_NULL);
1532 psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
1533 if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
1542 IMG_HANDLE SyncPrimGetServerHandle(PVRSRV_CLIENT_SYNC_PRIM *psSync)
1544 SYNC_PRIM *psSyncInt;
1546 PVR_ASSERT(psSync != IMG_NULL);
1547 psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
1548 PVR_ASSERT(psSyncInt->eType == SYNC_PRIM_TYPE_SERVER);
1550 return psSyncInt->u.sServer.hServerSync;
1554 PVRSRV_ERROR SyncPrimServerQueueOp(PVRSRV_CLIENT_SYNC_PRIM_OP *psSyncOp)
1556 SYNC_PRIM *psSyncInt;
1558 PVRSRV_ERROR eError;
1560 PVR_ASSERT(psSyncOp != IMG_NULL);
1561 psSyncInt = IMG_CONTAINER_OF(psSyncOp->psSync, SYNC_PRIM, sCommon);
1562 if (psSyncInt->eType != SYNC_PRIM_TYPE_SERVER)
1564 return PVRSRV_ERROR_INVALID_SYNC_PRIM;
1567 PVR_ASSERT(psSyncOp->ui32Flags != 0);
1568 if (psSyncOp->ui32Flags & PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE)
1573 bUpdate = IMG_FALSE;
1576 eError = BridgeServerSyncQueueHWOp(psSyncInt->u.sServer.hBridge,
1577 psSyncInt->u.sServer.hServerSync,
1579 &psSyncOp->ui32FenceValue,
1580 &psSyncOp->ui32UpdateValue);
1585 IMG_INTERNAL IMG_VOID SyncPrimPDump(PVRSRV_CLIENT_SYNC_PRIM *psSync)
1587 SYNC_PRIM *psSyncInt;
1588 SYNC_PRIM_BLOCK *psSyncBlock;
1589 SYNC_PRIM_CONTEXT *psContext;
1590 PVRSRV_ERROR eError;
1592 PVR_ASSERT(psSync != IMG_NULL);
1593 psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
1595 if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
1597 PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDump: Invalid sync type"));
1598 PVR_ASSERT(IMG_FALSE);
1602 psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
1603 psContext = psSyncBlock->psContext;
1605 eError = BridgeSyncPrimPDump(psContext->hBridge,
1606 psSyncBlock->hServerSyncPrimBlock,
1607 SyncPrimGetOffset(psSyncInt));
1609 if (eError != PVRSRV_OK)
1611 PVR_DPF((PVR_DBG_ERROR,
1612 "%s: failed with error %d",
1613 __FUNCTION__, eError));
1615 PVR_ASSERT(eError == PVRSRV_OK);
1618 IMG_INTERNAL IMG_VOID SyncPrimPDumpValue(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value)
1620 SYNC_PRIM *psSyncInt;
1621 SYNC_PRIM_BLOCK *psSyncBlock;
1622 SYNC_PRIM_CONTEXT *psContext;
1623 PVRSRV_ERROR eError;
1625 PVR_ASSERT(psSync != IMG_NULL);
1626 psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
1628 if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
1630 PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDump: Invalid sync type"));
1631 PVR_ASSERT(IMG_FALSE);
1635 psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
1636 psContext = psSyncBlock->psContext;
1638 eError = BridgeSyncPrimPDumpValue(psContext->hBridge,
1639 psSyncBlock->hServerSyncPrimBlock,
1640 SyncPrimGetOffset(psSyncInt),
1643 if (eError != PVRSRV_OK)
1645 PVR_DPF((PVR_DBG_ERROR,
1646 "%s: failed with error %d",
1647 __FUNCTION__, eError));
1649 PVR_ASSERT(eError == PVRSRV_OK);
1652 IMG_INTERNAL IMG_VOID SyncPrimPDumpPol(PVRSRV_CLIENT_SYNC_PRIM *psSync,
1653 IMG_UINT32 ui32Value,
1654 IMG_UINT32 ui32Mask,
1655 PDUMP_POLL_OPERATOR eOperator,
1656 IMG_UINT32 ui32PDumpFlags)
1658 SYNC_PRIM *psSyncInt;
1659 SYNC_PRIM_BLOCK *psSyncBlock;
1660 SYNC_PRIM_CONTEXT *psContext;
1661 PVRSRV_ERROR eError;
1663 PVR_ASSERT(psSync != IMG_NULL);
1664 psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
1666 if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
1668 PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDumpPol: Invalid sync type (expected SYNC_PRIM_TYPE_LOCAL)"));
1669 PVR_ASSERT(IMG_FALSE);
1673 psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
1674 psContext = psSyncBlock->psContext;
1676 eError = BridgeSyncPrimPDumpPol(psContext->hBridge,
1677 psSyncBlock->hServerSyncPrimBlock,
1678 SyncPrimGetOffset(psSyncInt),
1684 if (eError != PVRSRV_OK)
1686 PVR_DPF((PVR_DBG_ERROR,
1687 "%s: failed with error %d",
1688 __FUNCTION__, eError));
1690 PVR_ASSERT(eError == PVRSRV_OK);
1693 IMG_INTERNAL IMG_VOID SyncPrimOpPDumpPol(PSYNC_OP_COOKIE psCookie,
1694 PDUMP_POLL_OPERATOR eOperator,
1695 IMG_UINT32 ui32PDumpFlags)
1697 PVRSRV_ERROR eError;
1699 PVR_ASSERT(psCookie != IMG_NULL);
1701 eError = BridgeSyncPrimOpPDumpPol(psCookie->hBridge,
1702 psCookie->hServerCookie,
1706 if (eError != PVRSRV_OK)
1708 PVR_DPF((PVR_DBG_ERROR,
1709 "%s: failed with error %d",
1710 __FUNCTION__, eError));
1713 PVR_ASSERT(eError == PVRSRV_OK);
1716 IMG_INTERNAL IMG_VOID SyncPrimPDumpCBP(PVRSRV_CLIENT_SYNC_PRIM *psSync,
1717 IMG_UINT64 uiWriteOffset,
1718 IMG_UINT64 uiPacketSize,
1719 IMG_UINT64 uiBufferSize)
1721 SYNC_PRIM *psSyncInt;
1722 SYNC_PRIM_BLOCK *psSyncBlock;
1723 SYNC_PRIM_CONTEXT *psContext;
1724 PVRSRV_ERROR eError;
1726 PVR_ASSERT(psSync != IMG_NULL);
1727 psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
1729 if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
1731 PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDumpCBP: Invalid sync type"));
1732 PVR_ASSERT(IMG_FALSE);
1736 psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
1737 psContext = psSyncBlock->psContext;
1740 #if (defined(_WIN32) && !defined(_WIN64)) || (defined(LINUX) && defined(__i386__))
1741 PVR_ASSERT(uiWriteOffset<IMG_UINT32_MAX);
1742 PVR_ASSERT(uiPacketSize<IMG_UINT32_MAX);
1743 PVR_ASSERT(uiBufferSize<IMG_UINT32_MAX);
1745 eError = BridgeSyncPrimPDumpCBP(psContext->hBridge,
1746 psSyncBlock->hServerSyncPrimBlock,
1747 SyncPrimGetOffset(psSyncInt),
1748 (IMG_UINT32)uiWriteOffset,
1749 (IMG_UINT32)uiPacketSize,
1750 (IMG_UINT32)uiBufferSize);
1752 if (eError != PVRSRV_OK)
1754 PVR_DPF((PVR_DBG_ERROR,
1755 "%s: failed with error %d",
1756 __FUNCTION__, eError));
1758 PVR_ASSERT(eError == PVRSRV_OK);