static void BM_FreeMemory(void *h, u32 _base, struct BM_MAPPING *psMapping) { struct BM_HEAP *pBMHeap = h; size_t uPSize; PVR_UNREFERENCED_PARAMETER(_base); PVR_DPF(PVR_DBG_MESSAGE, "BM_FreeMemory (h=%08X, base=0x%x, psMapping=0x%x)", h, _base, psMapping); PVR_ASSERT(psMapping != NULL); if (psMapping == NULL) { PVR_DPF(PVR_DBG_ERROR, "BM_FreeMemory: invalid parameter"); return; } DevMemoryFree(psMapping); if ((psMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) != 0) psMapping->uSize /= 2; if (psMapping->ui32Flags & PVRSRV_MEM_DUMMY) uPSize = psMapping->pBMHeap->sDevArena.ui32DataPageSize; else uPSize = psMapping->uSize; if (pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) { OSFreePages(pBMHeap->ui32Attribs, uPSize, (void *)psMapping->CpuVAddr, psMapping->hOSMemHandle); } else if (pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) { struct IMG_SYS_PHYADDR sSysPAddr; OSUnReservePhys(psMapping->CpuVAddr, uPSize, pBMHeap->ui32Attribs, psMapping->hOSMemHandle); sSysPAddr = SysCpuPAddrToSysPAddr(psMapping->CpuPAddr); RA_Free(pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); } else { PVR_DPF(PVR_DBG_ERROR, "BM_FreeMemory: Invalid backing store type"); } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_MAPPING), psMapping, NULL); PVR_DPF(PVR_DBG_MESSAGE, "..BM_FreeMemory (h=%08X, base=0x%x, psMapping=0x%x)", h, _base, psMapping); }
/*! ****************************************************************************** @Function SysDeinitialise @Description De-initialises kernel services at 'driver unload' time @Return PVRSRV_ERROR ******************************************************************************/ PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) { PVRSRV_ERROR eError; PVR_UNREFERENCED_PARAMETER(psSysData); if(gpsSysData->pvSOCTimerRegisterKM) { OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM, 4, PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, gpsSysData->hSOCTimerRegisterOSMemHandle); } #if defined(SYS_USING_INTERRUPTS) if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) { eError = OSUninstallDeviceLISR(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed")); return eError; } } #endif if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) { eError = OSUninstallMISR(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed")); return eError; } } if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV)) { #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)); /* Reenable SGX clocks whilst SGX is being deinitialised. */ eError = EnableSGXClocksWrap(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed")); return eError; } #endif /* SUPPORT_ACTIVE_POWER_MANAGEMENT */ /* Deinitialise SGX */ eError = PVRSRVDeinitialiseDevice(gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device")); return eError; } } /* Disable system clocks. Must happen after last access to hardware */ if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) { DisableSystemClocks(gpsSysData); } if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_DVFS_INIT)) { eError = SysDvfsDeinitialize(gpsSysSpecificData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to de-init DVFS")); gpsSysData = IMG_NULL; return eError; } } if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_PM_RUNTIME)) { eError = SysPMRuntimeUnregister(); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: Failed to unregister with OSPM!")); gpsSysData = IMG_NULL; return eError; } } if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA)) { eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure")); return eError; } } SysDeinitialiseCommon(gpsSysData); #if defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) if(gsSGXRegsCPUVAddr != IMG_NULL) { #if defined(NO_HARDWARE) /* Free hardware resources. */ OSBaseFreeContigMemory(SYS_OMAP3630_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase); #else #if defined(SGX_OCP_REGS_ENABLED) OSUnMapPhysToLin(gsSGXRegsCPUVAddr, gsSGXDeviceMap.ui32RegsSize, PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, IMG_NULL); gpvOCPRegsLinAddr = IMG_NULL; #endif #endif /* defined(NO_HARDWARE) */ gsSGXRegsCPUVAddr = IMG_NULL; gsSGXDeviceMap.pvRegsCpuVBase = gsSGXRegsCPUVAddr; } #endif /* defined(NO_HARDWARE) || defined(SGX_OCP_REGS_ENABLED) */ gpsSysSpecificData->ui32SysSpecificData = 0; gpsSysSpecificData->bSGXInitComplete = IMG_FALSE; gpsSysData = IMG_NULL; return PVRSRV_OK; }
PVRSRV_ERROR SysDeinitialise (SYS_DATA *psSysData) { PVRSRV_ERROR eError; #if defined(SYS_USING_INTERRUPTS) if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LISR)) { eError = OSUninstallDeviceLISR(psSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallDeviceLISR failed")); return eError; } } #endif if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_MISR)) { eError = OSUninstallMISR(psSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: OSUninstallMISR failed")); return eError; } } if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_INITDEV)) { #if defined(SUPPORT_ACTIVE_POWER_MANAGEMENT) PVR_ASSERT(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)); eError = EnableSGXClocksWrap(gpsSysData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: EnableSGXClocks failed")); return eError; } #endif eError = PVRSRVDeinitialiseDevice (gui32SGXDeviceID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init the device")); return eError; } } #if defined(SGX_OCP_REGS_ENABLED) if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_OCPREGS)) { OSUnMapPhysToLin(gpvOCPRegsLinAddr, SYS_OMAP3430_OCP_REGS_SIZE, PVRSRV_HAP_UNCACHED|PVRSRV_HAP_KERNEL_ONLY, IMG_NULL); } #endif if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_SYSCLOCKS)) { DisableSystemClocks(gpsSysData); } if (SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_ENVDATA)) { eError = OSDeInitEnvData(gpsSysData->pvEnvSpecificData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"SysDeinitialise: failed to de-init env structure")); return eError; } } if(gpsSysData->pvSOCTimerRegisterKM) { OSUnReservePhys(gpsSysData->pvSOCTimerRegisterKM, 4, PVRSRV_HAP_MULTI_PROCESS|PVRSRV_HAP_UNCACHED, gpsSysData->hSOCTimerRegisterOSMemHandle); } SysDeinitialiseCommon(gpsSysData); #if defined(NO_HARDWARE) if(SYS_SPECIFIC_DATA_TEST(gpsSysSpecificData, SYS_SPECIFIC_DATA_ENABLE_LOCATEDEV)) { OSBaseFreeContigMemory(SYS_OMAP3430_SGX_REGS_SIZE, gsSGXRegsCPUVAddr, gsSGXDeviceMap.sRegsCpuPBase); } #endif gpsSysSpecificData->ui32SysSpecificData = 0; gpsSysSpecificData->bSGXInitComplete = IMG_FALSE; gpsSysData = IMG_NULL; return PVRSRV_OK; }
static IMG_VOID FreeBuf (BM_BUF *pBuf, IMG_UINT32 ui32Flags, IMG_BOOL bFromAllocator) { BM_MAPPING *pMapping; PVR_DPF ((PVR_DBG_MESSAGE, "FreeBuf: pBuf=0x%x: DevVAddr=%08X CpuVAddr=0x%x CpuPAddr=%08X", (IMG_UINTPTR_T)pBuf, pBuf->DevVAddr.uiAddr, (IMG_UINTPTR_T)pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr)); pMapping = pBuf->pMapping; if(ui32Flags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) { if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0)) { if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION) { PVR_DPF ((PVR_DBG_ERROR, "FreeBuf: combination of DevVAddr management and RAM backing mode unsupported")); } else { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL); pBuf->pMapping = IMG_NULL; } } } else { if(pBuf->hOSMemHandle != pMapping->hOSMemHandle) { if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0)) { OSReleaseSubMemHandle(pBuf->hOSMemHandle, ui32Flags); } } if(ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION) { if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0)) { PVR_ASSERT(pBuf->ui32ExportCount == 0) RA_Free (pBuf->pMapping->pArena, pBuf->DevVAddr.uiAddr, IMG_FALSE); } } else { if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0)) { switch (pMapping->eCpuMemoryOrigin) { case hm_wrapped: OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle); break; case hm_wrapped_virtaddr: OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle); break; case hm_wrapped_scatter: OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle); break; case hm_wrapped_scatter_virtaddr: OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle); break; default: break; } } if (bFromAllocator) DevMemoryFree (pMapping); if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0)) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL); pBuf->pMapping = IMG_NULL; } } } if ((pBuf->ui32ExportCount == 0) && (pBuf->ui32RefCount == 0)) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_BUF), pBuf, IMG_NULL); } }
static IMG_BOOL WrapMemory (BM_HEAP *psBMHeap, IMG_SIZE_T uSize, IMG_SIZE_T ui32BaseOffset, IMG_BOOL bPhysContig, IMG_SYS_PHYADDR *psAddr, IMG_VOID *pvCPUVAddr, IMG_UINT32 uFlags, BM_BUF *pBuf) { IMG_DEV_VIRTADDR DevVAddr = {0}; BM_MAPPING *pMapping; IMG_BOOL bResult; IMG_SIZE_T const ui32PageSize = HOST_PAGESIZE(); PVR_DPF ((PVR_DBG_MESSAGE, "WrapMemory(psBMHeap=%08X, size=0x%x, offset=0x%x, bPhysContig=0x%x, pvCPUVAddr = 0x%08x, flags=0x%x)", (IMG_UINTPTR_T)psBMHeap, uSize, ui32BaseOffset, bPhysContig, (IMG_UINTPTR_T)pvCPUVAddr, uFlags)); PVR_ASSERT((psAddr->uiAddr & (ui32PageSize - 1)) == 0); PVR_ASSERT(((IMG_UINTPTR_T)pvCPUVAddr & (ui32PageSize - 1)) == 0); uSize += ui32BaseOffset; uSize = HOST_PAGEALIGN (uSize); if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*pMapping), (IMG_PVOID *)&pMapping, IMG_NULL, "Mocked-up mapping") != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSAllocMem(0x%x) FAILED",sizeof(*pMapping))); return IMG_FALSE; } OSMemSet(pMapping, 0, sizeof (*pMapping)); pMapping->uSize = uSize; pMapping->pBMHeap = psBMHeap; if(pvCPUVAddr) { pMapping->CpuVAddr = pvCPUVAddr; if (bPhysContig) { pMapping->eCpuMemoryOrigin = hm_wrapped_virtaddr; pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]); if(OSRegisterMem(pMapping->CpuPAddr, pMapping->CpuVAddr, pMapping->uSize, uFlags, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterMem Phys=0x%08X, Size=%d) failed", pMapping->CpuPAddr.uiAddr, pMapping->uSize)); goto fail_cleanup; } } else { pMapping->eCpuMemoryOrigin = hm_wrapped_scatter_virtaddr; pMapping->psSysAddr = psAddr; if(OSRegisterDiscontigMem(pMapping->psSysAddr, pMapping->CpuVAddr, pMapping->uSize, uFlags, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSRegisterDiscontigMem Size=%d) failed", pMapping->uSize)); goto fail_cleanup; } } } else { if (bPhysContig) { pMapping->eCpuMemoryOrigin = hm_wrapped; pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]); if(OSReservePhys(pMapping->CpuPAddr, pMapping->uSize, uFlags, &pMapping->CpuVAddr, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReservePhys Phys=0x%08X, Size=%d) failed", pMapping->CpuPAddr.uiAddr, pMapping->uSize)); goto fail_cleanup; } } else { pMapping->eCpuMemoryOrigin = hm_wrapped_scatter; pMapping->psSysAddr = psAddr; if(OSReserveDiscontigPhys(pMapping->psSysAddr, pMapping->uSize, uFlags, &pMapping->CpuVAddr, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSReserveDiscontigPhys Size=%d) failed", pMapping->uSize)); goto fail_cleanup; } } } bResult = DevMemoryAlloc(psBMHeap->pBMContext, pMapping, IMG_NULL, uFlags | PVRSRV_MEM_READ | PVRSRV_MEM_WRITE, IMG_CAST_TO_DEVVADDR_UINT(ui32PageSize), &DevVAddr); if (!bResult) { PVR_DPF((PVR_DBG_ERROR, "WrapMemory: DevMemoryAlloc(0x%x) failed", pMapping->uSize)); goto fail_cleanup; } pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + ui32BaseOffset; if(!ui32BaseOffset) { pBuf->hOSMemHandle = pMapping->hOSMemHandle; } else { if(OSGetSubMemHandle(pMapping->hOSMemHandle, ui32BaseOffset, (pMapping->uSize-ui32BaseOffset), uFlags, &pBuf->hOSMemHandle)!=PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "WrapMemory: OSGetSubMemHandle failed")); goto fail_cleanup; } } if(pMapping->CpuVAddr) { pBuf->CpuVAddr = (IMG_VOID*) ((IMG_UINTPTR_T)pMapping->CpuVAddr + ui32BaseOffset); } pBuf->DevVAddr.uiAddr = pMapping->DevVAddr.uiAddr + IMG_CAST_TO_DEVVADDR_UINT(ui32BaseOffset); if(uFlags & PVRSRV_MEM_ZERO) { if(!ZeroBuf(pBuf, pMapping, uSize, uFlags)) { return IMG_FALSE; } } PVR_DPF ((PVR_DBG_MESSAGE, "DevVaddr.uiAddr=%08X", DevVAddr.uiAddr)); PVR_DPF ((PVR_DBG_MESSAGE, "WrapMemory: DevV=%08X CpuP=%08X uSize=0x%x", pMapping->DevVAddr.uiAddr, pMapping->CpuPAddr.uiAddr, pMapping->uSize)); PVR_DPF ((PVR_DBG_MESSAGE, "WrapMemory: DevV=%08X CpuP=%08X uSize=0x%x", pBuf->DevVAddr.uiAddr, pBuf->CpuPAddr.uiAddr, uSize)); pBuf->pMapping = pMapping; return IMG_TRUE; fail_cleanup: if(ui32BaseOffset && pBuf->hOSMemHandle) { OSReleaseSubMemHandle(pBuf->hOSMemHandle, uFlags); } if(pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle)) { switch(pMapping->eCpuMemoryOrigin) { case hm_wrapped: OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle); break; case hm_wrapped_virtaddr: OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle); break; case hm_wrapped_scatter: OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle); break; case hm_wrapped_scatter_virtaddr: OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle); break; default: break; } } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL); return IMG_FALSE; }
static IMG_VOID BM_FreeMemory (IMG_VOID *h, IMG_UINTPTR_T _base, BM_MAPPING *psMapping) { BM_HEAP *pBMHeap = h; IMG_SIZE_T uPSize; PVR_UNREFERENCED_PARAMETER (_base); PVR_DPF ((PVR_DBG_MESSAGE, "BM_FreeMemory (h=0x%x, base=0x%x, psMapping=0x%x)", (IMG_UINTPTR_T)h, _base, (IMG_UINTPTR_T)psMapping)); PVR_ASSERT (psMapping != IMG_NULL); if (psMapping == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: invalid parameter")); return; } DevMemoryFree (psMapping); if((psMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) != 0) { psMapping->uSize /= 2; } if(psMapping->ui32Flags & PVRSRV_MEM_DUMMY) { uPSize = psMapping->pBMHeap->sDevArena.ui32DataPageSize; } else { uPSize = psMapping->uSize; } if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) { OSFreePages(pBMHeap->ui32Attribs, uPSize, (IMG_VOID *) psMapping->CpuVAddr, psMapping->hOSMemHandle); } else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) { IMG_SYS_PHYADDR sSysPAddr; OSUnReservePhys(psMapping->CpuVAddr, uPSize, pBMHeap->ui32Attribs, psMapping->hOSMemHandle); sSysPAddr = SysCpuPAddrToSysPAddr(psMapping->CpuPAddr); RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); } else { PVR_DPF((PVR_DBG_ERROR, "BM_FreeMemory: Invalid backing store type")); } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), psMapping, IMG_NULL); PVR_DPF((PVR_DBG_MESSAGE, "..BM_FreeMemory (h=0x%x, base=0x%x)", (IMG_UINTPTR_T)h, _base)); }
static IMG_BOOL BM_ImportMemory (IMG_VOID *pH, IMG_SIZE_T uRequestSize, IMG_SIZE_T *pActualSize, BM_MAPPING **ppsMapping, IMG_UINT32 uFlags, IMG_UINTPTR_T *pBase) { BM_MAPPING *pMapping; BM_HEAP *pBMHeap = pH; BM_CONTEXT *pBMContext = pBMHeap->pBMContext; IMG_BOOL bResult; IMG_SIZE_T uSize; IMG_SIZE_T uPSize; IMG_UINT32 uDevVAddrAlignment = 0; PVR_DPF ((PVR_DBG_MESSAGE, "BM_ImportMemory (pBMContext=0x%x, uRequestSize=0x%x, uFlags=0x%x, uAlign=0x%x)", (IMG_UINTPTR_T)pBMContext, uRequestSize, uFlags, uDevVAddrAlignment)); PVR_ASSERT (ppsMapping != IMG_NULL); PVR_ASSERT (pBMContext != IMG_NULL); if (ppsMapping == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: invalid parameter")); goto fail_exit; } uSize = HOST_PAGEALIGN (uRequestSize); PVR_ASSERT (uSize >= uRequestSize); if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_MAPPING), (IMG_PVOID *)&pMapping, IMG_NULL, "Buffer Manager Mapping") != PVRSRV_OK) { PVR_DPF ((PVR_DBG_ERROR, "BM_ImportMemory: failed BM_MAPPING alloc")); goto fail_exit; } pMapping->hOSMemHandle = 0; pMapping->CpuVAddr = 0; pMapping->DevVAddr.uiAddr = 0; pMapping->CpuPAddr.uiAddr = 0; pMapping->uSize = uSize; pMapping->pBMHeap = pBMHeap; pMapping->ui32Flags = uFlags; if (pActualSize) { *pActualSize = uSize; } if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY) { uPSize = pBMHeap->sDevArena.ui32DataPageSize; } else { uPSize = pMapping->uSize; } if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) { IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs; if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK) { ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK; ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK); } if (OSAllocPages(ui32Attribs, uPSize, pBMHeap->sDevArena.ui32DataPageSize, (IMG_VOID **)&pMapping->CpuVAddr, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: OSAllocPages(0x%x) failed", uPSize)); goto fail_mapping_alloc; } pMapping->eCpuMemoryOrigin = hm_env; } else if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) { IMG_SYS_PHYADDR sSysPAddr; IMG_UINT32 ui32Attribs = pBMHeap->ui32Attribs; PVR_ASSERT(pBMHeap->pLocalDevMemArena != IMG_NULL); if (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK) { ui32Attribs &= ~PVRSRV_HAP_CACHETYPE_MASK; ui32Attribs |= (pMapping->ui32Flags & PVRSRV_HAP_CACHETYPE_MASK); } if (!RA_Alloc (pBMHeap->pLocalDevMemArena, uPSize, IMG_NULL, IMG_NULL, 0, pBMHeap->sDevArena.ui32DataPageSize, 0, (IMG_UINTPTR_T *)&sSysPAddr.uiAddr)) { PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: RA_Alloc(0x%x) FAILED", uPSize)); goto fail_mapping_alloc; } pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); if(OSReservePhys(pMapping->CpuPAddr, uPSize, ui32Attribs, &pMapping->CpuVAddr, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: OSReservePhys failed")); goto fail_dev_mem_alloc; } pMapping->eCpuMemoryOrigin = hm_contiguous; } else { PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: Invalid backing store type")); goto fail_mapping_alloc; } bResult = DevMemoryAlloc (pBMContext, pMapping, IMG_NULL, uFlags, uDevVAddrAlignment, &pMapping->DevVAddr); if (!bResult) { PVR_DPF((PVR_DBG_ERROR, "BM_ImportMemory: DevMemoryAlloc(0x%x) failed", pMapping->uSize)); goto fail_dev_mem_alloc; } PVR_ASSERT (uDevVAddrAlignment>1?(pMapping->DevVAddr.uiAddr%uDevVAddrAlignment)==0:1); *pBase = pMapping->DevVAddr.uiAddr; *ppsMapping = pMapping; PVR_DPF ((PVR_DBG_MESSAGE, "BM_ImportMemory: IMG_TRUE")); return IMG_TRUE; fail_dev_mem_alloc: if (pMapping && (pMapping->CpuVAddr || pMapping->hOSMemHandle)) { if(pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) { pMapping->uSize /= 2; } if(pMapping->ui32Flags & PVRSRV_MEM_DUMMY) { uPSize = pBMHeap->sDevArena.ui32DataPageSize; } else { uPSize = pMapping->uSize; } if(pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) { OSFreePages(pBMHeap->ui32Attribs, uPSize, (IMG_VOID *)pMapping->CpuVAddr, pMapping->hOSMemHandle); } else { IMG_SYS_PHYADDR sSysPAddr; if(pMapping->CpuVAddr) { OSUnReservePhys(pMapping->CpuVAddr, uPSize, pBMHeap->ui32Attribs, pMapping->hOSMemHandle); } sSysPAddr = SysCpuPAddrToSysPAddr(pMapping->CpuPAddr); RA_Free (pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); } } fail_mapping_alloc: OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(BM_MAPPING), pMapping, IMG_NULL); fail_exit: return IMG_FALSE; }
static void FreeBuf(struct BM_BUF *pBuf, u32 ui32Flags) { struct BM_MAPPING *pMapping; PVR_DPF(PVR_DBG_MESSAGE, "FreeBuf: pBuf=%08X: DevVAddr=%08X CpuVAddr=%08X CpuPAddr=%08X", pBuf, pBuf->DevVAddr.uiAddr, pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr); pMapping = pBuf->pMapping; if (ui32Flags & PVRSRV_MEM_USER_SUPPLIED_DEVVADDR) { if (ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION) PVR_DPF(PVR_DBG_ERROR, "FreeBuf: " "combination of DevVAddr management " "and RAM backing mode unsupported"); else OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_MAPPING), pMapping, NULL); } else { if (pBuf->hOSMemHandle != pMapping->hOSMemHandle) OSReleaseSubMemHandle(pBuf->hOSMemHandle, ui32Flags); if (ui32Flags & PVRSRV_MEM_RAM_BACKED_ALLOCATION) { RA_Free(pBuf->pMapping->pArena, pBuf->DevVAddr.uiAddr, IMG_FALSE); } else { switch (pMapping->eCpuMemoryOrigin) { case hm_wrapped: OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle); break; case hm_wrapped_virtaddr: OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping->hOSMemHandle); break; case hm_wrapped_scatter: OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping-> hOSMemHandle); break; case hm_wrapped_scatter_virtaddr: OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, ui32Flags, pMapping-> hOSMemHandle); break; default: break; } DevMemoryFree(pMapping); OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_MAPPING), pMapping, NULL); } } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_BUF), pBuf, NULL); }
static IMG_BOOL WrapMemory(struct BM_HEAP *psBMHeap, size_t uSize, u32 ui32BaseOffset, IMG_BOOL bPhysContig, struct IMG_SYS_PHYADDR *psAddr, void *pvCPUVAddr, u32 uFlags, struct BM_BUF *pBuf) { struct IMG_DEV_VIRTADDR DevVAddr = { 0 }; struct BM_MAPPING *pMapping; IMG_BOOL bResult; u32 const ui32PageSize = HOST_PAGESIZE(); PVR_DPF(PVR_DBG_MESSAGE, "WrapMemory(psBMHeap=%08X, size=0x%x, offset=0x%x, " "bPhysContig=0x%x, pvCPUVAddr = 0x%x, flags=0x%x, pBuf=%08X)", psBMHeap, uSize, ui32BaseOffset, bPhysContig, pvCPUVAddr, uFlags, pBuf); PVR_ASSERT((psAddr->uiAddr & (ui32PageSize - 1)) == 0); PVR_ASSERT(((u32) pvCPUVAddr & (ui32PageSize - 1)) == 0); uSize += ui32BaseOffset; uSize = HOST_PAGEALIGN(uSize); if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*pMapping), (void **)&pMapping, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "WrapMemory: OSAllocMem(0x%x) FAILED", sizeof(*pMapping)); return IMG_FALSE; } OSMemSet(pMapping, 0, sizeof(*pMapping)); pMapping->uSize = uSize; pMapping->pBMHeap = psBMHeap; if (pvCPUVAddr) { pMapping->CpuVAddr = pvCPUVAddr; if (bPhysContig) { pMapping->eCpuMemoryOrigin = hm_wrapped_virtaddr; pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]); if (OSRegisterMem(pMapping->CpuPAddr, pMapping->CpuVAddr, pMapping->uSize, uFlags, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "WrapMemory: " "OSRegisterMem Phys=0x%08X, " "CpuVAddr = 0x%08X, Size=%d) failed", pMapping->CpuPAddr, pMapping->CpuVAddr, pMapping->uSize); goto fail_cleanup; } } else { pMapping->eCpuMemoryOrigin = hm_wrapped_scatter_virtaddr; pMapping->psSysAddr = psAddr; if (OSRegisterDiscontigMem(pMapping->psSysAddr, pMapping->CpuVAddr, pMapping->uSize, uFlags, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "WrapMemory: " "OSRegisterDiscontigMem CpuVAddr = " "0x%08X, Size=%d) failed", pMapping->CpuVAddr, pMapping->uSize); goto fail_cleanup; } } } else { if (bPhysContig) { pMapping->eCpuMemoryOrigin = hm_wrapped; pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(psAddr[0]); if (OSReservePhys(pMapping->CpuPAddr, pMapping->uSize, uFlags, &pMapping->CpuVAddr, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "WrapMemory: " "OSReservePhys Phys=0x%08X, Size=%d) " "failed", pMapping->CpuPAddr, pMapping->uSize); goto fail_cleanup; } } else { pMapping->eCpuMemoryOrigin = hm_wrapped_scatter; pMapping->psSysAddr = psAddr; if (OSReserveDiscontigPhys(pMapping->psSysAddr, pMapping->uSize, uFlags, &pMapping->CpuVAddr, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "WrapMemory: " "OSReserveDiscontigPhys Size=%d) failed", pMapping->uSize); goto fail_cleanup; } } } bResult = DevMemoryAlloc(psBMHeap->pBMContext, pMapping, uFlags | PVRSRV_MEM_READ | PVRSRV_MEM_WRITE, ui32PageSize, &DevVAddr); if (!bResult) { PVR_DPF(PVR_DBG_ERROR, "WrapMemory: DevMemoryAlloc(0x%x) failed", pMapping->uSize); goto fail_cleanup; } pBuf->CpuPAddr.uiAddr = pMapping->CpuPAddr.uiAddr + ui32BaseOffset; if (!ui32BaseOffset) pBuf->hOSMemHandle = pMapping->hOSMemHandle; else if (OSGetSubMemHandle(pMapping->hOSMemHandle, ui32BaseOffset, (pMapping->uSize - ui32BaseOffset), uFlags, &pBuf->hOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "WrapMemory: OSGetSubMemHandle failed"); goto fail_cleanup; } if (pMapping->CpuVAddr) pBuf->CpuVAddr = (void *)((u32) pMapping->CpuVAddr + ui32BaseOffset); pBuf->DevVAddr.uiAddr = pMapping->DevVAddr.uiAddr + ui32BaseOffset; if (uFlags & PVRSRV_MEM_ZERO) if (!ZeroBuf(pBuf, pMapping, uSize, uFlags)) return IMG_FALSE; PVR_DPF(PVR_DBG_MESSAGE, "DevVaddr.uiAddr=%08X", DevVAddr.uiAddr); PVR_DPF(PVR_DBG_MESSAGE, "WrapMemory: pMapping=%08X: DevV=%08X " "CpuV=%08X CpuP=%08X uSize=0x%x", pMapping, pMapping->DevVAddr.uiAddr, pMapping->CpuVAddr, pMapping->CpuPAddr.uiAddr, pMapping->uSize); PVR_DPF(PVR_DBG_MESSAGE, "WrapMemory: pBuf=%08X: DevV=%08X " "CpuV=%08X CpuP=%08X uSize=0x%x", pBuf, pBuf->DevVAddr.uiAddr, pBuf->CpuVAddr, pBuf->CpuPAddr.uiAddr, uSize); pBuf->pMapping = pMapping; return IMG_TRUE; fail_cleanup: if (ui32BaseOffset && pBuf->hOSMemHandle) OSReleaseSubMemHandle(pBuf->hOSMemHandle, uFlags); if (pMapping->CpuVAddr || pMapping->hOSMemHandle) switch (pMapping->eCpuMemoryOrigin) { case hm_wrapped: OSUnReservePhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle); break; case hm_wrapped_virtaddr: OSUnRegisterMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle); break; case hm_wrapped_scatter: OSUnReserveDiscontigPhys(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle); break; case hm_wrapped_scatter_virtaddr: OSUnRegisterDiscontigMem(pMapping->CpuVAddr, pMapping->uSize, uFlags, pMapping->hOSMemHandle); break; default: break; } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_MAPPING), pMapping, NULL); return IMG_FALSE; }
static IMG_BOOL BM_ImportMemory(void *pH, size_t uRequestSize, size_t *pActualSize, struct BM_MAPPING **ppsMapping, u32 uFlags, u32 *pBase) { struct BM_MAPPING *pMapping; struct BM_HEAP *pBMHeap = pH; struct BM_CONTEXT *pBMContext = pBMHeap->pBMContext; IMG_BOOL bResult; size_t uSize; size_t uPSize; u32 uDevVAddrAlignment = 0; PVR_DPF(PVR_DBG_MESSAGE, "BM_ImportMemory (pBMContext=%08X, uRequestSize=0x%x, " "uFlags=0x%x, uAlign=0x%x)", pBMContext, uRequestSize, uFlags, uDevVAddrAlignment); PVR_ASSERT(ppsMapping != NULL); PVR_ASSERT(pBMContext != NULL); if (ppsMapping == NULL) { PVR_DPF(PVR_DBG_ERROR, "BM_ImportMemory: invalid parameter"); goto fail_exit; } uSize = HOST_PAGEALIGN(uRequestSize); PVR_ASSERT(uSize >= uRequestSize); if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_MAPPING), (void **)&pMapping, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "BM_ImportMemory: failed struct BM_MAPPING alloc"); goto fail_exit; } pMapping->hOSMemHandle = NULL; pMapping->CpuVAddr = NULL; pMapping->DevVAddr.uiAddr = 0; pMapping->CpuPAddr.uiAddr = 0; pMapping->uSize = uSize; pMapping->pBMHeap = pBMHeap; pMapping->ui32Flags = uFlags; if (pActualSize) *pActualSize = uSize; if (pMapping->ui32Flags & PVRSRV_MEM_DUMMY) uPSize = pBMHeap->sDevArena.ui32DataPageSize; else uPSize = pMapping->uSize; if (pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) { if (OSAllocPages(pBMHeap->ui32Attribs, uPSize, pBMHeap->sDevArena.ui32DataPageSize, (void **)&pMapping->CpuVAddr, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "BM_ImportMemory: OSAllocPages(0x%x) failed", uPSize); goto fail_mapping_alloc; } pMapping->eCpuMemoryOrigin = hm_env; } else if (pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_LOCALMEM_CONTIG) { struct IMG_SYS_PHYADDR sSysPAddr; PVR_ASSERT(pBMHeap->pLocalDevMemArena != NULL); if (!RA_Alloc(pBMHeap->pLocalDevMemArena, uPSize, NULL, 0, pBMHeap->sDevArena.ui32DataPageSize, (u32 *)&sSysPAddr.uiAddr)) { PVR_DPF(PVR_DBG_ERROR, "BM_ImportMemory: RA_Alloc(0x%x) FAILED", uPSize); goto fail_mapping_alloc; } pMapping->CpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr); if (OSReservePhys(pMapping->CpuPAddr, uPSize, pBMHeap->ui32Attribs, &pMapping->CpuVAddr, &pMapping->hOSMemHandle) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "BM_ImportMemory: OSReservePhys failed"); goto fail_dev_mem_alloc; } pMapping->eCpuMemoryOrigin = hm_contiguous; } else { PVR_DPF(PVR_DBG_ERROR, "BM_ImportMemory: Invalid backing store type"); goto fail_mapping_alloc; } bResult = DevMemoryAlloc(pBMContext, pMapping, uFlags, uDevVAddrAlignment, &pMapping->DevVAddr); if (!bResult) { PVR_DPF(PVR_DBG_ERROR, "BM_ImportMemory: DevMemoryAlloc(0x%x) failed", pMapping->uSize); goto fail_dev_mem_alloc; } PVR_ASSERT(uDevVAddrAlignment > 1 ? (pMapping->DevVAddr.uiAddr % uDevVAddrAlignment) == 0 : 1); *pBase = pMapping->DevVAddr.uiAddr; *ppsMapping = pMapping; PVR_DPF(PVR_DBG_MESSAGE, "BM_ImportMemory: IMG_TRUE"); return IMG_TRUE; fail_dev_mem_alloc: if (pMapping->CpuVAddr || pMapping->hOSMemHandle) { if (pMapping->ui32Flags & PVRSRV_MEM_INTERLEAVED) pMapping->uSize /= 2; if (pMapping->ui32Flags & PVRSRV_MEM_DUMMY) uPSize = pBMHeap->sDevArena.ui32DataPageSize; else uPSize = pMapping->uSize; if (pBMHeap->ui32Attribs & PVRSRV_BACKINGSTORE_SYSMEM_NONCONTIG) { OSFreePages(pBMHeap->ui32Attribs, uPSize, (void *)pMapping->CpuVAddr, pMapping->hOSMemHandle); } else { struct IMG_SYS_PHYADDR sSysPAddr; if (pMapping->CpuVAddr) OSUnReservePhys(pMapping->CpuVAddr, uPSize, pBMHeap->ui32Attribs, pMapping->hOSMemHandle); sSysPAddr = SysCpuPAddrToSysPAddr(pMapping->CpuPAddr); RA_Free(pBMHeap->pLocalDevMemArena, sSysPAddr.uiAddr, IMG_FALSE); } } fail_mapping_alloc: OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_MAPPING), pMapping, NULL); fail_exit: return IMG_FALSE; }