IMG_INTERNAL PVRSRV_ERROR _DevmemMemDescAlloc(DEVMEM_MEMDESC **ppsMemDesc) { DEVMEM_MEMDESC *psMemDesc; PVRSRV_ERROR eError; psMemDesc = OSAllocMem(sizeof(DEVMEM_MEMDESC)); if (psMemDesc == IMG_NULL) { eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto failAlloc; } /* Structure must be zero'd incase it needs to be freed before it is initialised! */ OSMemSet(psMemDesc, 0, sizeof(DEVMEM_MEMDESC)); eError = OSLockCreate(&psMemDesc->hLock, LOCK_TYPE_PASSIVE); if (eError != PVRSRV_OK) { goto failMDLock; } eError = OSLockCreate(&psMemDesc->sDeviceMemDesc.hLock, LOCK_TYPE_PASSIVE); if (eError != PVRSRV_OK) { goto failDMDLock; } eError = OSLockCreate(&psMemDesc->sCPUMemDesc.hLock, LOCK_TYPE_PASSIVE); if (eError != PVRSRV_OK) { goto failCMDLock; } *ppsMemDesc = psMemDesc; return PVRSRV_OK; failCMDLock: OSLockDestroy(psMemDesc->sDeviceMemDesc.hLock); failDMDLock: OSLockDestroy(psMemDesc->hLock); failMDLock: OSFreeMem(psMemDesc); failAlloc: PVR_ASSERT(eError != PVRSRV_OK); return eError; }
static PVRSRV_ERROR SyncRecordListInit(IMG_VOID) { PVRSRV_ERROR eError; eError = OSLockCreate(&g_hSyncRecordListLock, LOCK_TYPE_NONE); if (eError != PVRSRV_OK) { goto fail_lock_create; } dllist_init(&g_sSyncRecordList); eError = PVRSRVRegisterDbgRequestNotify(&g_hSyncRecordNotify, _SyncRecordRequest, DEBUG_REQUEST_SERVERSYNC, IMG_NULL); if (eError != PVRSRV_OK) { goto fail_dbg_register; } return PVRSRV_OK; fail_dbg_register: OSLockDestroy(g_hSyncRecordListLock);; fail_lock_create: return eError; }
/* SyncRegisterConnection */ PVRSRV_ERROR SyncRegisterConnection(SYNC_CONNECTION_DATA **ppsSyncConnectionData) { SYNC_CONNECTION_DATA *psSyncConnectionData; PVRSRV_ERROR eError; psSyncConnectionData = OSAllocMem(sizeof(SYNC_CONNECTION_DATA)); if (psSyncConnectionData == IMG_NULL) { eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto fail_alloc; } eError = OSLockCreate(&psSyncConnectionData->hLock, LOCK_TYPE_PASSIVE); if (eError != PVRSRV_OK) { goto fail_lockcreate; } dllist_init(&psSyncConnectionData->sListHead); psSyncConnectionData->ui32RefCount = 1; *ppsSyncConnectionData = psSyncConnectionData; return PVRSRV_OK; fail_lockcreate: OSFreeMem(psSyncConnectionData); fail_alloc: PVR_ASSERT(eError != PVRSRV_OK); return eError; }
PVRSRV_ERROR ServerSyncInit(IMG_VOID) { PVRSRV_ERROR eError; eError = OSLockCreate(&g_hListLock, LOCK_TYPE_NONE); if (eError != PVRSRV_OK) { goto fail_lock_create; } dllist_init(&g_sAllServerSyncs); eError = PVRSRVRegisterDbgRequestNotify(&g_hNotify, _ServerSyncDebugRequest, DEBUG_REQUEST_SERVERSYNC, IMG_NULL); if (eError != PVRSRV_OK) { goto fail_dbg_register; } return PVRSRV_OK; fail_dbg_register: OSLockDestroy(g_hListLock);; fail_lock_create: return eError; }
PVRSRV_ERROR ServerSyncInit(IMG_VOID) { PVRSRV_ERROR eError; eError = OSLockCreate(&g_hListLock, LOCK_TYPE_NONE); if (eError != PVRSRV_OK) { goto fail_lock_create; } dllist_init(&g_sAllServerSyncs); eError = PVRSRVRegisterDbgRequestNotify(&g_hNotify, _ServerSyncDebugRequest, DEBUG_REQUEST_SERVERSYNC, IMG_NULL); if (eError != PVRSRV_OK) { goto fail_dbg_register; } #if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) eError = SyncRecordListInit(); if (eError != PVRSRV_OK) { goto fail_record_list; } #endif return PVRSRV_OK; #if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) fail_record_list: PVRSRVUnregisterDbgRequestNotify(g_hNotify); #endif fail_dbg_register: OSLockDestroy(g_hListLock);; fail_lock_create: return eError; }
/* TLInit must only be called once at driver initialisation for one device. * An assert is provided to check this condition on debug builds. */ PVRSRV_ERROR TLInit(PVRSRV_DEVICE_NODE *psDevNode) { PVRSRV_ERROR eError; PVR_DPF_ENTERED; PVR_ASSERT(psDevNode); PVR_ASSERT(sTLGlobalData.psRgxDevNode==0); /* Store the RGX device node for later use in devmem buffer allocations */ sTLGlobalData.psRgxDevNode = (IMG_VOID*)psDevNode; /* Allocate a lock for TL global data, to be used while updating the TL data. * This is for making TL global data muti-thread safe */ eError = OSLockCreate (&sTLGlobalData.hTLGDLock, LOCK_TYPE_PASSIVE); if (eError != PVRSRV_OK) { goto e0; } /* Allocate the event object used to signal global TL events such as * new stream created */ eError = OSEventObjectCreate("TLGlobalEventObj", &sTLGlobalData.hTLEventObj); if (eError != PVRSRV_OK) { goto e1; } PVR_DPF_RETURN_OK; /* Don't allow the driver to start up on error */ e1: OSLockDestroy (sTLGlobalData.hTLGDLock); sTLGlobalData.hTLGDLock = NULL; e0: PVR_DPF_RETURN_RC (eError); }
/* Allocate and init an import structure */ IMG_INTERNAL PVRSRV_ERROR _DevmemImportStructAlloc(IMG_HANDLE hBridge, IMG_BOOL bExportable, DEVMEM_IMPORT **ppsImport) { DEVMEM_IMPORT *psImport; PVRSRV_ERROR eError; psImport = OSAllocMem(sizeof *psImport); if (psImport == IMG_NULL) { return PVRSRV_ERROR_OUT_OF_MEMORY; } /* Setup some known bad values for things we don't have yet */ psImport->sDeviceImport.hReservation = LACK_OF_RESERVATION_POISON; psImport->sDeviceImport.hMapping = LACK_OF_MAPPING_POISON; psImport->sDeviceImport.psHeap = IMG_NULL; psImport->sDeviceImport.bMapped = IMG_FALSE; eError = OSLockCreate(&psImport->sDeviceImport.hLock, LOCK_TYPE_PASSIVE); if (eError != PVRSRV_OK) { goto failDIOSLockCreate; } psImport->sCPUImport.hOSMMapData = IMG_NULL; psImport->sCPUImport.pvCPUVAddr = IMG_NULL; eError = OSLockCreate(&psImport->sCPUImport.hLock, LOCK_TYPE_PASSIVE); if (eError != PVRSRV_OK) { goto failCIOSLockCreate; } /* Set up common elements */ psImport->hBridge = hBridge; psImport->bExportable = bExportable; /* Setup refcounts */ psImport->sDeviceImport.ui32RefCount = 0; psImport->sCPUImport.ui32RefCount = 0; psImport->ui32RefCount = 0; /* Create the lock */ eError = OSLockCreate(&psImport->hLock, LOCK_TYPE_PASSIVE); if (eError != PVRSRV_OK) { goto failILockAlloc; } #if !defined(__KERNEL__) && defined(SUPPORT_ION) psImport->sCPUImport.iDmaBufFd = -1; #endif *ppsImport = psImport; return PVRSRV_OK; failILockAlloc: OSLockDestroy(psImport->sCPUImport.hLock); failCIOSLockCreate: OSLockDestroy(psImport->sDeviceImport.hLock); failDIOSLockCreate: OSFreeMem(psImport); PVR_ASSERT(eError != PVRSRV_OK); return eError; }
/* SCPCreate */ IMG_EXPORT PVRSRV_ERROR IMG_CALLCONV SCPCreate(IMG_UINT32 ui32CCBSizeLog2, SCP_CONTEXT **ppsContext) { SCP_CONTEXT *psContext; IMG_UINT32 ui32Power2QueueSize = 1 << ui32CCBSizeLog2; PVRSRV_ERROR eError; /* allocate an internal queue info structure */ psContext = OSAllocMem(sizeof(SCP_CONTEXT)); if (psContext == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR,"SCPCreate: Failed to alloc queue struct")); eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ErrorExit; } OSMemSet(psContext, 0, sizeof(SCP_CONTEXT)); /* allocate the command queue buffer - allow for overrun */ psContext->pvCCB = OSAllocMem(ui32Power2QueueSize); if (psContext->pvCCB == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR,"SCPCreate: Failed to alloc queue buffer")); eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ErrorExit; } /* Sanity check: Should be zeroed by OSMemSet */ PVR_ASSERT(psContext->ui32ReadOffset == 0); PVR_ASSERT(psContext->ui32WriteOffset == 0); psContext->ui32CCBSize = ui32Power2QueueSize; eError = OSLockCreate(&psContext->hLock, LOCK_TYPE_NONE); if (eError != PVRSRV_OK) { goto ErrorExit; } eError = PVRSRVServerSyncRequesterRegisterKM(&psContext->psSyncRequesterID); if (eError != PVRSRV_OK) { goto ErrorExit; } SCP_DEBUG_PRINT("%s: New SCP %p of size %d", __FUNCTION__, psContext, ui32Power2QueueSize); *ppsContext = psContext; return PVRSRV_OK; ErrorExit: if(psContext) { if(psContext->pvCCB) { OSFreeMem(psContext->pvCCB); psContext->pvCCB = IMG_NULL; } OSFreeMem(psContext); } return eError; }
PVRSRV_ERROR PVRSRVServerSyncAllocKM(PVRSRV_DEVICE_NODE *psDevNode, SERVER_SYNC_PRIMITIVE **ppsSync, IMG_UINT32 *pui32SyncPrimVAddr, IMG_UINT32 ui32ClassNameSize, const IMG_CHAR *pszClassName) { SERVER_SYNC_PRIMITIVE *psNewSync; PVRSRV_ERROR eError; psNewSync = OSAllocMem(sizeof(SERVER_SYNC_PRIMITIVE)); if (psNewSync == IMG_NULL) { return PVRSRV_ERROR_OUT_OF_MEMORY; } /* szClassName must be setup now and used for the SyncPrimAlloc call because * pszClassName is allocated in the bridge code is not NULL terminated */ if(pszClassName) { if (ui32ClassNameSize >= SYNC_MAX_CLASS_NAME_LEN) ui32ClassNameSize = SYNC_MAX_CLASS_NAME_LEN - 1; /* Copy over the class name annotation */ OSStringNCopy(psNewSync->szClassName, pszClassName, ui32ClassNameSize); psNewSync->szClassName[ui32ClassNameSize] = 0; } else { /* No class name annotation */ psNewSync->szClassName[0] = 0; } eError = SyncPrimAlloc(psDevNode->hSyncPrimContext, &psNewSync->psSync, psNewSync->szClassName); if (eError != PVRSRV_OK) { goto fail_sync_alloc; } eError = OSLockCreate(&psNewSync->hLock, LOCK_TYPE_NONE); if (eError != PVRSRV_OK) { goto fail_lock_create; } SyncPrimSet(psNewSync->psSync, 0); psNewSync->ui32NextOp = 0; psNewSync->ui32RefCount = 1; psNewSync->ui32UID = g_ServerSyncUID++; psNewSync->ui32LastSyncRequesterID = SYNC_REQUESTOR_UNKNOWN; psNewSync->bSWOperation = IMG_FALSE; psNewSync->ui32LastHWUpdate = 0x0bad592c; psNewSync->bPDumped = IMG_FALSE; /* Add the sync to the global list */ OSLockAcquire(g_hListLock); dllist_add_to_head(&g_sAllServerSyncs, &psNewSync->sNode); OSLockRelease(g_hListLock); *pui32SyncPrimVAddr = SyncPrimGetFirmwareAddr(psNewSync->psSync); SYNC_UPDATES_PRINT("%s: sync: %p, fwaddr: %8.8X", __FUNCTION__, psNewSync, *pui32SyncPrimVAddr); *ppsSync = psNewSync; return PVRSRV_OK; fail_lock_create: SyncPrimFree(psNewSync->psSync); fail_sync_alloc: OSFreeMem(psNewSync); return eError; }
PVRSRV_ERROR PVRSRVAllocSyncPrimitiveBlockKM(CONNECTION_DATA *psConnection, PVRSRV_DEVICE_NODE *psDevNode, SYNC_PRIMITIVE_BLOCK **ppsSyncBlk, IMG_UINT32 *puiSyncPrimVAddr, IMG_UINT32 *puiSyncPrimBlockSize, DEVMEM_EXPORTCOOKIE **psExportCookie) { SYNC_PRIMITIVE_BLOCK *psNewSyncBlk; PVRSRV_ERROR eError; psNewSyncBlk = OSAllocMem(sizeof(SYNC_PRIMITIVE_BLOCK)); if (psNewSyncBlk == IMG_NULL) { eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto e0; } psNewSyncBlk->psDevNode = psDevNode; PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Allocate UFO block"); eError = psDevNode->pfnAllocUFOBlock(psDevNode, &psNewSyncBlk->psMemDesc, puiSyncPrimVAddr, &psNewSyncBlk->ui32BlockSize); if (eError != PVRSRV_OK) { goto e1; } eError = DevmemAcquireCpuVirtAddr(psNewSyncBlk->psMemDesc, (IMG_PVOID *) &psNewSyncBlk->pui32LinAddr); if (eError != PVRSRV_OK) { goto e2; } eError = DevmemExport(psNewSyncBlk->psMemDesc, &psNewSyncBlk->sExportCookie); if (eError != PVRSRV_OK) { goto e3; } eError = OSLockCreate(&psNewSyncBlk->hLock, LOCK_TYPE_NONE); if (eError != PVRSRV_OK) { goto e4; } psNewSyncBlk->ui32RefCount = 1; /* If there is a connection pointer then add the new block onto it's list */ _SyncConnectionAddBlock(psConnection, psNewSyncBlk); *psExportCookie = &psNewSyncBlk->sExportCookie; *ppsSyncBlk = psNewSyncBlk; *puiSyncPrimBlockSize = psNewSyncBlk->ui32BlockSize; PDUMPCOMMENTWITHFLAGS(PDUMP_FLAGS_CONTINUOUS, "Allocated UFO block (FirmwareVAddr = 0x%08x)", *puiSyncPrimVAddr); return PVRSRV_OK; e4: DevmemUnexport(psNewSyncBlk->psMemDesc, &psNewSyncBlk->sExportCookie); e3: DevmemReleaseCpuVirtAddr(psNewSyncBlk->psMemDesc); e2: psDevNode->pfnFreeUFOBlock(psDevNode, psNewSyncBlk->psMemDesc); e1: OSFreeMem(psNewSyncBlk); e0: return eError; }