Esempio n. 1
0
IMG_BOOL
BM_Wrap (	IMG_HANDLE hDevMemHeap,
			IMG_SIZE_T ui32Size,
			IMG_SIZE_T ui32Offset,
			IMG_BOOL bPhysContig,
			IMG_SYS_PHYADDR *psSysAddr,
			IMG_VOID *pvCPUVAddr,
			IMG_UINT32 *pui32Flags,
			BM_HANDLE *phBuf)
{
	BM_BUF *pBuf;
	BM_CONTEXT *psBMContext;
	BM_HEAP *psBMHeap;
	SYS_DATA *psSysData;
	IMG_SYS_PHYADDR sHashAddress;
	IMG_UINT32 uFlags;

	psBMHeap = (BM_HEAP*)hDevMemHeap;
	psBMContext = psBMHeap->pBMContext;

	uFlags = psBMHeap->ui32Attribs & (PVRSRV_HAP_CACHETYPE_MASK | PVRSRV_HAP_MAPTYPE_MASK);

	if ((pui32Flags != IMG_NULL) && ((*pui32Flags & PVRSRV_HAP_CACHETYPE_MASK) != 0))
	{
		uFlags &= ~PVRSRV_HAP_CACHETYPE_MASK;
		uFlags |= *pui32Flags & PVRSRV_HAP_CACHETYPE_MASK;
	}

	PVR_DPF ((PVR_DBG_MESSAGE,
		  "BM_Wrap (uSize=0x%x, uOffset=0x%x, bPhysContig=0x%x, pvCPUVAddr=0x%x, uFlags=0x%x)",
			ui32Size, ui32Offset, bPhysContig, (IMG_UINTPTR_T)pvCPUVAddr, uFlags));

	SysAcquireData(&psSysData);

#if defined(PVR_LMA)
	if (bPhysContig)
	{
		if (!ValidSysPAddrRangeForDev(psBMContext->psDeviceNode, *psSysAddr, WRAP_MAPPING_SIZE(ui32Size, ui32Offset)))
		{
			PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: System address range invalid for device"));
			return IMG_FALSE;
		}
	}
	else
	{
		IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE();

		if (!ValidSysPAddrArrayForDev(psBMContext->psDeviceNode, psSysAddr, WRAP_PAGE_COUNT(ui32Size, ui32Offset, ui32HostPageSize), ui32HostPageSize))
		{
			PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: Array of system addresses invalid for device"));
			return IMG_FALSE;
		}
	}
#endif
	
	sHashAddress = psSysAddr[0];

	
	sHashAddress.uiAddr += ui32Offset;

	
	pBuf = (BM_BUF *)HASH_Retrieve(psBMContext->pBufferHash, sHashAddress.uiAddr);

	if(pBuf)
	{
		IMG_SIZE_T ui32MappingSize = HOST_PAGEALIGN (ui32Size + ui32Offset);

		
		if(pBuf->pMapping->uSize == ui32MappingSize && (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped ||
														pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr))
		{
			PVR_DPF((PVR_DBG_MESSAGE,
					"BM_Wrap (Matched previous Wrap! uSize=0x%x, uOffset=0x%x, SysAddr=%08X)",
					ui32Size, ui32Offset, sHashAddress.uiAddr));

			pBuf->ui32RefCount++;
			*phBuf = (BM_HANDLE)pBuf;
			if(pui32Flags)
				*pui32Flags = uFlags;

			return IMG_TRUE;
		}
	}

	
	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
						sizeof (BM_BUF),
						(IMG_PVOID *)&pBuf, IMG_NULL,
						"Buffer Manager buffer") != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: BM_Buf alloc FAILED"));
		return IMG_FALSE;
	}
	OSMemSet(pBuf, 0, sizeof (BM_BUF));

	
	if (WrapMemory (psBMHeap, ui32Size, ui32Offset, bPhysContig, psSysAddr, pvCPUVAddr, uFlags, pBuf) != IMG_TRUE)
	{
		PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: WrapMemory FAILED"));
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL);
		
		return IMG_FALSE;
	}

	
	if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
	{
		
		PVR_ASSERT(SysSysPAddrToCpuPAddr(sHashAddress).uiAddr == pBuf->CpuPAddr.uiAddr);

		if (!HASH_Insert (psBMContext->pBufferHash, sHashAddress.uiAddr, (IMG_UINTPTR_T)pBuf))
		{
			FreeBuf (pBuf, uFlags, IMG_TRUE);
			PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: HASH_Insert FAILED"));
			return IMG_FALSE;
		}
	}

	PVR_DPF ((PVR_DBG_MESSAGE,
			"BM_Wrap (uSize=0x%x, uFlags=0x%x, devVAddr=%08X)",
			ui32Size, uFlags, pBuf->DevVAddr.uiAddr));

	
	pBuf->ui32RefCount = 1;
	*phBuf = (BM_HANDLE)pBuf;
	if(pui32Flags)
	{
		
		*pui32Flags = (uFlags & ~PVRSRV_HAP_MAPTYPE_MASK) | PVRSRV_HAP_MULTI_PROCESS;
	}

	return IMG_TRUE;
}
IMG_BOOL BM_Wrap(void *hDevMemHeap, u32 ui32Size, u32 ui32Offset,
		 IMG_BOOL bPhysContig, struct IMG_SYS_PHYADDR *psSysAddr,
		 void *pvCPUVAddr, u32 *pui32Flags, void **phBuf)
{
	struct BM_BUF *pBuf;
	struct BM_CONTEXT *psBMContext;
	struct BM_HEAP *psBMHeap;
	struct SYS_DATA *psSysData;
	struct IMG_SYS_PHYADDR sHashAddress;
	u32 uFlags;

	psBMHeap = (struct BM_HEAP *)hDevMemHeap;
	psBMContext = psBMHeap->pBMContext;

	uFlags = psBMHeap->ui32Attribs &
		 (PVRSRV_HAP_CACHETYPE_MASK | PVRSRV_HAP_MAPTYPE_MASK);

	if (pui32Flags)
		uFlags |= *pui32Flags;

	PVR_DPF(PVR_DBG_MESSAGE, "BM_Wrap (uSize=0x%x, uOffset=0x%x, "
			"bPhysContig=0x%x, pvCPUVAddr=0x%x, uFlags=0x%x)",
			ui32Size, ui32Offset, bPhysContig, pvCPUVAddr, uFlags);

	if (SysAcquireData(&psSysData) != PVRSRV_OK)
		return IMG_FALSE;

	sHashAddress = psSysAddr[0];

	sHashAddress.uiAddr += ui32Offset;

	pBuf = (struct BM_BUF *)HASH_Retrieve(psBMContext->pBufferHash,
				     (u32) sHashAddress.uiAddr);

	if (pBuf) {
		u32 ui32MappingSize =
		    HOST_PAGEALIGN(ui32Size + ui32Offset);

		if (pBuf->pMapping->uSize == ui32MappingSize &&
		    (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped ||
		      pBuf->pMapping->eCpuMemoryOrigin ==
			hm_wrapped_virtaddr)) {
			PVR_DPF(PVR_DBG_MESSAGE, "BM_Wrap "
				"(Matched previous Wrap! uSize=0x%x, "
				"uOffset=0x%x, SysAddr=%08X)",
				 ui32Size, ui32Offset, sHashAddress.uiAddr);

			pBuf->ui32RefCount++;
			*phBuf = (void *)pBuf;
			if (pui32Flags)
				*pui32Flags = uFlags;

			return IMG_TRUE;
		}
	}

	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_BUF),
		       (void **)&pBuf, NULL) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "BM_Wrap: BM_Buf alloc FAILED");
		return IMG_FALSE;
	}
	OSMemSet(pBuf, 0, sizeof(struct BM_BUF));

	if (WrapMemory(psBMHeap, ui32Size, ui32Offset, bPhysContig, psSysAddr,
			pvCPUVAddr, uFlags, pBuf) != IMG_TRUE) {
		PVR_DPF(PVR_DBG_ERROR, "BM_Wrap: WrapMemory FAILED");
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_BUF), pBuf,
			  NULL);
		return IMG_FALSE;
	}

	if (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped ||
	    pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr) {

		PVR_ASSERT(SysSysPAddrToCpuPAddr(sHashAddress).uiAddr ==
			   pBuf->CpuPAddr.uiAddr);

		if (!HASH_Insert(psBMContext->pBufferHash,
				 (u32)sHashAddress.uiAddr, (u32) pBuf)) {
			FreeBuf(pBuf, uFlags);
			PVR_DPF(PVR_DBG_ERROR, "BM_Wrap: HASH_Insert FAILED");
			return IMG_FALSE;
		}
	}

	PVR_DPF(PVR_DBG_MESSAGE,
		 "BM_Wrap (uSize=0x%x, uFlags=0x%x)=%08X(devVAddr=%08X)",
		 ui32Size, uFlags, pBuf, pBuf->DevVAddr.uiAddr);

	pBuf->ui32RefCount = 1;
	pvr_get_ctx(psBMContext);
	*phBuf = (void *) pBuf;
	if (pui32Flags)
		*pui32Flags = (uFlags & ~PVRSRV_HAP_MAPTYPE_MASK) |
			      PVRSRV_HAP_MULTI_PROCESS;

	return IMG_TRUE;
}