Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE				hDevCookie,
												PVRSRV_PER_PROCESS_DATA	*psPerProc,
												IMG_HANDLE				hDevMemContext,
												IMG_SIZE_T 				ui32ByteSize,
												IMG_SIZE_T				ui32PageOffset,
												IMG_BOOL				bPhysContig,
												IMG_SYS_PHYADDR	 		*psExtSysPAddr,
												IMG_VOID 				*pvLinAddr,
												IMG_UINT32				ui32Flags,
												PVRSRV_KERNEL_MEM_INFO	**ppsMemInfo)
{
	PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
	DEVICE_MEMORY_INFO  *psDevMemoryInfo;
	IMG_SIZE_T			ui32HostPageSize = HOST_PAGESIZE();
	IMG_HANDLE			hDevMemHeap = IMG_NULL;
	PVRSRV_DEVICE_NODE* psDeviceNode;
	BM_HANDLE 			hBuffer;
	PVRSRV_MEMBLK		*psMemBlock;
	IMG_BOOL			bBMError;
	BM_HEAP				*psBMHeap;
	PVRSRV_ERROR		eError;
	IMG_VOID 			*pvPageAlignedCPUVAddr;
	IMG_SYS_PHYADDR	 	*psIntSysPAddr = IMG_NULL;
	IMG_HANDLE			hOSWrapMem = IMG_NULL;
	DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;	
	IMG_UINT32		i;
        IMG_SIZE_T              ui32PageCount = 0;
	
	
	psDeviceNode = (PVRSRV_DEVICE_NODE*)hDevCookie;
	PVR_ASSERT(psDeviceNode != IMG_NULL);

	if (psDeviceNode == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: invalid parameter"));
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	if(pvLinAddr)
	{
		
		ui32PageOffset = (IMG_UINTPTR_T)pvLinAddr & (ui32HostPageSize - 1);

		
		ui32PageCount = HOST_PAGEALIGN(ui32ByteSize + ui32PageOffset) / ui32HostPageSize;
		pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvLinAddr - ui32PageOffset);

		
		if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
						ui32PageCount * sizeof(IMG_SYS_PHYADDR),
						(IMG_VOID **)&psIntSysPAddr, IMG_NULL,
						"Array of Page Addresses") != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
			return PVRSRV_ERROR_OUT_OF_MEMORY;
		}

		eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr,
										ui32PageCount * ui32HostPageSize,
										psIntSysPAddr,
										&hOSWrapMem);
		if(eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
			goto ErrorExitPhase1;
		}

		
		psExtSysPAddr = psIntSysPAddr;

		

		bPhysContig = IMG_FALSE;
	}
	else
	{
		
	}
	
	
	psDevMemoryInfo = &((BM_CONTEXT*)hDevMemContext)->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,"PVRSRVWrapExtMemoryKM: unable to find mapping heap"));
		eError = PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP;
		goto ErrorExitPhase2;
	}

	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
					sizeof(PVRSRV_KERNEL_MEM_INFO),
					(IMG_VOID **)&psMemInfo, IMG_NULL,
					"Kernel Memory Info") != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto ErrorExitPhase2;
	}

	OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
	psMemInfo->ui32Flags = ui32Flags;

	psMemBlock = &(psMemInfo->sMemBlk);

	bBMError = BM_Wrap(hDevMemHeap,
					   ui32ByteSize,
					   ui32PageOffset,
					   bPhysContig,
					   psExtSysPAddr,
					   IMG_NULL,
					   &psMemInfo->ui32Flags,
					   &hBuffer);
	if (!bBMError)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: BM_Wrap Failed"));
		eError = PVRSRV_ERROR_BAD_MAPPING;
		goto ErrorExitPhase3;
	}

	
	psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
	psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
	psMemBlock->hOSWrapMem = hOSWrapMem;
	psMemBlock->psIntSysPAddr = psIntSysPAddr;

	
	psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;

	
	psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
	psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
	psMemInfo->ui32AllocSize = ui32ByteSize;

	

	psMemInfo->pvSysBackupBuffer = IMG_NULL;

	


	psBMHeap = (BM_HEAP*)hDevMemHeap;
	hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext;
	eError = PVRSRVAllocSyncInfoKM(hDevCookie,
									hDevMemContext,
									&psMemInfo->psKernelSyncInfo);
	if(eError != PVRSRV_OK)
	{
		goto ErrorExitPhase4;
	}

	psMemInfo->psKernelSyncInfo->ui32RefCount++;

	
	psMemInfo->ui32RefCount++;

	psMemInfo->memType = PVRSRV_MEMTYPE_WRAPPED;

	
	psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
													RESMAN_TYPE_DEVICEMEM_WRAP,
													psMemInfo,
													0,
													&UnwrapExtMemoryCallBack);

	
	*ppsMemInfo = psMemInfo;

	return PVRSRV_OK;

	

ErrorExitPhase4:
	if(psMemInfo)
	{
		FreeDeviceMem(psMemInfo);
		


		psMemInfo = IMG_NULL;
	}

ErrorExitPhase3:
	if(psMemInfo)
	{
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
		
	}

ErrorExitPhase2:
	if(psIntSysPAddr)
	{
		OSReleasePhysPageAddr(hOSWrapMem);
	}

ErrorExitPhase1:
	if(psIntSysPAddr)
	{
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageCount * sizeof(IMG_SYS_PHYADDR), psIntSysPAddr, IMG_NULL);
		
	}
	
	return eError;
}
enum PVRSRV_ERROR PVRSRVWrapExtMemoryKM(void *hDevCookie,
			    struct PVRSRV_PER_PROCESS_DATA *psPerProc,
			    void *hDevMemContext, u32 ui32ByteSize,
			    u32 ui32PageOffset, IMG_BOOL bPhysContig,
			    struct IMG_SYS_PHYADDR *psExtSysPAddr,
			    void *pvLinAddr,
			    struct PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
{
	struct PVRSRV_KERNEL_MEM_INFO *psMemInfo = NULL;
	struct DEVICE_MEMORY_INFO *psDevMemoryInfo;
	u32 ui32HostPageSize = HOST_PAGESIZE();
	void *hDevMemHeap = NULL;
	struct PVRSRV_DEVICE_NODE *psDeviceNode;
	void *hBuffer;
	struct PVRSRV_MEMBLK *psMemBlock;
	IMG_BOOL bBMError;
	struct BM_HEAP *psBMHeap;
	enum PVRSRV_ERROR eError;
	void *pvPageAlignedCPUVAddr;
	struct IMG_SYS_PHYADDR *psIntSysPAddr = NULL;
	void *hOSWrapMem = NULL;
	struct DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
	int page_count = 0;
	u32 i;

	psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie;
	PVR_ASSERT(psDeviceNode != NULL);

	if (!psDeviceNode || (!pvLinAddr && !psExtSysPAddr)) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVWrapExtMemoryKM: invalid parameter");
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	if (pvLinAddr) {
		get_page_details((u32)pvLinAddr, ui32ByteSize,
				&ui32PageOffset, &page_count);
		pvPageAlignedCPUVAddr = (void *)((u8 *) pvLinAddr -
					ui32PageOffset);

		if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
			       page_count * sizeof(struct IMG_SYS_PHYADDR),
			       (void **)&psIntSysPAddr, NULL) != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: "
					"Failed to alloc memory for block");
			return PVRSRV_ERROR_OUT_OF_MEMORY;
		}

		eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr,
				       page_count * ui32HostPageSize,
				       psIntSysPAddr, &hOSWrapMem);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM:"
				   " Failed to alloc memory for block");
				eError = PVRSRV_ERROR_OUT_OF_MEMORY;
				goto ErrorExitPhase1;
		}
		psExtSysPAddr = psIntSysPAddr;
		bPhysContig = IMG_FALSE;
	}

	psDevMemoryInfo =
	    &((struct BM_CONTEXT *)hDevMemContext)->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 == NULL) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVWrapExtMemoryKM: unable to find mapping heap");
		eError = PVRSRV_ERROR_GENERIC;
		goto ErrorExitPhase2;
	}

	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
		       sizeof(struct PVRSRV_KERNEL_MEM_INFO),
		       (void **) &psMemInfo, NULL) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: "
					"Failed to alloc memory for block");
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto ErrorExitPhase2;
	}

	OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
	psMemBlock = &(psMemInfo->sMemBlk);

	bBMError = BM_Wrap(hDevMemHeap,
			   ui32ByteSize,
			   ui32PageOffset,
			   bPhysContig,
			   psExtSysPAddr,
			   NULL, &psMemInfo->ui32Flags, &hBuffer);
	if (!bBMError) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVWrapExtMemoryKM: BM_Wrap Failed");
		eError = PVRSRV_ERROR_BAD_MAPPING;
		goto ErrorExitPhase3;
	}

	psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
	psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
	psMemBlock->hOSWrapMem = hOSWrapMem;
	psMemBlock->psIntSysPAddr = psIntSysPAddr;

	psMemBlock->hBuffer = (void *) hBuffer;

	psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
	psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
	psMemInfo->ui32AllocSize = ui32ByteSize;

	psMemInfo->pvSysBackupBuffer = NULL;

	psBMHeap = (struct BM_HEAP *)hDevMemHeap;
	hDevMemContext = (void *) psBMHeap->pBMContext;
	eError = alloc_or_reuse_syncinfo(hDevCookie,
					 hDevMemContext,
					 &psMemInfo->psKernelSyncInfo,
					 psExtSysPAddr);
	if (eError != PVRSRV_OK)
		goto ErrorExitPhase4;

	psMemInfo->ui32RefCount++;

	psMemInfo->sMemBlk.hResItem =
	    ResManRegisterRes(psPerProc->hResManContext,
			      RESMAN_TYPE_DEVICEMEM_WRAP, psMemInfo, 0,
			      UnwrapExtMemoryCallBack);

	*ppsMemInfo = psMemInfo;

	return PVRSRV_OK;

ErrorExitPhase4:
	FreeDeviceMem(psMemInfo);
	psMemInfo = NULL;

ErrorExitPhase3:
	if (psMemInfo) {
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
			  sizeof(struct PVRSRV_KERNEL_MEM_INFO), psMemInfo,
			  NULL);
	}

ErrorExitPhase2:
	if (hOSWrapMem)
		OSReleasePhysPageAddr(hOSWrapMem);

ErrorExitPhase1:
	if (psIntSysPAddr) {
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
			  page_count * sizeof(struct IMG_SYS_PHYADDR),
			  psIntSysPAddr, NULL);
	}

	return eError;
}
enum PVRSRV_ERROR PVRSRVMapDeviceClassMemoryKM(
				struct PVRSRV_PER_PROCESS_DATA *psPerProc,
				void *hDevMemContext, void *hDeviceClassBuffer,
				struct PVRSRV_KERNEL_MEM_INFO **ppsMemInfo,
				void **phOSMapInfo)
{
	enum PVRSRV_ERROR eError;
	struct PVRSRV_KERNEL_MEM_INFO *psMemInfo;
	struct PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer;
	struct IMG_SYS_PHYADDR *psSysPAddr;
	void *pvCPUVAddr, *pvPageAlignedCPUVAddr;
	IMG_BOOL bPhysContig;
	struct BM_CONTEXT *psBMContext;
	struct DEVICE_MEMORY_INFO *psDevMemoryInfo;
	struct DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
	void *hDevMemHeap = NULL;
	u32 ui32ByteSize;
	u32 ui32Offset;
	u32 ui32PageSize = HOST_PAGESIZE();
	void *hBuffer;
	struct PVRSRV_MEMBLK *psMemBlock;
	IMG_BOOL bBMError;
	u32 i;

	if (!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo ||
	    !hDevMemContext) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVMapDeviceClassMemoryKM: invalid parameters");
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psDeviceClassBuffer = (struct PVRSRV_DEVICECLASS_BUFFER *)
							hDeviceClassBuffer;

	eError =
	    psDeviceClassBuffer->pfnGetBufferAddr(psDeviceClassBuffer->
						  hExtDevice,
						  psDeviceClassBuffer->
						  hExtBuffer, &psSysPAddr,
						  &ui32ByteSize,
						  (void __iomem **)&pvCPUVAddr,
						  phOSMapInfo, &bPhysContig);
	if (eError != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceClassMemoryKM: "
					"unable to get buffer address");
		return PVRSRV_ERROR_GENERIC;
	}

	psBMContext = (struct BM_CONTEXT *)psDeviceClassBuffer->hDevMemContext;
	psDevMemoryInfo = &psBMContext->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 == NULL) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceClassMemoryKM: "
					"unable to find mapping heap");
		return PVRSRV_ERROR_GENERIC;
	}

	ui32Offset = ((u32)pvCPUVAddr) & (ui32PageSize - 1);
	pvPageAlignedCPUVAddr = (void *)((u8 *)pvCPUVAddr - ui32Offset);

	if (OSAllocMem(PVRSRV_PAGEABLE_SELECT,
		       sizeof(struct PVRSRV_KERNEL_MEM_INFO),
		       (void **)&psMemInfo, NULL) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceClassMemoryKM: "
					"Failed to alloc memory for block");
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	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");
		OSFreeMem(PVRSRV_PAGEABLE_SELECT,
			  sizeof(struct PVRSRV_KERNEL_MEM_INFO), psMemInfo,
			  NULL);
		return PVRSRV_ERROR_BAD_MAPPING;
	}

	psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
	psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);

	psMemBlock->hBuffer = (void *) hBuffer;

	psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);

	psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
	psMemInfo->ui32AllocSize = ui32ByteSize;
	psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo;

	psMemInfo->pvSysBackupBuffer = NULL;

	psMemInfo->sMemBlk.hResItem =
	    ResManRegisterRes(psPerProc->hResManContext,
			      RESMAN_TYPE_DEVICECLASSMEM_MAPPING, psMemInfo, 0,
			      UnmapDeviceClassMemoryCallBack);

	*ppsMemInfo = psMemInfo;

	return PVRSRV_OK;
}
Exemplo n.º 5
0
/*!
******************************************************************************

 @Function SGXUT_readmem

 @Description	Read memory from ukernel

 @Input		*psSGXDevData : device data for SGX-type device
 @Input		asHeapInfo : heap allocation info
 @Input		ui32SharedHeapCount : heap count (includes per-context heaps)
 @Input		hDevMemContext : device memory context of this app

 @Return	void
******************************************************************************/
static IMG_VOID SGXUT_readmem(PVRSRV_DEV_DATA *psSGXDevData,
							  PVRSRV_HEAP_INFO	*asHeapInfo,
							  IMG_UINT32		ui32SharedHeapCount,
							  IMG_HANDLE		hDevMemContext)
{
	SGX_MISC_INFO			sSGXMiscInfo;
	PVRSRV_ERROR            eResult;

	PVRSRV_CLIENT_MEM_INFO  *psDeviceMemInfo;
	PVRSRV_CLIENT_MEM_INFO  *psDeviceDestMemInfo;
	IMG_DEV_VIRTADDR		sDevVAddr;
	IMG_PVOID				pvLinAddr;

	IMG_UINT32				ui32ByteOffset = 1;
	IMG_UINT32				ui32InitMemValue = 0x1234, ui32DeviceValue;
	IMG_HANDLE				hVertexShaderHeap, hKernelDataHeap;
	IMG_UINT				i;

	/* Find the kernel-video data heap */

	for(i=0; i < ui32SharedHeapCount; i++)
	{
		switch(HEAP_IDX(asHeapInfo[i].ui32HeapID))
		{
			case SGX_VERTEXSHADER_HEAP_ID:
			{
				hVertexShaderHeap		= asHeapInfo[i].hDevMemHeap;
				break;
			}
			case SGX_KERNEL_DATA_HEAP_ID:
			{
				hKernelDataHeap			= asHeapInfo[i].hDevMemHeap;
			}
			default:
			{
				break;
			}
		}
	}

	/*
	 * Allocate device-addressable memory and check its value from
	 * within the microkernel
	 */
	PVRSRVAllocDeviceMem(psSGXDevData,
			/* hKernelDataHeap, */
			hVertexShaderHeap,
			PVRSRV_MEM_READ | PVRSRV_MEM_WRITE,
			16, 4,
			&psDeviceMemInfo);

	/* Apply offset */
	sDevVAddr = psDeviceMemInfo->sDevVAddr;
	pvLinAddr = psDeviceMemInfo->pvLinAddr;
	sDevVAddr.uiAddr += ui32ByteOffset;
	pvLinAddr = (IMG_PVOID)((IMG_CHAR*)pvLinAddr + ui32ByteOffset);

	/* Initialise value in device-addressable memory
	 */
	DPF("Writing memory (CPU)    at 0x%x: value is %x\n",
			(IMG_UINTPTR_T)pvLinAddr,
			ui32InitMemValue);
	PVRSRVMemCopy(pvLinAddr, (IMG_PVOID)&ui32InitMemValue, sizeof(IMG_UINT32));

	/* Configure the address to read and its context in the microkernel */
	DPF("\nMisc Info API: Query the SGX device memory buffer\n");
	sSGXMiscInfo.eRequest = SGX_MISC_INFO_REQUEST_MEMREAD;
	sSGXMiscInfo.sDevVAddrSrc = sDevVAddr;
	sSGXMiscInfo.hDevMemContext = hDevMemContext;

	eResult = SGXGetMiscInfo(psSGXDevData, &sSGXMiscInfo);

	ui32DeviceValue = sSGXMiscInfo.uData.sSGXFeatures.ui32DeviceMemValue;
	DPF("Reading memory (device) at 0x%x: value is %x\n",
			sSGXMiscInfo.sDevVAddrSrc.uiAddr,
			ui32DeviceValue);
	if(ui32DeviceValue != ui32InitMemValue)
	{
		DPF("ERROR: Device and CPU values disagree.\n\n");
	}

	{
		/* Allocate dest buffer for GPU memcopy */
		PVRSRVAllocDeviceMem(psSGXDevData,
				hKernelDataHeap,
				/* hVertexShaderHeap, */
				PVRSRV_MEM_WRITE,
				16, 4,
				&psDeviceDestMemInfo);
	
		/* Configure the mem copy */
		DPF("\nMisc Info API: Perform a device-->device 4-byte memcopy\n");
		sSGXMiscInfo.eRequest = SGX_MISC_INFO_REQUEST_MEMCOPY;
		sSGXMiscInfo.sDevVAddrSrc = sDevVAddr;
		sSGXMiscInfo.sDevVAddrDest = psDeviceDestMemInfo->sDevVAddr;
		
		eResult = SGXGetMiscInfo(psSGXDevData, &sSGXMiscInfo);
	
		ui32DeviceValue = *(IMG_UINT32*)psDeviceDestMemInfo->pvLinAddr;
		DPF("Reading memory (device) at 0x%x: value is %x\n",
				sSGXMiscInfo.sDevVAddrDest.uiAddr,
				ui32DeviceValue);
		if(ui32DeviceValue != ui32InitMemValue)
		{
			DPF("ERROR: Device src and dest values disagree.\n\n");
		}
	}
	
	/* Free allocations */
	PVRSRVFreeDeviceMem(psSGXDevData, psDeviceMemInfo);
	PVRSRVFreeDeviceMem(psSGXDevData, psDeviceDestMemInfo);
}
Exemplo n.º 6
0
int alloc_ramdec_region(unsigned long *base_addr0, unsigned long *base_addr1,
				unsigned long size0, unsigned long size1)
{
	unsigned long pid = OSGetCurrentProcessIDKM();
    unsigned long num = 10;
	unsigned long heap_count = 0;
    void *sgx_cookie = NULL;
    unsigned long heapIndex = 0, generalHeapIndex = 0;
	PVRSRV_ERROR err;
	PVRSRV_KERNEL_MEM_INFO *rendec0MemInfo;
	PVRSRV_KERNEL_MEM_INFO *rendec1MemInfo;
	int i;

	printk(KERN_INFO "Calling PVRSRVPerProcessData()\n");
	if (PVRSRVPerProcessDataConnect(200) != PVRSRV_OK) {
		printk(KERN_ERR "msvdx_init: connect to PVR failed\n");
	}

	psPerProc = PVRSRVPerProcessData(200);
	if (psPerProc == IMG_NULL)
	{
		printk(KERN_ERR "msvdx_init:  Couldn't find per process data for pid=%lx\n", pid);
	}

	printk(KERN_INFO "  TEST: pp_data = 0x%p\n", psPerProc);


	PVRSRVEnumerateDevicesKM(&num, dev_id_list);
	printk(KERN_INFO "Calling PVRSRVEnumerateDevicesKM()\n");
	if (PVRSRVEnumerateDevicesKM(&num, dev_id_list) != PVRSRV_OK) {
		printk(KERN_ERR "msvdx_init: PVRSRVEnumerateDevice failed\n");
	} else {
		printk(KERN_INFO "  PVRSRVEnumerateDevicesKM() found %ld devices\n", num);
		for (i = 0 ; i < num ; i++) {
			PVRSRV_DEVICE_IDENTIFIER *id = dev_id_list + i;
			unsigned long cookie = 0;
			printk(KERN_INFO "    Device %d has type %d, class %d & index %ld\n", i,
					id->eDeviceType, id->eDeviceClass, id->ui32DeviceIndex);
			if (PVRSRV_DEVICE_TYPE_EXT != id->eDeviceType) {
				// Call PVRSRVAcquireDeviceDataKM():
				printk(KERN_INFO "Calling PVRSRVAcquireDeviceDataKM()\n");
				err = PVRSRVAcquireDeviceDataKM(id->ui32DeviceIndex,
						PVRSRV_DEVICE_TYPE_UNKNOWN, (void *) &cookie);
				if (err != PVRSRV_OK) {
					printk(KERN_ERR "[EMGD] PVRSRVAcquireDeviceDataKM() "
							"returned %d\n", err);
					break;
				}
				if (PVRSRV_DEVICE_TYPE_SGX == id->eDeviceType) {
					printk(KERN_INFO "  Found cookie = 0x%lx\n", cookie);
					// Save this away for later:
					sgx_cookie = (void *) cookie;
				}
			}
		}
	}

	// Enumerate the display class devices to be able to find the 3DD:
	printk(KERN_INFO "Calling PVRSRVEnumerateDCKM()\n");
	err = PVRSRVEnumerateDCKM(PVRSRV_DEVICE_CLASS_DISPLAY,
			&num, dev_ids);
	if (err != PVRSRV_OK) {
		printk(KERN_ERR "[EMGD] PVRSRVEnumerateDCKM() returned %d\n", err);
	} else {
		// Find the 3DD:
		printk(KERN_INFO "  PVRSRVEnumerateDCKM() found %ld devices\n", num);
		for (i = 0 ; i < num ; i++) {
			printk(KERN_INFO "    device %d has ID %ld\n", i, dev_ids[i]);
		}
		if (0 == dev_ids[0]) {
			printk(KERN_ERR "[EMGD] Did not find 3rd-party display driver ID\n");
		}
	}

	// Call PVRSRVCreateDeviceMemContextKM():

	printk(KERN_INFO "Calling PVRSRVCreateDeviceMemContextKM()\n");
	err = PVRSRVCreateDeviceMemContextKM(sgx_cookie, psPerProc,
			&dev_mem_context, &heap_count, heap_info, &mem_created, &dummy);
	if (err != PVRSRV_OK) {
		printk(KERN_ERR "[EMGD] PVRSRVCreateDeviceMemContextKM() "
				"returned %d\n", err);
	}


	for (heapIndex=0; heapIndex<heap_count; heapIndex++) {
		if (HEAP_IDX(heap_info[heapIndex].ui32HeapID) == SGX_GENERAL_HEAP_ID)
		{
			generalHeapIndex = heapIndex;
			break;
		}
	}

	if (PVRSRVAllocDeviceMemKM(sgx_cookie, psPerProc, heap_info[generalHeapIndex].hDevMemHeap,
                        PVRSRV_MEM_READ | PVRSRV_MEM_WRITE,
                        size0, 0, &rendec0MemInfo, "") != PVRSRV_OK) {
		printk(KERN_ERR "msvdx: PVRSRVAllocDeviceMemKM failed\n");
	}

	if (PVRSRVAllocDeviceMemKM(sgx_cookie, psPerProc, heap_info[generalHeapIndex].hDevMemHeap,
                        PVRSRV_MEM_READ | PVRSRV_MEM_WRITE,
                        size1, 0, &rendec1MemInfo, "") != PVRSRV_OK) {
		printk(KERN_ERR "msvdx: PVRSRVAllocDeviceMemKM failed\n");
	}

	*base_addr0 = rendec0MemInfo->sDevVAddr.uiAddr;
	*base_addr1 = rendec1MemInfo->sDevVAddr.uiAddr;

	//printk(KERN_INFO "pvr size0=%lx, size1=%lx, heap=%ld\n", size0, size1, generalHeapIndex);

//	return PVRSRV_OK;
	return 0;

}
Exemplo n.º 7
0
/*
 * Can't call from module initialization, since PVR services are started when
 * the Xorg server starts.
 */
int msvdx_pvr_init(void)
{
	drm_emgd_priv_t        *priv;
	igd_context_t           *context;
	platform_context_plb_t  *platform;
	struct msvdx_pvr_info   *pvr;
	PVRSRV_DEVICE_IDENTIFIER dev_id_list[PVRSRV_MAX_DEVICES];
	IMG_UINT32   pid;
	IMG_UINT32   num_devices;
	IMG_UINT32   i;
	IMG_BOOL     mem_created;
	PVRSRV_ERROR err;
	int ret;

	priv     = gpDrmDevice->dev_private;
	context  = priv->context;
	platform = (platform_context_plb_t *)context->platform_context;

	if (platform->msvdx_pvr) {
		printk(KERN_INFO "[EMGD] MSVDX: PVR services already "
			"initialized\n");
		return 0;
	}

    pvr = kzalloc(sizeof(*pvr), GFP_KERNEL);
	if (!pvr)
		return -ENOMEM;

    /*
	 * Create a dummy kernel thread so that a persistent PVR per process
	 * data could be created.
	 */
	pvr->kthread = kthread_run(msvdx_pvr_kthread, NULL, "msvdx-pvr");
	if (IS_ERR(pvr->kthread)) {
		ret = PTR_ERR(pvr->kthread);
		printk(KERN_ERR "[EMGD] MSVDX: failed to create MSVDX PVR "
			"kernel tread, error=%i\n", ret);
		pvr->kthread = NULL;
		goto out_free;
	}

	ret = -ENODEV;
	pid = OSGetCurrentProcessIDKM(); //(IMG_UINT32)pvr->kthread->pid;
    err = PVRSRVPerProcessDataConnect(pid);
	if (err != PVRSRV_OK) {
		printk(KERN_ERR "[EMGD] MSVDX: connect to PVR failed (pid=%u), "
			"error=%i\n", (unsigned int)err, err);
		goto out_stop_kthread;
	}
	pvr->per_proc = PVRSRVPerProcessData(pid);
	if (pvr->per_proc == IMG_NULL) {
		printk(KERN_ERR "[EMGD] MSVDX: Couldn't find per process "
			"data for pid=%u\n", (unsigned int)pid);
		goto out_stop_kthread;
	}

	err = PVRSRVEnumerateDevicesKM(&num_devices, dev_id_list);
	if (err != PVRSRV_OK) {
		printk(KERN_ERR "[EMGD] MSVDX: PVRSRVEnumerateDevice() failed, "
			"error=%u\n", (unsigned int)err);
		goto out_stop_kthread;
	}

	for (i = 0 ; i < num_devices ; i++) {
		PVRSRV_DEVICE_IDENTIFIER *id;
		IMG_HANDLE cookie;

		cookie = IMG_NULL;
		id = &dev_id_list[i];

		if (id->eDeviceType != PVRSRV_DEVICE_TYPE_EXT) {
			err = PVRSRVAcquireDeviceDataKM(id->ui32DeviceIndex,
				PVRSRV_DEVICE_TYPE_UNKNOWN, &cookie);
			if (err != PVRSRV_OK) {
				printk(KERN_ERR "[EMGD] MSVDX: "
					"PVRSRVAcquireDeviceDataKM() failed, "
					"error=%u\n", err);
				break;
			}
			if (PVRSRV_DEVICE_TYPE_SGX == id->eDeviceType) {
				pvr->sgx_cookie = cookie;
				break;
			}
		}
	}

	if (pvr->sgx_cookie == IMG_NULL)
		goto out_stop_kthread;

	err = PVRSRVCreateDeviceMemContextKM(pvr->sgx_cookie, pvr->per_proc,
			&pvr->dev_mem_context, &pvr->heap_count,
			pvr->heap_info, &mem_created, pvr->heap_shared);
	if (err != PVRSRV_OK) {
		printk(KERN_ERR "[EMGD] MSVDX: PVRSRVCreateDeviceMemContextKM()"
			" failed, error=%u\n", (unsigned int)err);
		goto out_stop_kthread;
	}

	for (i = 0; i < pvr->heap_count; i++) {
		if (HEAP_IDX(pvr->heap_info[i].ui32HeapID) ==
			SGX_VIDEO_HEAP_ID) {
			pvr->mapping_heap_index = i;
			break;
		}
	}

	platform->msvdx_pvr = pvr;
	pvr->pid = pid;


	return 0;

out_stop_kthread:
	kthread_stop(pvr->kthread);
out_free:
	kfree(pvr);
	return ret;
}