static PVRSRV_ERROR UnmapDeviceClassMemoryCallBack(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL gDummy) { PVRSRV_DC_MAPINFO *psDCMapInfo = pvParam; PVRSRV_KERNEL_MEM_INFO *psMemInfo; PVR_UNREFERENCED_PARAMETER(ui32Param); psMemInfo = psDCMapInfo->psMemInfo; #if defined(SUPPORT_MEMORY_TILING) if(psDCMapInfo->ui32TilingStride > 0) { PVRSRV_DEVICE_NODE *psDeviceNode = psDCMapInfo->psDeviceNode; if (psDeviceNode->pfnFreeMemTilingRange(psDeviceNode, psDCMapInfo->ui32RangeIndex) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceClassMemoryCallBack: FreeMemTilingRange failed")); } } #endif OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_MAPINFO), psDCMapInfo, IMG_NULL); return FreeMemCallBackCommon(psMemInfo, ui32Param, IMG_TRUE); }
static PVRSRV_ERROR BM_DestroyContextCallBack_AnyVaCb(BM_HEAP *psBMHeap, va_list va) { PVRSRV_DEVICE_NODE *psDeviceNode; psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*); if(psBMHeap->ui32Attribs & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) { if (psBMHeap->pImportArena) { RA_Delete (psBMHeap->pImportArena); } } else { PVR_DPF((PVR_DBG_ERROR, "BM_DestroyContext: backing store type unsupported")); return PVRSRV_ERROR_UNSUPPORTED_BACKING_STORE; } psDeviceNode->pfnMMUDelete(psBMHeap->pMMUHeap); OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL); return PVRSRV_OK; }
static IMG_VOID _SyncPrimitiveBlockUnref(SYNC_PRIMITIVE_BLOCK *psSyncBlk) { IMG_UINT32 ui32RefCount; OSLockAcquire(psSyncBlk->hLock); ui32RefCount = --psSyncBlk->ui32RefCount; OSLockRelease(psSyncBlk->hLock); if (ui32RefCount == 0) { PVRSRV_DEVICE_NODE *psDevNode = psSyncBlk->psDevNode; SYNC_REFCOUNT_PRINT("%s: Sync block %p, refcount = %d (remove)", __FUNCTION__, psSyncBlk, ui32RefCount); _SyncConnectionRemoveBlock(psSyncBlk); OSLockDestroy(psSyncBlk->hLock); DevmemUnexport(psSyncBlk->psMemDesc, &psSyncBlk->sExportCookie); DevmemReleaseCpuVirtAddr(psSyncBlk->psMemDesc); psDevNode->pfnFreeUFOBlock(psDevNode, psSyncBlk->psMemDesc); OSFreeMem(psSyncBlk); } else { SYNC_REFCOUNT_PRINT("%s: Sync block %p, refcount = %d", __FUNCTION__, psSyncBlk, ui32RefCount); } }
static IMG_VOID DevMemoryFree (BM_MAPPING *pMapping) { PVRSRV_DEVICE_NODE *psDeviceNode; #ifdef PDUMP IMG_UINT32 ui32PSize; #endif #ifdef PDUMP if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY) { ui32PSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize; } else { ui32PSize = pMapping->uSize; } PDUMPFREEPAGES(pMapping->pBMHeap, pMapping->DevVAddr, ui32PSize, pMapping->pBMHeap->sDevArena.ui32DataPageSize, (IMG_HANDLE)pMapping, (pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) ? IMG_TRUE : IMG_FALSE); #endif psDeviceNode = pMapping->pBMHeap->pBMContext->psDeviceNode; psDeviceNode->pfnMMUFree (pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr, IMG_CAST_TO_DEVVADDR_UINT(pMapping->uSize)); }
PVRSRV_ERROR PDumpFreePages(BM_HEAP * psBMHeap, IMG_DEV_VIRTADDR sDevVAddr, u32 ui32NumBytes, u32 ui32PageSize, void *hUniqueTag, int bInterleaved) { PVRSRV_ERROR eErr; u32 ui32NumPages, ui32PageCounter; IMG_DEV_PHYADDR sDevPAddr; PVRSRV_DEVICE_NODE *psDeviceNode; PDUMP_GET_SCRIPT_STRING(); PVR_ASSERT(((u32) sDevVAddr.uiAddr & (ui32PageSize - 1)) == 0); PVR_ASSERT(((u32) ui32NumBytes & (ui32PageSize - 1)) == 0); eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "-- FREE :SGXMEM:VA_%8.8lX\r\n", sDevVAddr.uiAddr); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); ui32NumPages = ui32NumBytes / ui32PageSize; psDeviceNode = psBMHeap->pBMContext->psDeviceNode; for (ui32PageCounter = 0; ui32PageCounter < ui32NumPages; ui32PageCounter++) { if (!bInterleaved || (ui32PageCounter % 2) == 0) { sDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(psBMHeap-> pMMUHeap, sDevVAddr); { eErr = PDumpOSBufprintf(hScript, ui32MaxLen, "FREE :SGXMEM:PA_%8.8lX%8.8lX\r\n", (u32) hUniqueTag, sDevPAddr.uiAddr); if (eErr != PVRSRV_OK) { return eErr; } PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS); } } else { } sDevVAddr.uiAddr += ui32PageSize; } return PVRSRV_OK; }
/*! ****************************************************************************** @Function PVRSRVInitialiseDevice @Description initialises device by index @Input ui32DevIndex : Index to the required device @Return PVRSRV_ERROR : ******************************************************************************/ PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice (IMG_UINT32 ui32DevIndex) { PVRSRV_DEVICE_NODE *psDeviceNode; SYS_DATA *psSysData; PVRSRV_ERROR eError; PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInitialiseDevice")); SysAcquireData(&psSysData); /* Find device in the list */ psDeviceNode = (PVRSRV_DEVICE_NODE*) List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, &MatchDeviceKM_AnyVaCb, ui32DevIndex, IMG_TRUE); if(!psDeviceNode) { /* Devinfo not in the list */ PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: requested device is not present")); return PVRSRV_ERROR_INIT_FAILURE; } /* FoundDevice: */ PVR_ASSERT (psDeviceNode->ui32RefCount > 0); /* Create the device's resource manager context. */ eError = PVRSRVResManConnect(IMG_NULL, &psDeviceNode->hResManContext); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed PVRSRVResManConnect call")); return eError; } /* Initialise the device */ if(psDeviceNode->pfnInitDevice != IMG_NULL) { eError = psDeviceNode->pfnInitDevice(psDeviceNode); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed InitDevice call")); return eError; } } return PVRSRV_OK; }
static PVRSRV_ERROR BM_DestroyContextCallBack(IMG_PVOID pvParam, IMG_UINT32 ui32Param) { BM_CONTEXT *pBMContext = pvParam; PVRSRV_DEVICE_NODE *psDeviceNode; PVRSRV_ERROR eError; PVR_UNREFERENCED_PARAMETER(ui32Param); psDeviceNode = pBMContext->psDeviceNode; eError = List_BM_HEAP_PVRSRV_ERROR_Any_va(pBMContext->psBMHeap, &BM_DestroyContextCallBack_AnyVaCb, psDeviceNode); if (eError != PVRSRV_OK) { return eError; } if (pBMContext->psMMUContext) { psDeviceNode->pfnMMUFinalise(pBMContext->psMMUContext); } if (pBMContext->pBufferHash) { HASH_Delete(pBMContext->pBufferHash); } if (pBMContext == psDeviceNode->sDevMemoryInfo.pBMKernelContext) { psDeviceNode->sDevMemoryInfo.pBMKernelContext = IMG_NULL; } else { List_BM_CONTEXT_Remove(pBMContext); } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_CONTEXT), pBMContext, IMG_NULL); return PVRSRV_OK; }
static IMG_VOID BM_CreateContext_InsertHeap_ForEachVaCb(BM_HEAP *psBMHeap, va_list va) { PVRSRV_DEVICE_NODE *psDeviceNode; BM_CONTEXT *pBMContext; psDeviceNode = va_arg(va, PVRSRV_DEVICE_NODE*); pBMContext = va_arg(va, BM_CONTEXT*); switch(psBMHeap->sDevArena.DevMemHeapType) { case DEVICE_MEMORY_HEAP_SHARED: case DEVICE_MEMORY_HEAP_SHARED_EXPORTED: { psDeviceNode->pfnMMUInsertHeap(pBMContext->psMMUContext, psBMHeap->pMMUHeap); break; } } }
IMG_VOID BM_GetPhysPageAddr(PVRSRV_KERNEL_MEM_INFO *psMemInfo, IMG_DEV_VIRTADDR sDevVPageAddr, IMG_DEV_PHYADDR *psDevPAddr) { PVRSRV_DEVICE_NODE *psDeviceNode; PVR_DPF((PVR_DBG_MESSAGE, "BM_GetPhysPageAddr")); PVR_ASSERT (psMemInfo && psDevPAddr) PVR_ASSERT((sDevVPageAddr.uiAddr & 0xFFF) == 0); psDeviceNode = ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pBMContext->psDeviceNode; *psDevPAddr = psDeviceNode->pfnMMUGetPhysPageAddr(((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping->pBMHeap->pMMUHeap, sDevVPageAddr); }
IMG_VOID BM_DestroyHeap (IMG_HANDLE hDevMemHeap) { BM_HEAP* psBMHeap = (BM_HEAP*)hDevMemHeap; PVRSRV_DEVICE_NODE *psDeviceNode = psBMHeap->pBMContext->psDeviceNode; PVR_DPF((PVR_DBG_MESSAGE, "BM_DestroyHeap")); if(psBMHeap) { if(psBMHeap->ui32Attribs & (PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG |PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG)) { if (psBMHeap->pImportArena) { RA_Delete (psBMHeap->pImportArena); } } else { PVR_DPF((PVR_DBG_ERROR, "BM_DestroyHeap: backing store type unsupported")); return; } psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap); List_BM_HEAP_Remove(psBMHeap); OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL); } else { PVR_DPF ((PVR_DBG_ERROR, "BM_DestroyHeap: invalid heap handle")); } }
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; }
PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex) { PVRSRV_DEVICE_NODE *psDeviceNode; SYS_DATA *psSysData; PVRSRV_ERROR eError; SysAcquireData(&psSysData); psDeviceNode = (PVRSRV_DEVICE_NODE*) List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, &MatchDeviceKM_AnyVaCb, ui32DevIndex, IMG_TRUE); if (!psDeviceNode) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex)); return PVRSRV_ERROR_DEVICEID_NOT_FOUND; } eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex, PVRSRV_DEV_POWER_STATE_OFF, KERNEL_ID, IMG_FALSE); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call")); return eError; } eError = ResManFreeResByCriteria(psDeviceNode->hResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ALLOCATION, IMG_NULL, 0); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed ResManFreeResByCriteria call")); return eError; } if(psDeviceNode->pfnDeInitDevice != IMG_NULL) { eError = psDeviceNode->pfnDeInitDevice(psDeviceNode); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call")); return eError; } } PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE); psDeviceNode->hResManContext = IMG_NULL; List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode); (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex); OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL); return (PVRSRV_OK); }
/*! ****************************************************************************** @Function PVRSRVDeinitialiseDevice @Description This De-inits device @Input ui32DevIndex : Index to the required device @Return PVRSRV_ERROR : ******************************************************************************/ PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex) { PVRSRV_DEVICE_NODE *psDeviceNode; SYS_DATA *psSysData; PVRSRV_ERROR eError; SysAcquireData(&psSysData); psDeviceNode = (PVRSRV_DEVICE_NODE*) List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, &MatchDeviceKM_AnyVaCb, ui32DevIndex, IMG_TRUE); if (!psDeviceNode) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex)); return PVRSRV_ERROR_DEVICEID_NOT_FOUND; } eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVPowerLock call")); return eError; } /* Power down the device if necessary. */ eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex, PVRSRV_DEV_POWER_STATE_OFF); PVRSRVPowerUnlock(KERNEL_ID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call")); return eError; } /* Free the dissociated device memory. */ eError = ResManFreeResByCriteria(psDeviceNode->hResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ALLOCATION, IMG_NULL, 0); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed ResManFreeResByCriteria call")); return eError; } /* De-init the device. */ if(psDeviceNode->pfnDeInitDevice != IMG_NULL) { eError = psDeviceNode->pfnDeInitDevice(psDeviceNode); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call")); return eError; } } /* Close the device's resource manager context. */ PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE); psDeviceNode->hResManContext = IMG_NULL; /* remove node from list */ List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode); /* deallocate id and memory */ (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex); OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL); /*not nulling pointer, out of scope*/ return (PVRSRV_OK); }
IMG_HANDLE BM_CreateHeap (IMG_HANDLE hBMContext, DEVICE_MEMORY_HEAP_INFO *psDevMemHeapInfo) { BM_CONTEXT *pBMContext = (BM_CONTEXT*)hBMContext; PVRSRV_DEVICE_NODE *psDeviceNode; BM_HEAP *psBMHeap; PVR_DPF((PVR_DBG_MESSAGE, "BM_CreateHeap")); if(!pBMContext) { PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: BM_CONTEXT null")); return IMG_NULL; } psDeviceNode = pBMContext->psDeviceNode; if(pBMContext->ui32RefCount > 0) { psBMHeap = (BM_HEAP*)List_BM_HEAP_Any_va(pBMContext->psBMHeap, &BM_CreateHeap_AnyVaCb, psDevMemHeapInfo); if (psBMHeap) { return psBMHeap; } } if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_HEAP), (IMG_PVOID *)&psBMHeap, IMG_NULL, "Buffer Manager Heap") != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: Alloc failed")); return IMG_NULL; } OSMemSet (psBMHeap, 0, sizeof (BM_HEAP)); psBMHeap->sDevArena.ui32HeapID = psDevMemHeapInfo->ui32HeapID; psBMHeap->sDevArena.pszName = psDevMemHeapInfo->pszName; psBMHeap->sDevArena.BaseDevVAddr = psDevMemHeapInfo->sDevVAddrBase; psBMHeap->sDevArena.ui32Size = psDevMemHeapInfo->ui32HeapSize; psBMHeap->sDevArena.DevMemHeapType = psDevMemHeapInfo->DevMemHeapType; psBMHeap->sDevArena.ui32DataPageSize = psDevMemHeapInfo->ui32DataPageSize; psBMHeap->sDevArena.psDeviceMemoryHeapInfo = psDevMemHeapInfo; psBMHeap->ui32Attribs = psDevMemHeapInfo->ui32Attribs; psBMHeap->pBMContext = pBMContext; psBMHeap->pMMUHeap = psDeviceNode->pfnMMUCreate (pBMContext->psMMUContext, &psBMHeap->sDevArena, &psBMHeap->pVMArena, &psBMHeap->psMMUAttrib); if (!psBMHeap->pMMUHeap) { PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: MMUCreate failed")); goto ErrorExit; } psBMHeap->pImportArena = RA_Create (psDevMemHeapInfo->pszBSName, 0, 0, IMG_NULL, MAX(HOST_PAGESIZE(), psBMHeap->sDevArena.ui32DataPageSize), &BM_ImportMemory, &BM_FreeMemory, IMG_NULL, psBMHeap); if(psBMHeap->pImportArena == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: RA_Create failed")); goto ErrorExit; } if(psBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) { psBMHeap->pLocalDevMemArena = psDevMemHeapInfo->psLocalDevMemArena; if(psBMHeap->pLocalDevMemArena == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR, "BM_CreateHeap: LocalDevMemArena null")); goto ErrorExit; } } List_BM_HEAP_Insert(&pBMContext->psBMHeap, psBMHeap); return (IMG_HANDLE)psBMHeap; ErrorExit: if (psBMHeap->pMMUHeap != IMG_NULL) { psDeviceNode->pfnMMUDelete (psBMHeap->pMMUHeap); psDeviceNode->pfnMMUFinalise (pBMContext->psMMUContext); } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_HEAP), psBMHeap, IMG_NULL); return IMG_NULL; }
static IMG_BOOL DevMemoryAlloc (BM_CONTEXT *pBMContext, BM_MAPPING *pMapping, IMG_SIZE_T *pActualSize, IMG_UINT32 uFlags, IMG_UINT32 dev_vaddr_alignment, IMG_DEV_VIRTADDR *pDevVAddr) { PVRSRV_DEVICE_NODE *psDeviceNode; #ifdef PDUMP IMG_UINT32 ui32PDumpSize = pMapping->uSize; #endif psDeviceNode = pBMContext->psDeviceNode; if(uFlags & PVRSRV_MEM_INTERLEAVED) { pMapping->uSize *= 2; } #ifdef PDUMP if(uFlags & PVRSRV_MEM_DUMMY) { ui32PDumpSize = pMapping->pBMHeap->sDevArena.ui32DataPageSize; } #endif if (!psDeviceNode->pfnMMUAlloc (pMapping->pBMHeap->pMMUHeap, pMapping->uSize, pActualSize, 0, dev_vaddr_alignment, &(pMapping->DevVAddr))) { PVR_DPF((PVR_DBG_ERROR, "DevMemoryAlloc ERROR MMU_Alloc")); return IMG_FALSE; } #ifdef SUPPORT_SGX_MMU_BYPASS EnableHostAccess(pBMContext->psMMUContext); #endif #if defined(PDUMP) PDUMPMALLOCPAGES(&psDeviceNode->sDevId, pMapping->DevVAddr.uiAddr, pMapping->CpuVAddr, pMapping->hOSMemHandle, ui32PDumpSize, pMapping->pBMHeap->sDevArena.ui32DataPageSize, #if defined(SUPPORT_PDUMP_MULTI_PROCESS) psDeviceNode->pfnMMUIsHeapShared(pMapping->pBMHeap->pMMUHeap), #else IMG_FALSE, #endif (IMG_HANDLE)pMapping); #endif switch (pMapping->eCpuMemoryOrigin) { case hm_wrapped: case hm_wrapped_virtaddr: case hm_contiguous: { psDeviceNode->pfnMMUMapPages ( pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr, SysCpuPAddrToSysPAddr (pMapping->CpuPAddr), pMapping->uSize, uFlags, (IMG_HANDLE)pMapping); *pDevVAddr = pMapping->DevVAddr; break; } case hm_env: { psDeviceNode->pfnMMUMapShadow ( pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr, pMapping->uSize, pMapping->CpuVAddr, pMapping->hOSMemHandle, pDevVAddr, uFlags, (IMG_HANDLE)pMapping); break; } case hm_wrapped_scatter: case hm_wrapped_scatter_virtaddr: { psDeviceNode->pfnMMUMapScatter (pMapping->pBMHeap->pMMUHeap, pMapping->DevVAddr, pMapping->psSysAddr, pMapping->uSize, uFlags, (IMG_HANDLE)pMapping); *pDevVAddr = pMapping->DevVAddr; break; } default: PVR_DPF((PVR_DBG_ERROR, "Illegal value %d for pMapping->eCpuMemoryOrigin", pMapping->eCpuMemoryOrigin)); return IMG_FALSE; } #ifdef SUPPORT_SGX_MMU_BYPASS DisableHostAccess(pBMContext->psMMUContext); #endif return IMG_TRUE; }