struct LinuxMemArea *NewIORemapLinuxMemArea(struct IMG_CPU_PHYADDR BasePAddr, u32 ui32Bytes, u32 ui32AreaFlags) { struct LinuxMemArea *psLinuxMemArea; void __iomem *pvIORemapCookie; psLinuxMemArea = LinuxMemAreaStructAlloc(); if (!psLinuxMemArea) return NULL; pvIORemapCookie = IORemapWrapper(BasePAddr, ui32Bytes, ui32AreaFlags); if (!pvIORemapCookie) { LinuxMemAreaStructFree(psLinuxMemArea); return NULL; } psLinuxMemArea->eAreaType = LINUX_MEM_AREA_IOREMAP; psLinuxMemArea->uData.sIORemap.pvIORemapCookie = pvIORemapCookie; psLinuxMemArea->uData.sIORemap.CPUPhysAddr = BasePAddr; psLinuxMemArea->ui32ByteSize = ui32Bytes; psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; psLinuxMemArea->bMMapRegistered = IMG_FALSE; INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); #if defined(DEBUG_LINUX_MEM_AREAS) DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); #endif return psLinuxMemArea; }
void FreeAllocPagesLinuxMemArea(struct LinuxMemArea *psLinuxMemArea) { u32 ui32PageCount; struct page **pvPageList; void *hBlockPageList; u32 i; PVR_ASSERT(psLinuxMemArea); PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_ALLOC_PAGES); #if defined(DEBUG_LINUX_MEM_AREAS) DebugLinuxMemAreaRecordRemove(psLinuxMemArea); #endif ui32PageCount = RANGE_TO_PAGES(psLinuxMemArea->ui32ByteSize); pvPageList = psLinuxMemArea->uData.sPageList.pvPageList; hBlockPageList = psLinuxMemArea->uData.sPageList.hBlockPageList; #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, pvPageList, __FILE__, __LINE__); #endif for (i = 0; i < ui32PageCount; i++) __free_pages(pvPageList[i], 0); OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, hBlockPageList); LinuxMemAreaStructFree(psLinuxMemArea); }
struct LinuxMemArea *NewVMallocLinuxMemArea(u32 ui32Bytes, u32 ui32AreaFlags) { struct LinuxMemArea *psLinuxMemArea; void *pvCpuVAddr; psLinuxMemArea = LinuxMemAreaStructAlloc(); if (!psLinuxMemArea) goto failed; pvCpuVAddr = VMallocWrapper(ui32Bytes, ui32AreaFlags); if (!pvCpuVAddr) goto failed; psLinuxMemArea->eAreaType = LINUX_MEM_AREA_VMALLOC; psLinuxMemArea->uData.sVmalloc.pvVmallocAddress = pvCpuVAddr; psLinuxMemArea->ui32ByteSize = ui32Bytes; psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; psLinuxMemArea->bMMapRegistered = IMG_FALSE; INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); #if defined(DEBUG_LINUX_MEM_AREAS) DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); #endif return psLinuxMemArea; failed: PVR_DPF(PVR_DBG_ERROR, "%s: failed!", __func__); if (psLinuxMemArea) LinuxMemAreaStructFree(psLinuxMemArea); return NULL; }
struct LinuxMemArea *NewAllocPagesLinuxMemArea(u32 ui32Bytes, u32 ui32AreaFlags) { struct LinuxMemArea *psLinuxMemArea; u32 ui32PageCount; struct page **pvPageList; void *hBlockPageList; s32 i; enum PVRSRV_ERROR eError; psLinuxMemArea = LinuxMemAreaStructAlloc(); if (!psLinuxMemArea) goto failed_area_alloc; ui32PageCount = RANGE_TO_PAGES(ui32Bytes); eError = OSAllocMem(0, sizeof(*pvPageList) * ui32PageCount, (void **)&pvPageList, &hBlockPageList); if (eError != PVRSRV_OK) goto failed_page_list_alloc; for (i = 0; i < ui32PageCount; i++) { pvPageList[i] = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, 0); if (!pvPageList[i]) goto failed_alloc_pages; } #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, pvPageList, NULL, 0, NULL, PAGE_ALIGN(ui32Bytes), "unknown", 0); #endif psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ALLOC_PAGES; psLinuxMemArea->uData.sPageList.pvPageList = pvPageList; psLinuxMemArea->uData.sPageList.hBlockPageList = hBlockPageList; psLinuxMemArea->ui32ByteSize = ui32Bytes; psLinuxMemArea->ui32AreaFlags = ui32AreaFlags; psLinuxMemArea->bMMapRegistered = IMG_FALSE; INIT_LIST_HEAD(&psLinuxMemArea->sMMapOffsetStructList); #if defined(DEBUG_LINUX_MEM_AREAS) DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); #endif return psLinuxMemArea; failed_alloc_pages: for (i--; i >= 0; i--) __free_pages(pvPageList[i], 0); OSFreeMem(0, sizeof(*pvPageList) * ui32PageCount, pvPageList, hBlockPageList); failed_page_list_alloc: LinuxMemAreaStructFree(psLinuxMemArea); failed_area_alloc: PVR_DPF(PVR_DBG_ERROR, "%s: failed", __func__); return NULL; }
static void FreeSubLinuxMemArea(struct LinuxMemArea *psLinuxMemArea) { PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_SUB_ALLOC); #if defined(DEBUG_LINUX_MEM_AREAS) DebugLinuxMemAreaRecordRemove(psLinuxMemArea); #endif LinuxMemAreaStructFree(psLinuxMemArea); }
void FreeExternalKVLinuxMemArea(struct LinuxMemArea *psLinuxMemArea) { PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_EXTERNAL_KV); #if defined(DEBUG_LINUX_MEM_AREAS) DebugLinuxMemAreaRecordRemove(psLinuxMemArea); #endif LinuxMemAreaStructFree(psLinuxMemArea); }
void FreeIORemapLinuxMemArea(struct LinuxMemArea *psLinuxMemArea) { PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IOREMAP); #if defined(DEBUG_LINUX_MEM_AREAS) DebugLinuxMemAreaRecordRemove(psLinuxMemArea); #endif IOUnmapWrapper(psLinuxMemArea->uData.sIORemap.pvIORemapCookie); LinuxMemAreaStructFree(psLinuxMemArea); }
struct LinuxMemArea *NewAllocPagesLinuxMemArea(u32 ui32Bytes, u32 ui32AreaFlags) { struct LinuxMemArea *psLinuxMemArea; u32 ui32PageCount; struct page **pvPageList; u32 i; psLinuxMemArea = LinuxMemAreaStructAlloc(); if (!psLinuxMemArea) goto failed_area_alloc; ui32PageCount = RANGE_TO_PAGES(ui32Bytes); pvPageList = VMallocWrapper(sizeof(void *) * ui32PageCount, PVRSRV_HAP_CACHED); if (!pvPageList) goto failed_vmalloc; for (i = 0; i < ui32PageCount; i++) { pvPageList[i] = alloc_pages(GFP_KERNEL, 0); if (!pvPageList[i]) goto failed_alloc_pages; } #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) DebugMemAllocRecordAdd(DEBUG_MEM_ALLOC_TYPE_ALLOC_PAGES, pvPageList, NULL, 0, NULL, PAGE_ALIGN(ui32Bytes), "unknown", 0); #endif psLinuxMemArea->eAreaType = LINUX_MEM_AREA_ALLOC_PAGES; psLinuxMemArea->uData.sPageList.pvPageList = pvPageList; psLinuxMemArea->ui32ByteSize = ui32Bytes; #if defined(DEBUG_LINUX_MEM_AREAS) DebugLinuxMemAreaRecordAdd(psLinuxMemArea, ui32AreaFlags); #endif return psLinuxMemArea; failed_alloc_pages: for (i--; i >= 0; i--) __free_pages(pvPageList[i], 0); VFreeWrapper(pvPageList); failed_vmalloc: LinuxMemAreaStructFree(psLinuxMemArea); failed_area_alloc: PVR_DPF(PVR_DBG_ERROR, "%s: failed", __func__); return NULL; }
void FreeIOLinuxMemArea(struct LinuxMemArea *psLinuxMemArea) { PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_IO); #if defined(DEBUG_LINUX_MEM_AREAS) DebugLinuxMemAreaRecordRemove(psLinuxMemArea); #endif #if defined(DEBUG_LINUX_MEMORY_ALLOCATIONS) DebugMemAllocRecordRemove(DEBUG_MEM_ALLOC_TYPE_IO, (void *)psLinuxMemArea->uData.sIO. CPUPhysAddr.uiAddr, __FILE__, __LINE__); #endif LinuxMemAreaStructFree(psLinuxMemArea); }
void FreeVMallocLinuxMemArea(struct LinuxMemArea *psLinuxMemArea) { PVR_ASSERT(psLinuxMemArea); PVR_ASSERT(psLinuxMemArea->eAreaType == LINUX_MEM_AREA_VMALLOC); PVR_ASSERT(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress); #if defined(DEBUG_LINUX_MEM_AREAS) DebugLinuxMemAreaRecordRemove(psLinuxMemArea); #endif PVR_DPF(PVR_DBG_MESSAGE, "%s: pvCpuVAddr: %p", __func__, psLinuxMemArea->uData.sVmalloc.pvVmallocAddress); VFreeWrapper(psLinuxMemArea->uData.sVmalloc.pvVmallocAddress); LinuxMemAreaStructFree(psLinuxMemArea); }