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;
}
Exemple #2
0
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;
}
static IMG_BOOL PagesAreContiguous(struct IMG_SYS_PHYADDR *psSysPhysAddr,
				   u32 ui32Bytes)
{
	u32 ui32;
	u32 ui32AddrChk;
	u32 ui32NumPages = RANGE_TO_PAGES(ui32Bytes);

	for (ui32 = 0, ui32AddrChk = psSysPhysAddr[0].uiAddr;
	     ui32 < ui32NumPages; ui32++, ui32AddrChk += PAGE_SIZE)
		if (psSysPhysAddr[ui32].uiAddr != ui32AddrChk)
			return IMG_FALSE;

	return IMG_TRUE;
}
Exemple #4
0
static void inv_cache_page_list(const struct LinuxMemArea *mem_area)
{
	u32 pg_cnt;
	struct page **pg_list;

	extern void ___dma_single_dev_to_cpu(const void *, size_t,
			                enum dma_data_direction);

	pg_cnt = RANGE_TO_PAGES(mem_area->ui32ByteSize);
	pg_list = mem_area->uData.sPageList.pvPageList;
	while (pg_cnt--)
		___dma_single_dev_to_cpu(page_address(*pg_list++), PAGE_SIZE,
				DMA_FROM_DEVICE);
}
BCE_ERROR BCAllocDiscontigMemory(unsigned long ulSize,
                              BCE_HANDLE unref__ *phMemHandle,
                              IMG_CPU_VIRTADDR *pLinAddr,
                              IMG_SYS_PHYADDR **ppPhysAddr)
{
	unsigned long ulPages = RANGE_TO_PAGES(ulSize);
	IMG_SYS_PHYADDR *pPhysAddr;
	unsigned long ulPage;
	IMG_CPU_VIRTADDR LinAddr;

	LinAddr = __vmalloc(ulSize, GFP_KERNEL | __GFP_HIGHMEM, pgprot_noncached(PAGE_KERNEL));
	if (!LinAddr)
	{
		return BCE_ERROR_OUT_OF_MEMORY;
	}

	pPhysAddr = kmalloc(ulPages * sizeof(IMG_SYS_PHYADDR), GFP_KERNEL);
	if (!pPhysAddr)
	{
		vfree(LinAddr);
		return BCE_ERROR_OUT_OF_MEMORY;
	}

	*pLinAddr = LinAddr;

	for (ulPage = 0; ulPage < ulPages; ulPage++)
	{
		pPhysAddr[ulPage].uiAddr = VMALLOC_TO_PAGE_PHYS(LinAddr);

		LinAddr += PAGE_SIZE;
	}

	*ppPhysAddr = pPhysAddr;

	return BCE_OK;
}