Пример #1
0
/*!
******************************************************************************

 @Function	PVRSRVTimeTraceBufferDestroy

 @Description

 Destroy a trace buffer.

 Note: We assume that this will only be called once per process.

 @Input ui32PID : PID of the process that is creating the buffer

 @Return none

******************************************************************************/
PVRSRV_ERROR PVRSRVTimeTraceBufferDestroy(IMG_UINT32 ui32PID)
{
#if !defined(TTRACE_KEEP_BUFFER_ON_EXIT)
	sTimeTraceBuffer *psBuffer;

#if defined(DUMP_TTRACE_BUFFERS_ON_EXIT)
	PVRSRVDumpTimeTraceBuffers();
#endif
    LinuxLockMutex(&g_sTTraceMutex);
	psBuffer = (sTimeTraceBuffer *) HASH_Retrieve(g_psBufferTable, (IMG_UINTPTR_T) ui32PID);
	if (psBuffer)
	{
		OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(sTimeTraceBuffer) + TIME_TRACE_BUFFER_SIZE,
				psBuffer, NULL);
		HASH_Remove(g_psBufferTable, (IMG_UINTPTR_T) ui32PID);
        LinuxUnLockMutex(&g_sTTraceMutex);
		return PVRSRV_OK;
	}

	PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceBufferDestroy: Can't find trace buffer in hash table"));
	LinuxUnLockMutex(&g_sTTraceMutex);
	return PVRSRV_ERROR_INVALID_PARAMS;
#else
	return PVRSRV_OK;
#endif
}
Пример #2
0
void PVRSRVPerProcessDataDisconnect(u32 ui32PID)
{
	enum PVRSRV_ERROR eError;
	struct PVRSRV_PER_PROCESS_DATA *psPerProc;

	PVR_ASSERT(psHashTab != NULL);

	psPerProc = (struct PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab,
							      (u32)ui32PID);
	if (psPerProc == NULL) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataDealloc: "
			 "Couldn't locate per-process data for PID %u",
			 ui32PID);
	} else {
		psPerProc->ui32RefCount--;
		if (psPerProc->ui32RefCount == 0) {
			PVR_DPF(PVR_DBG_MESSAGE,
				 "PVRSRVPerProcessDataDisconnect: "
				 "Last close from process 0x%x received",
				 ui32PID);

			PVRSRVResManDisconnect(psPerProc->hResManContext,
					       IMG_FALSE);

			eError = FreePerProcessData(psPerProc);
			if (eError != PVRSRV_OK)
				PVR_DPF(PVR_DBG_ERROR,
					 "PVRSRVPerProcessDataDisconnect: "
					 "Error freeing per-process data");
		}
	}
}
Пример #3
0
/*!
******************************************************************************

 @Function	PVRSRVPerProcessData

 @Description	Return per-process data area

 @Input		ui32PID - process ID

 @Return	Pointer to per-process data area, or IMG_NULL on error.

******************************************************************************/
PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID)
{
	PVRSRV_PER_PROCESS_DATA *psPerProc;

	PVR_ASSERT(psHashTab != IMG_NULL);

	/* Look for existing per-process data area */
	psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
	return psPerProc;
}
Пример #4
0
PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID)
{
	PVRSRV_PER_PROCESS_DATA *psPerProc;

	PVR_ASSERT(psHashTab != IMG_NULL);

	
	psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
	return psPerProc;
}
Пример #5
0
struct PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(u32 ui32PID)
{
	struct PVRSRV_PER_PROCESS_DATA *psPerProc;

	PVR_ASSERT(psHashTab != NULL);

	psPerProc =
	    (struct PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab,
						      (u32) ui32PID);
	return psPerProc;
}
Пример #6
0
/*!
******************************************************************************

 @Function	PVRSRVPerProcessDataDisconnect

 @Description	Decrement refcount for per-process data area,
 				and free the resources if necessary.

 @Input		ui32PID - process ID

 @Return	IMG_VOID

******************************************************************************/
IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32	ui32PID)
{
	PVRSRV_ERROR eError;
	PVRSRV_PER_PROCESS_DATA *psPerProc;

	PVR_ASSERT(psHashTab != IMG_NULL);

	psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
	if (psPerProc == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDealloc: Couldn't locate per-process data for PID %u", ui32PID));
	}
	else
	{
		psPerProc->ui32RefCount--;
		if (psPerProc->ui32RefCount == 0)
		{
			PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVPerProcessDataDisconnect: "
					"Last close from process 0x%x received", ui32PID));

			/* Close the Resource Manager connection */
			PVRSRVResManDisconnect(psPerProc->hResManContext, IMG_FALSE);

#if defined (TTRACE)
			PVRSRVTimeTraceBufferDestroy(ui32PID);
#endif

			/* Free the per-process data */
			eError = FreePerProcessData(psPerProc);
			if (eError != PVRSRV_OK)
			{
				PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Error freeing per-process data"));
			}
		}
	}

	eError = PVRSRVPurgeHandles(KERNEL_HANDLE_BASE);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Purge of global handle pool failed (%d)", eError));
	}
}
static inline
enum PVRSRV_ERROR alloc_or_reuse_syncinfo(void *dev_cookie,
		    void *mem_context_handle,
		    struct PVRSRV_KERNEL_SYNC_INFO **syncinfo,
		    struct IMG_SYS_PHYADDR *phys_addr)
{
	enum PVRSRV_ERROR error;
	struct PVRSRV_DEVICE_NODE *dev;

	dev = (struct PVRSRV_DEVICE_NODE *) dev_cookie;

	*syncinfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
					HASH_Retrieve(dev->sync_table,
						      phys_addr->uiAddr);

	if (!*syncinfo) {
		/* Dont' have one so create one */
		error = PVRSRVAllocSyncInfoKM(dev_cookie, mem_context_handle,
					       syncinfo);

		if (error != PVRSRV_OK)
			return error;

		/* Setup our extra data */
		(*syncinfo)->phys_addr.uiAddr = phys_addr->uiAddr;
		(*syncinfo)->dev_cookie = dev_cookie;
		(*syncinfo)->refcount = 1;

		if (!HASH_Insert(dev->sync_table, phys_addr->uiAddr,
			    (u32) *syncinfo)) {
			PVR_DPF(PVR_DBG_ERROR, "alloc_or_reuse_syncinfo: "
				"Failed to add syncobject to hash table");
			return PVRSRV_ERROR_GENERIC;
		}
	} else
		get_syncinfo(*syncinfo);

	return PVRSRV_OK;
}
Пример #8
0
/*!
******************************************************************************

 @Function	PVRSRVTimeTraceBufferDestroy

 @Description

 Destroy a trace buffer.

 Note: We assume that this will only be called once per process.

 @Input ui32PID : PID of the process that is creating the buffer

 @Return none

******************************************************************************/
PVRSRV_ERROR PVRSRVTimeTraceBufferDestroy(IMG_UINT32 ui32PID)
{
	sTimeTraceBuffer *psBuffer;

#if defined(DUMP_TTRACE_BUFFERS_ON_EXIT)
	PVRSRVDumpTimeTraceBuffers();
#endif
	psBuffer = (sTimeTraceBuffer *) HASH_Retrieve(g_psBufferTable, (IMG_UINTPTR_T) ui32PID);
	if (psBuffer)
	{
		if (psBuffer->pui8Data)
			OSFreeMem(PVRSRV_PAGEABLE_SELECT, TIME_TRACE_BUFFER_SIZE,
					psBuffer->pui8Data, NULL);
		OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(sTimeTraceBuffer),
				psBuffer, NULL);
		HASH_Remove(g_psBufferTable, (IMG_UINTPTR_T) ui32PID);
		return PVRSRV_OK;
	}

	PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceBufferDestroy: Can't find trace buffer in hash table"));
	return PVRSRV_ERROR_INVALID_PARAMS;
}
Пример #9
0
/*!
******************************************************************************

 @Function	PVRSRVPerProcessDataConnect

 @Description	Allocate per-process data area, or increment refcount if one
 				already exists for this PID.

 @Input		ui32PID - process ID
 			ppsPerProc - Pointer to per-process data area

 @Return	PVRSRV_ERROR

******************************************************************************/
PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32	ui32PID, IMG_UINT32 ui32Flags)
{
	PVRSRV_PER_PROCESS_DATA *psPerProc;
	IMG_HANDLE hBlockAlloc;
	PVRSRV_ERROR eError = PVRSRV_OK;

	if (psHashTab == IMG_NULL)
	{
		return PVRSRV_ERROR_INIT_FAILURE;
	}

	/* Look for existing per-process data area */
	psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);

	if (psPerProc == IMG_NULL)
	{
		/* Allocate per-process data area */
		eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
							sizeof(*psPerProc),
							(IMG_PVOID *)&psPerProc,
							&hBlockAlloc,
							"Per Process Data");
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError));
			return eError;
		}
		OSMemSet(psPerProc, 0, sizeof(*psPerProc));
		psPerProc->hBlockAlloc = hBlockAlloc;

		if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc))
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table"));
			eError = PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED;
			goto failure;
		}

		psPerProc->ui32PID = ui32PID;
		psPerProc->ui32RefCount = 0;

#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
		if (ui32Flags == SRV_FLAGS_PDUMP_ACTIVE)
		{
			psPerProc->bPDumpActive = IMG_TRUE;
		}
#else
		PVR_UNREFERENCED_PARAMETER(ui32Flags);
#endif

		/* Call environment specific per process init function */
		eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData);
		if (eError != PVRSRV_OK)
		{
			 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError));
			goto failure;
		}

		/* Allocate a handle for the per-process data area */
		eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
								   &psPerProc->hPerProcData,
								   psPerProc,
								   PVRSRV_HANDLE_TYPE_PERPROC_DATA,
								   PVRSRV_HANDLE_ALLOC_FLAG_NONE);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError));
			goto failure;
		}

		/* Allocate handle base for this process */
		eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError));
			goto failure;
		}

		/* Set per-process handle options */
		eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError));
			goto failure;
		}

		/* Create a resource manager context for the process */
		eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager"));
			goto failure;
		}
#if defined (TTRACE)
		PVRSRVTimeTraceBufferCreate(ui32PID);
#endif
	}

	psPerProc->ui32RefCount++;
	PVR_DPF((PVR_DBG_MESSAGE,
			"PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d",
			ui32PID, psPerProc->ui32RefCount));

	return eError;

failure:
	(IMG_VOID)FreePerProcessData(psPerProc);
	return eError;
}
Пример #10
0
enum PVRSRV_ERROR PVRSRVPerProcessDataConnect(u32 ui32PID)
{
	struct PVRSRV_PER_PROCESS_DATA *psPerProc;
	void *hBlockAlloc;
	enum PVRSRV_ERROR eError = PVRSRV_OK;

	PVR_ASSERT(psHashTab != NULL);

	psPerProc = (struct PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab,
						      (u32)ui32PID);
	if (psPerProc == NULL) {
		eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
				    sizeof(*psPerProc), (void **)&psPerProc,
				    &hBlockAlloc);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: "
				"Couldn't allocate per-process data (%d)",
				 eError);
			return eError;
		}
		OSMemSet(psPerProc, 0, sizeof(*psPerProc));
		psPerProc->hBlockAlloc = hBlockAlloc;

		if (!HASH_Insert(psHashTab, (u32) ui32PID, (u32)psPerProc)) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: "
			   "Couldn't insert per-process data into hash table");
			eError = PVRSRV_ERROR_GENERIC;
			goto failure;
		}

		psPerProc->ui32PID = ui32PID;
		psPerProc->ui32RefCount = 0;

		eError =
		    OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: "
				"OSPerProcessPrivateDataInit failed (%d)",
				 eError);
			goto failure;
		}

		eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
					   &psPerProc->hPerProcData,
					   psPerProc,
					   PVRSRV_HANDLE_TYPE_PERPROC_DATA,
					   PVRSRV_HANDLE_ALLOC_FLAG_NONE);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: "
			   "Couldn't allocate handle for per-process data (%d)",
			   eError);
			goto failure;
		}

		eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: "
			       "Couldn't allocate handle base for process (%d)",
			       eError);
			goto failure;
		}

		eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: "
					"Couldn't set handle options (%d)",
				 eError);
			goto failure;
		}

		eError =
		    PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: "
				"Couldn't register with the resource manager");
			goto failure;
		}
	}

	psPerProc->ui32RefCount++;
	PVR_DPF(PVR_DBG_MESSAGE,
		 "PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d",
		 ui32PID, psPerProc->ui32RefCount);

	return eError;

failure:
	(void)FreePerProcessData(psPerProc);
	return eError;
}
Пример #11
0
PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32	ui32PID, IMG_UINT32 ui32Flags)
{
	PVRSRV_PER_PROCESS_DATA *psPerProc;
	IMG_HANDLE hBlockAlloc;
	PVRSRV_ERROR eError = PVRSRV_OK;

	PVR_ASSERT(psHashTab != IMG_NULL);


	psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);

	if (psPerProc == IMG_NULL)
	{

		eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
							sizeof(*psPerProc),
							(IMG_PVOID *)&psPerProc,
							&hBlockAlloc,
							"Per Process Data");
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError));
			return eError;
		}
		OSMemSet(psPerProc, 0, sizeof(*psPerProc));
		psPerProc->hBlockAlloc = hBlockAlloc;

		/*
		 * FIXME: using a hash to retrieve psPerProc makes not much
		 * sense. We always want to have this struct on the IOCTL path
		 * for the current task, so it'd be just a matter of storing
		 * it in the file private object. Until this is resolved and
		 * we get rid of this pid specific lookup make sure the above
		 * assumption holds.
		 */
		WARN_ON(OSGetCurrentProcessIDKM() != ui32PID);
		get_task_comm(psPerProc->name, current);

		if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc))
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table"));
			eError = PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED;
			goto failure;
		}
		psPerProc->ui32PID = ui32PID;
		psPerProc->ui32RefCount = 0;

#if defined(PERPROC_LIST)
		List_PVRSRV_PER_PROCESS_DATA_Insert(&psPerProcList, psPerProc);
		/*PVR_LOG(("MarkTupsperproc %d\n", ui32PID));*/
#endif

#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
		if (ui32Flags == SRV_FLAGS_PDUMP_ACTIVE)
		{
			psPerProc->bPDumpActive = IMG_TRUE;
		}
#else
		PVR_UNREFERENCED_PARAMETER(ui32Flags);
#endif


		eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData);
		if (eError != PVRSRV_OK)
		{
			 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError));
			goto failure;
		}


		eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
								   &psPerProc->hPerProcData,
								   psPerProc,
								   PVRSRV_HANDLE_TYPE_PERPROC_DATA,
								   PVRSRV_HANDLE_ALLOC_FLAG_NONE);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError));
			goto failure;
		}


		eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError));
			goto failure;
		}


		eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError));
			goto failure;
		}


		eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager"));
			goto failure;
		}
	}

	psPerProc->ui32RefCount++;
	PVR_DPF((PVR_DBG_MESSAGE,
			"PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d",
			ui32PID, psPerProc->ui32RefCount));

	return eError;

failure:
	(IMG_VOID)FreePerProcessData(psPerProc);
	return eError;
}
Пример #12
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;
}
Пример #13
0
/*!
******************************************************************************

 @Function	PVRSRVTimeTraceAllocItem

 @Description

 Allocate a trace item from the buffer of the current process

 @Output ppsTraceItem :	Pointer to allocated trace item

 @Input ui32Size : Size of data packet to be allocated

 @Return none

******************************************************************************/
static IMG_VOID
PVRSRVTimeTraceAllocItem(IMG_UINT32 **pui32Item, IMG_UINT32 ui32Size)
{
	IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
	IMG_UINT32 ui32AllocOffset;
	sTimeTraceBuffer *psBuffer = (sTimeTraceBuffer *) HASH_Retrieve(g_psBufferTable, (IMG_UINTPTR_T) ui32PID);

	/* The caller only asks for extra data space */
	ui32Size += PVRSRV_TRACE_ITEM_SIZE;

	/* Always round to 32-bit */
	ui32Size = ((ui32Size - 1) & (~0x3)) + 0x04;

	if (!psBuffer)
	{
		PVRSRV_ERROR eError;

		PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVTimeTraceAllocItem: Creating buffer for PID %u", (IMG_UINT32) ui32PID));
		eError = PVRSRVTimeTraceBufferCreate(ui32PID);
		if (eError != PVRSRV_OK)
		{
			*pui32Item = IMG_NULL;
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceAllocItem: Failed to create buffer"));
			return;
		}
		
		psBuffer = (sTimeTraceBuffer *) HASH_Retrieve(g_psBufferTable, (IMG_UINTPTR_T) ui32PID);
		if (psBuffer == IMG_NULL)
		{
			*pui32Item = NULL;
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceAllocItem: Failed to retrieve buffer"));
			return;
		}
	}

	/* Can't allocate more then buffer size */
	if (ui32Size >= TIME_TRACE_BUFFER_SIZE)
	{
		*pui32Item = NULL;
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceAllocItem: Error trace item too large (%d)", ui32Size));
		return;
	}

	/* FIXME: Enter critical section? */

	/* Always ensure we have enough space to write a padding message */
	if ((psBuffer->ui32Woff + ui32Size + PVRSRV_TRACE_ITEM_SIZE) > TIME_TRACE_BUFFER_SIZE)
	{
		IMG_UINT32 *ui32WriteEOB = (IMG_UINT32 *) &psBuffer->pui8Data[psBuffer->ui32Woff];
		IMG_UINT32 ui32Remain = TIME_TRACE_BUFFER_SIZE - psBuffer->ui32Woff;

		/* Not enough space at the end of the buffer, back to the start */
		*ui32WriteEOB++ = WRITE_HEADER(GROUP, PVRSRV_TRACE_GROUP_PADDING);
		*ui32WriteEOB++ = 0;		/* Don't need timestamp */
		*ui32WriteEOB++ = 0;		/* Don't need UID */
		*ui32WriteEOB = WRITE_HEADER(SIZE, (ui32Remain - PVRSRV_TRACE_ITEM_SIZE));
		psBuffer->ui32ByteCount += ui32Remain;
		psBuffer->ui32Woff = ui32AllocOffset = 0;
	}
	else
		ui32AllocOffset = psBuffer->ui32Woff;

	psBuffer->ui32Woff = psBuffer->ui32Woff + ui32Size;
	psBuffer->ui32ByteCount += ui32Size;

	/* This allocation will start overwritting past our read pointer, move the read pointer along */
	while (psBuffer->ui32ByteCount > TIME_TRACE_BUFFER_SIZE)
	{
		IMG_UINT32 *psReadItem = (IMG_UINT32 *) &psBuffer->pui8Data[psBuffer->ui32Roff];
		IMG_UINT32 ui32ReadSize;

		ui32ReadSize = PVRSRVTimeTraceItemSize(psReadItem);
		psBuffer->ui32Roff = (psBuffer->ui32Roff + ui32ReadSize) & (TIME_TRACE_BUFFER_SIZE - 1);
		psBuffer->ui32ByteCount -= ui32ReadSize;
	}

	*pui32Item = (IMG_UINT32 *) &psBuffer->pui8Data[ui32AllocOffset];
	/* FIXME: Exit critical section? */
}
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;
}