Exemple #1
0
IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
        IMG_HANDLE hOSMemHandle,
		IMG_UINT32 ui32Offset,
		IMG_UINT8 *pui8LinAddr,
		IMG_UINT32 ui32PageSize,
		IMG_DEV_PHYADDR *psDevPAddr)
{
	if(hOSMemHandle)
	{
		
		IMG_CPU_PHYADDR	sCpuPAddr;

		PVR_UNREFERENCED_PARAMETER(pui8LinAddr);

		sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
		PVR_ASSERT((sCpuPAddr.uiAddr & (ui32PageSize - 1)) == 0);

		
		*psDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
	}
	else
	{
		IMG_CPU_PHYADDR	sCpuPAddr;

		PVR_UNREFERENCED_PARAMETER(ui32Offset);

		sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr);
		*psDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
	}
}
void PDumpMallocPages(u32 ui32DevVAddr, void *hOSMemHandle,
		      u32 ui32NumBytes, void *hUniqueTag)
{
	struct IMG_CPU_PHYADDR sCpuPAddr;
	struct IMG_DEV_PHYADDR sDevPAddr;
	u32 ui32Offset;

	PVR_ASSERT(((u32) ui32DevVAddr & ~PAGE_MASK) == 0);
	PVR_ASSERT(hOSMemHandle);
	PVR_ASSERT(((u32) ui32NumBytes & ~PAGE_MASK) == 0);

	PDumpComment("MALLOC :SGXMEM:VA_%8.8X 0x%8.8X %u\r\n",
		     ui32DevVAddr, ui32NumBytes, PAGE_SIZE);

	for (ui32Offset = 0; ui32Offset < ui32NumBytes;
	     ui32Offset += PAGE_SIZE) {
		sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
		sDevPAddr = SysCpuPAddrToDevPAddr(0, sCpuPAddr);

		pdump_print(PDUMP_FLAGS_CONTINUOUS,
			    "MALLOC :SGXMEM:PA_%8.8X%8.8X %u %u 0x%8.8X\r\n",
			    (u32)hUniqueTag, sDevPAddr.uiAddr, PAGE_SIZE,
			    PAGE_SIZE, sDevPAddr.uiAddr);
	}
}
Exemple #3
0
void PDumpFreePageTable(enum PVRSRV_DEVICE_TYPE eDeviceType, void *pvLinAddr,
			u32 ui32NumBytes, void *hUniqueTag)
{
	u8 *pui8LinAddr;
	u32 ui32NumPages;
	struct IMG_CPU_PHYADDR sCpuPAddr;
	struct IMG_DEV_PHYADDR sDevPAddr;
	u32 ui32Page;
	__PDBG_PDUMP_STATE_GET_SCRIPT_STRING();

	PVR_ASSERT(((u32) pvLinAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0);
	PVR_ASSERT(((u32) ui32NumBytes & (SGX_MMU_PAGE_SIZE - 1)) == 0);

	snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
		 "-- FREE :SGXMEM:PAGE_TABLE\r\n");
	PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);

	pui8LinAddr = (u8 *) pvLinAddr;
	ui32NumPages = ui32NumBytes >> SGX_MMU_PAGE_SHIFT;
	while (ui32NumPages--) {
		sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr);
		sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
		ui32Page = sDevPAddr.uiAddr >> SGX_MMU_PAGE_SHIFT;
		pui8LinAddr += SGX_MMU_PAGE_SIZE;

		snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
			 "FREE :SGXMEM:PA_%p%8.8lX\r\n", hUniqueTag,
			 ui32Page * SGX_MMU_PAGE_SIZE);
		PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);
	}
}
void PDumpFreePageTable(void *pvLinAddr)
{
	struct IMG_CPU_PHYADDR sCpuPAddr;
	struct IMG_DEV_PHYADDR sDevPAddr;

	PVR_ASSERT(((u32) pvLinAddr & ~PAGE_MASK) == 0);

	PDumpComment("FREE :SGXMEM:PAGE_TABLE\r\n");

	sCpuPAddr = OSMapLinToCPUPhys(pvLinAddr);
	sDevPAddr = SysCpuPAddrToDevPAddr(0, sCpuPAddr);

	pdump_print(PDUMP_FLAGS_CONTINUOUS, "FREE :SGXMEM:PA_%8.8X%8.8lX\r\n",
		    PDUMP_PT_UNIQUETAG, sDevPAddr.uiAddr);
}
void PDumpMallocPageTable(void *pvLinAddr, void *hUniqueTag)
{
	struct IMG_CPU_PHYADDR sCpuPAddr;
	struct IMG_DEV_PHYADDR sDevPAddr;

	PVR_ASSERT(((u32) pvLinAddr & ~PAGE_MASK) == 0);

	PDumpComment("MALLOC :SGXMEM:PAGE_TABLE 0x%8.8X %lu\r\n",
		     PAGE_SIZE, PAGE_SIZE);

	sCpuPAddr = OSMapLinToCPUPhys(pvLinAddr);
	sDevPAddr = SysCpuPAddrToDevPAddr(0, sCpuPAddr);

	pdump_print(PDUMP_FLAGS_CONTINUOUS, "MALLOC :SGXMEM:PA_%8.8X%8.8lX "
		    "0x%lX %lu 0x%8.8lX\r\n", (u32)hUniqueTag,
		    sDevPAddr.uiAddr, PAGE_SIZE,
		    PAGE_SIZE, sDevPAddr.uiAddr);
}
Exemple #6
0
void PDumpMallocPages(enum PVRSRV_DEVICE_TYPE eDeviceType, u32 ui32DevVAddr,
		      void *pvLinAddr, void *hOSMemHandle, u32 ui32NumBytes,
		      void *hUniqueTag)
{
	u32 ui32Offset;
	u32 ui32NumPages;
	struct IMG_CPU_PHYADDR sCpuPAddr;
	struct IMG_DEV_PHYADDR sDevPAddr;
	u32 ui32Page;
	__PDBG_PDUMP_STATE_GET_SCRIPT_STRING();
	PVR_UNREFERENCED_PARAMETER(pvLinAddr);

	PVR_ASSERT(((u32) ui32DevVAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0);
	PVR_ASSERT(hOSMemHandle);
	PVR_ASSERT(((u32) ui32NumBytes & (SGX_MMU_PAGE_SIZE - 1)) == 0);

	snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
		 "-- MALLOC :SGXMEM:VA_%8.8lX 0x%8.8lX %lu\r\n", ui32DevVAddr,
		 ui32NumBytes, SGX_MMU_PAGE_SIZE);
	PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);

	ui32Offset = 0;
	ui32NumPages = ui32NumBytes >> SGX_MMU_PAGE_SHIFT;
	while (ui32NumPages--) {
		sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
		PVR_ASSERT((sCpuPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1)) == 0);
		ui32Offset += SGX_MMU_PAGE_SIZE;
		sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
		ui32Page = sDevPAddr.uiAddr >> SGX_MMU_PAGE_SHIFT;

		snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
			 "MALLOC :SGXMEM:PA_%p%8.8lX %lu %lu 0x%8.8lX\r\n",
			 hUniqueTag, ui32Page * SGX_MMU_PAGE_SIZE,
			 SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE,
			 ui32Page * SGX_MMU_PAGE_SIZE);
		PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);
	}
}
/*!
 * \name	PDumpOSCPUVAddrToDevPAddr
 */
IMG_VOID PDumpOSCPUVAddrToDevPAddr(PVRSRV_DEVICE_TYPE eDeviceType,
        IMG_HANDLE hOSMemHandle,
		IMG_UINT32 ui32Offset,
		IMG_UINT8 *pui8LinAddr,
		IMG_UINT32 ui32PageSize,
		IMG_DEV_PHYADDR *psDevPAddr)
{
	IMG_CPU_PHYADDR	sCpuPAddr;

	PVR_UNREFERENCED_PARAMETER(pui8LinAddr);
	PVR_UNREFERENCED_PARAMETER(ui32PageSize);   /* for when no assert */

	/* Caller must now alway supply hOSMemHandle, even though we only (presently)
	   use it here in the linux implementation */
	   
	PVR_ASSERT (hOSMemHandle != IMG_NULL);
	
	sCpuPAddr = OSMemHandleToCpuPAddr(hOSMemHandle, ui32Offset);
	PVR_ASSERT((sCpuPAddr.uiAddr & (ui32PageSize - 1)) == 0);

	/* convert CPU physical addr to device physical */
	*psDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);
}
Exemple #8
0
PVRSRV_ERROR PDumpSetMMUContext(PVRSRV_DEVICE_TYPE eDeviceType,
				char *pszMemSpace,
				u32 * pui32MMUContextID,
				u32 ui32MMUType,
				void *hUniqueTag1, void *pvPDCPUAddr)
{
	u8 *pui8LinAddr = (u8 *) pvPDCPUAddr;
	IMG_CPU_PHYADDR sCpuPAddr;
	IMG_DEV_PHYADDR sDevPAddr;
	u32 ui32MMUContextID;
	PVRSRV_ERROR eError;

	eError = _PdumpAllocMMUContext(&ui32MMUContextID);
	if (eError != PVRSRV_OK) {
		PVR_DPF((PVR_DBG_ERROR,
			 "PDumpSetMMUContext: _PdumpAllocMMUContext failed: %d",
			 eError));
		return eError;
	}

	sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr);
	sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);

	sDevPAddr.uiAddr &= ~((PVRSRV_4K_PAGE_SIZE) - 1);

	PDumpComment("Set MMU Context\r\n");

	PDumpComment("MMU :%s:v%d %d :%s:PA_%8.8lX%8.8lX\r\n",
		     pszMemSpace,
		     ui32MMUContextID,
		     ui32MMUType, pszMemSpace, hUniqueTag1, sDevPAddr.uiAddr);

	*pui32MMUContextID = ui32MMUContextID;

	return PVRSRV_OK;
}
Exemple #9
0
PVRSRV_ERROR PDumpMem2KM(PVRSRV_DEVICE_TYPE eDeviceType,
			 IMG_CPU_VIRTADDR pvLinAddr,
			 u32 ui32Bytes,
			 u32 ui32Flags,
			 int bInitialisePages,
			 void *hUniqueTag1, void *hUniqueTag2)
{
	PVRSRV_ERROR eErr;
	u32 ui32NumPages;
	u32 ui32PageOffset;
	u32 ui32BlockBytes;
	u8 *pui8LinAddr;
	IMG_DEV_PHYADDR sDevPAddr;
	IMG_CPU_PHYADDR sCpuPAddr;
	u32 ui32Offset;
	u32 ui32ParamOutPos;

	PDUMP_GET_SCRIPT_AND_FILE_STRING();

	if (!pvLinAddr || !PDumpOSJTInitialised()) {
		return PVRSRV_ERROR_GENERIC;
	}

	if (PDumpOSIsSuspended()) {
		return PVRSRV_OK;
	}

	PDumpOSCheckForSplitting(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
				 ui32Bytes, ui32Flags);

	ui32ParamOutPos = PDumpOSGetStreamOffset(PDUMP_STREAM_PARAM2);

	if (bInitialisePages) {

		if (!PDumpOSWriteString(PDumpOSGetStream(PDUMP_STREAM_PARAM2),
					pvLinAddr,
					ui32Bytes, PDUMP_FLAGS_CONTINUOUS)) {
			return PVRSRV_ERROR_GENERIC;
		}

		if (PDumpOSGetParamFileNum() == 0) {
			eErr =
			    PDumpOSSprintf(pszFileName, ui32MaxLenFileName,
					   "%%0%%.prm");
		} else {
			eErr =
			    PDumpOSSprintf(pszFileName, ui32MaxLenFileName,
					   "%%0%%%lu.prm",
					   PDumpOSGetParamFileNum());
		}
		if (eErr != PVRSRV_OK) {
			return eErr;
		}
	}

	ui32PageOffset = (u32) pvLinAddr & (HOST_PAGESIZE() - 1);
	ui32NumPages =
	    (ui32PageOffset + ui32Bytes + HOST_PAGESIZE() -
	     1) / HOST_PAGESIZE();
	pui8LinAddr = (u8 *) pvLinAddr;

	while (ui32NumPages) {
		ui32NumPages--;
		sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr);
		sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);

		if (ui32PageOffset + ui32Bytes > HOST_PAGESIZE()) {

			ui32BlockBytes = HOST_PAGESIZE() - ui32PageOffset;
		} else {

			ui32BlockBytes = ui32Bytes;
		}

		if (bInitialisePages) {
			eErr = PDumpOSBufprintf(hScript,
						ui32MaxLenScript,
						"LDB :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX 0x%8.8lX %s\r\n",
						(u32) hUniqueTag1,
						sDevPAddr.
						uiAddr & ~(SGX_MMU_PAGE_MASK),
						sDevPAddr.
						uiAddr & (SGX_MMU_PAGE_MASK),
						ui32BlockBytes, ui32ParamOutPos,
						pszFileName);
			if (eErr != PVRSRV_OK) {
				return eErr;
			}
			PDumpOSWriteString2(hScript, PDUMP_FLAGS_CONTINUOUS);
		} else {
			for (ui32Offset = 0; ui32Offset < ui32BlockBytes;
			     ui32Offset += sizeof(u32)) {
				u32 ui32PTE =
				    *((u32 *) (pui8LinAddr + ui32Offset));

				if ((ui32PTE & SGX_MMU_PDE_ADDR_MASK) != 0) {
#if defined(SGX_FEATURE_36BIT_MMU)
					eErr = PDumpOSBufprintf(hScript,
								ui32MaxLenScript,
								"WRW :SGXMEM:$1 :SGXMEM:PA_%8.8lX%8.8lX:0x0\r\n",
								(u32)
								hUniqueTag2,
								(ui32PTE &
								 SGX_MMU_PDE_ADDR_MASK)
								<<
								SGX_MMU_PTE_ADDR_ALIGNSHIFT);
					if (eErr != PVRSRV_OK) {
						return eErr;
					}
					PDumpOSWriteString2(hScript,
							    PDUMP_FLAGS_CONTINUOUS);
					eErr =
					    PDumpOSBufprintf(hScript,
							     ui32MaxLenScript,
							     "SHR :SGXMEM:$1 :SGXMEM:$1 0x4\r\n");
					if (eErr != PVRSRV_OK) {
						return eErr;
					}
					PDumpOSWriteString2(hScript,
							    PDUMP_FLAGS_CONTINUOUS);
					eErr =
					    PDumpOSBufprintf(hScript,
							     ui32MaxLenScript,
							     "OR :SGXMEM:$1 :SGXMEM:$1 0x%8.8lX\r\n",
							     ui32PTE &
							     ~SGX_MMU_PDE_ADDR_MASK);
					if (eErr != PVRSRV_OK) {
						return eErr;
					}
					PDumpOSWriteString2(hScript,
							    PDUMP_FLAGS_CONTINUOUS);
					eErr =
					    PDumpOSBufprintf(hScript,
							     ui32MaxLenScript,
							     "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX :SGXMEM:$1\r\n",
							     (u32) hUniqueTag1,
							     (sDevPAddr.uiAddr +
							      ui32Offset) &
							     ~
							     (SGX_MMU_PAGE_MASK),
							     (sDevPAddr.uiAddr +
							      ui32Offset) &
							     (SGX_MMU_PAGE_MASK));
					if (eErr != PVRSRV_OK) {
						return eErr;
					}
					PDumpOSWriteString2(hScript,
							    PDUMP_FLAGS_CONTINUOUS);
#else
					eErr = PDumpOSBufprintf(hScript,
								ui32MaxLenScript,
								"WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX\r\n",
								(u32)
								hUniqueTag1,
								(sDevPAddr.
								 uiAddr +
								 ui32Offset) &
								~
								(SGX_MMU_PAGE_MASK),
								(sDevPAddr.
								 uiAddr +
								 ui32Offset) &
								(SGX_MMU_PAGE_MASK),
								(u32)
								hUniqueTag2,
								(ui32PTE &
								 SGX_MMU_PDE_ADDR_MASK)
								<<
								SGX_MMU_PTE_ADDR_ALIGNSHIFT,
								ui32PTE &
								~SGX_MMU_PDE_ADDR_MASK);
					if (eErr != PVRSRV_OK) {
						return eErr;
					}
#endif
				} else {
					PVR_ASSERT((ui32PTE & SGX_MMU_PTE_VALID)
						   == 0UL);
					eErr =
					    PDumpOSBufprintf(hScript,
							     ui32MaxLenScript,
							     "WRW :SGXMEM:PA_%8.8lX%8.8lX:0x%8.8lX 0x%8.8lX%8.8lX\r\n",
							     (u32) hUniqueTag1,
							     (sDevPAddr.uiAddr +
							      ui32Offset) &
							     ~
							     (SGX_MMU_PAGE_MASK),
							     (sDevPAddr.uiAddr +
							      ui32Offset) &
							     (SGX_MMU_PAGE_MASK),
							     (ui32PTE <<
							      SGX_MMU_PTE_ADDR_ALIGNSHIFT),
							     (u32) hUniqueTag2);
					if (eErr != PVRSRV_OK) {
						return eErr;
					}
				}
				PDumpOSWriteString2(hScript,
						    PDUMP_FLAGS_CONTINUOUS);
			}
		}

		ui32PageOffset = 0;

		ui32Bytes -= ui32BlockBytes;

		pui8LinAddr += ui32BlockBytes;

		ui32ParamOutPos += ui32BlockBytes;
	}

	return PVRSRV_OK;
}
enum PVRSRV_ERROR
PDumpPageTableKM(void *pvLinAddr, u32 ui32Bytes, IMG_BOOL bInitialisePages,
		 void *hUniqueTag1, void *hUniqueTag2)
{
	struct IMG_DEV_PHYADDR sDevPAddr;
	struct IMG_CPU_PHYADDR sCpuPAddr;
	enum PVRSRV_ERROR eError;

	if (!pvLinAddr)
		return PVRSRV_ERROR_GENERIC;

	if (bInitialisePages) {
		eError = pdump_dump(PDUMP_FLAGS_CONTINUOUS, pvLinAddr,
				    ui32Bytes, false);
		if (eError != PVRSRV_OK)
			return eError;
	}

	while (ui32Bytes) {
		u32 ui32BlockBytes =
			min(ui32Bytes,
			    (u32)(PAGE_SIZE - ((u32)pvLinAddr & ~PAGE_MASK)));

		sCpuPAddr = OSMapLinToCPUPhys(pvLinAddr);
		sDevPAddr = SysCpuPAddrToDevPAddr(0, sCpuPAddr);

		if (bInitialisePages) {
			pdump_print(PDUMP_FLAGS_CONTINUOUS, "LDB :SGXMEM:"
				    "PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X\r\n",
				    (u32) hUniqueTag1,
				    sDevPAddr.uiAddr & PAGE_MASK,
				    sDevPAddr.uiAddr & ~PAGE_MASK,
				    ui32BlockBytes);
		} else {
			u32 ui32Offset;

			for (ui32Offset = 0; ui32Offset < ui32BlockBytes;
			     ui32Offset += sizeof(u32)) {
				u32 ui32PTE =
					*((u32 *)(pvLinAddr + ui32Offset));

				if ((ui32PTE & ~PAGE_MASK) != 0) {
					pdump_print(PDUMP_FLAGS_CONTINUOUS,
"WRW :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX\r\n",
						 (u32)hUniqueTag1,
						 sDevPAddr.uiAddr & PAGE_MASK,
						 sDevPAddr.uiAddr & ~PAGE_MASK,
						 (u32)hUniqueTag2,
						 ui32PTE & PAGE_MASK,
						 ui32PTE & ~PAGE_MASK);
				} else {
					PVR_ASSERT(!
						   (ui32PTE &
						    SGX_MMU_PTE_VALID));
					pdump_print(PDUMP_FLAGS_CONTINUOUS,
		"WRW :SGXMEM:PA_%8.8X%8.8lX:0x%8.8lX 0x%8.8X%8.8X\r\n",
						 (u32) hUniqueTag1,
						 sDevPAddr.uiAddr & PAGE_MASK,
						 sDevPAddr.uiAddr & ~PAGE_MASK,
						 ui32PTE, (u32)hUniqueTag2);
				}

				sDevPAddr.uiAddr += sizeof(u32);
			}
		}

		ui32Bytes -= ui32BlockBytes;
		pvLinAddr += ui32BlockBytes;
	}

	return PVRSRV_OK;
}
Exemple #11
0
enum PVRSRV_ERROR PDumpMem2KM(enum PVRSRV_DEVICE_TYPE eDeviceType,
			 void *pvLinAddr, u32 ui32Bytes, u32 ui32Flags,
			 IMG_BOOL bInitialisePages, void *hUniqueTag1,
			 void *hUniqueTag2)
{
	u32 ui32NumPages;
	u32 ui32PageOffset;
	u32 ui32BlockBytes;
	u8 *pui8LinAddr;
	struct IMG_DEV_PHYADDR sDevPAddr;
	struct IMG_CPU_PHYADDR sCpuPAddr;
	u32 ui32Offset;
	u32 ui32ParamOutPos;

	__PDBG_PDUMP_STATE_GET_SCRIPT_AND_FILE_STRING(PVRSRV_ERROR_GENERIC);

	if (ui32Flags)
		;

	if (!pvLinAddr)
		return PVRSRV_ERROR_GENERIC;

	if (gui32PDumpSuspended)
		return PVRSRV_OK;

	ui32ParamOutPos =
	    gpfnDbgDrv->pfnGetStreamOffset(gsDBGPdumpState.
					   psStream[PDUMP_STREAM_PARAM2]);

	if (bInitialisePages) {

		if (!PDumpWriteILock
		    (gsDBGPdumpState.psStream[PDUMP_STREAM_PARAM2], pvLinAddr,
		     ui32Bytes, PDUMP_FLAGS_CONTINUOUS))
			return PVRSRV_ERROR_GENERIC;

		if (gsDBGPdumpState.ui32ParamFileNum == 0)
			snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%.prm");
		else
			snprintf(pszFile, SZ_FILENAME_SIZE_MAX, "%%0%%%lu.prm",
				 gsDBGPdumpState.ui32ParamFileNum);
	}

	ui32PageOffset = (u32) pvLinAddr & (HOST_PAGESIZE() - 1);
	ui32NumPages =
	    (ui32PageOffset + ui32Bytes + HOST_PAGESIZE() -
	     1) / HOST_PAGESIZE();
	pui8LinAddr = (u8 *) pvLinAddr;

	while (ui32NumPages--) {
		sCpuPAddr = OSMapLinToCPUPhys(pui8LinAddr);
		sDevPAddr = SysCpuPAddrToDevPAddr(eDeviceType, sCpuPAddr);

		if (ui32PageOffset + ui32Bytes > HOST_PAGESIZE())

			ui32BlockBytes = HOST_PAGESIZE() - ui32PageOffset;
		else

			ui32BlockBytes = ui32Bytes;

		if (bInitialisePages) {
			snprintf(pszScript,
				 SZ_SCRIPT_SIZE_MAX,
				 "LDB :SGXMEM:PA_%p%8.8lX:0x%8.8lX 0x%8.8lX "
				 "0x%8.8lX %s\r\n",
				 hUniqueTag1,
				 sDevPAddr.uiAddr & ~(SGX_MMU_PAGE_SIZE - 1),
				 sDevPAddr.uiAddr & (SGX_MMU_PAGE_SIZE - 1),
				 ui32BlockBytes, ui32ParamOutPos, pszFile);
			PDumpWriteString2(pszScript, PDUMP_FLAGS_CONTINUOUS);
		} else {
			for (ui32Offset = 0; ui32Offset < ui32BlockBytes;
			     ui32Offset += sizeof(u32)) {
				u32 ui32PTE =
				    *((u32 *) (pui8LinAddr +
						      ui32Offset));

				if ((ui32PTE & SGX_MMU_PDE_ADDR_MASK) != 0) {
					snprintf(pszScript,
						 SZ_SCRIPT_SIZE_MAX,
						 "WRW :SGXMEM:PA_%p%8.8lX:"
						 "0x%8.8lX :SGXMEM:"
						 "PA_%p%8.8lX:0x%8.8lX\r\n",
						 hUniqueTag1,
						 (sDevPAddr.uiAddr +
						  ui32Offset) &
						 ~(SGX_MMU_PAGE_SIZE - 1),
						 (sDevPAddr.uiAddr +
						  ui32Offset) &
						 (SGX_MMU_PAGE_SIZE - 1),
						 hUniqueTag2,
						 ui32PTE &
						 SGX_MMU_PDE_ADDR_MASK,
						 ui32PTE &
						 ~SGX_MMU_PDE_ADDR_MASK);
				} else {
					PVR_ASSERT(!
						   (ui32PTE &
						    SGX_MMU_PTE_VALID));
					snprintf(pszScript, SZ_SCRIPT_SIZE_MAX,
						 "WRW :SGXMEM:PA_%p%8.8lX:"
						 "0x%8.8lX 0x%8.8lX%p\r\n",
						 hUniqueTag1,
						 (sDevPAddr.uiAddr +
						  ui32Offset) &
						 ~(SGX_MMU_PAGE_SIZE - 1),
						 (sDevPAddr.uiAddr +
						  ui32Offset) &
						 (SGX_MMU_PAGE_SIZE - 1),
						 ui32PTE, hUniqueTag2);
				}
				PDumpWriteString2(pszScript,
						  PDUMP_FLAGS_CONTINUOUS);
			}
		}

		ui32PageOffset = 0;
		ui32Bytes -= ui32BlockBytes;
		pui8LinAddr += ui32BlockBytes;
		ui32ParamOutPos += ui32BlockBytes;
	}

	return PVRSRV_OK;
}
enum PVRSRV_ERROR MMU_Initialise(struct PVRSRV_DEVICE_NODE *psDeviceNode,
			    struct MMU_CONTEXT **ppsMMUContext,
			    struct IMG_DEV_PHYADDR *psPDDevPAddr)
{
	u32 *pui32Tmp;
	u32 i;
	void *pvPDCpuVAddr;
	struct IMG_DEV_PHYADDR sPDDevPAddr;
	struct IMG_CPU_PHYADDR sCpuPAddr;
	struct IMG_SYS_PHYADDR sSysPAddr;
	struct MMU_CONTEXT *psMMUContext;
	void *hPDOSMemHandle;
	struct SYS_DATA *psSysData;
	struct PVRSRV_SGXDEV_INFO *psDevInfo;

	PVR_DPF(PVR_DBG_MESSAGE, "MMU_Initialise");

	if (SysAcquireData(&psSysData) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR,
			 "MMU_Initialise: ERROR call to SysAcquireData failed");
		return PVRSRV_ERROR_GENERIC;
	}

	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
		   sizeof(struct MMU_CONTEXT), (void **) &psMMUContext, NULL)
			!= PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR,
			 "MMU_Initialise: ERROR call to OSAllocMem failed");
		return PVRSRV_ERROR_GENERIC;
	}
	OSMemSet(psMMUContext, 0, sizeof(struct MMU_CONTEXT));

	psDevInfo = (struct PVRSRV_SGXDEV_INFO *)psDeviceNode->pvDevice;
	psMMUContext->psDevInfo = psDevInfo;

	psMMUContext->psDeviceNode = psDeviceNode;

	if (psDeviceNode->psLocalDevMemArena == NULL) {
		if (OSAllocPages
		    (PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
		     SGX_MMU_PAGE_SIZE, SGX_MMU_PAGE_SIZE, &pvPDCpuVAddr,
		     &hPDOSMemHandle) != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: "
					"ERROR call to OSAllocPages failed");
			goto err1;
		}

		if (pvPDCpuVAddr)
			sCpuPAddr = OSMapLinToCPUPhys(pvPDCpuVAddr);
		else
			sCpuPAddr = OSMemHandleToCpuPAddr(hPDOSMemHandle, 0);
		sPDDevPAddr =
		    SysCpuPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
	} else {
		if (RA_Alloc(psDeviceNode->psLocalDevMemArena,
			     SGX_MMU_PAGE_SIZE, NULL, 0, SGX_MMU_PAGE_SIZE,
			     &(sSysPAddr.uiAddr)) != IMG_TRUE) {
			PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: "
					"ERROR call to RA_Alloc failed");

			goto err1;
		}

		sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
		sPDDevPAddr =
		    SysSysPAddrToDevPAddr(PVRSRV_DEVICE_TYPE_SGX, sSysPAddr);
		pvPDCpuVAddr = (void __force *)
		    OSMapPhysToLin(sCpuPAddr, SGX_MMU_PAGE_SIZE,
				   PVRSRV_HAP_WRITECOMBINE |
				   PVRSRV_HAP_KERNEL_ONLY, &hPDOSMemHandle);
		if (!pvPDCpuVAddr) {
			PVR_DPF(PVR_DBG_ERROR, "MMU_Initialise: "
					"ERROR failed to map page tables");

			goto err2;
		}
	}

	PDUMPCOMMENT("Alloc page directory");

	PDUMPMALLOCPAGETABLE(pvPDCpuVAddr, PDUMP_PD_UNIQUETAG);

	if (pvPDCpuVAddr) {
		pui32Tmp = (u32 *) pvPDCpuVAddr;
	} else {
		PVR_DPF(PVR_DBG_ERROR,
			 "MMU_Initialise: pvPDCpuVAddr invalid");
		goto err3;
	}

	for (i = 0; i < SGX_MMU_PD_SIZE; i++)
		pui32Tmp[i] = 0;

	PDUMPCOMMENT("Page directory contents");
	PDUMPPAGETABLE(pvPDCpuVAddr, SGX_MMU_PAGE_SIZE, IMG_TRUE,
		       PDUMP_PD_UNIQUETAG, PDUMP_PT_UNIQUETAG);

	psMMUContext->pvPDCpuVAddr = pvPDCpuVAddr;
	psMMUContext->sPDDevPAddr = sPDDevPAddr;
	psMMUContext->hPDOSMemHandle = hPDOSMemHandle;

	*ppsMMUContext = psMMUContext;

	*psPDDevPAddr = sPDDevPAddr;

	psMMUContext->psNext = (struct MMU_CONTEXT *)
						psDevInfo->pvMMUContextList;
	psDevInfo->pvMMUContextList = (void *) psMMUContext;


	return PVRSRV_OK;
err3:
	if (psDeviceNode->psLocalDevMemArena)
		OSUnMapPhysToLin((void __iomem __force *)pvPDCpuVAddr,
				 SGX_MMU_PAGE_SIZE, PVRSRV_HAP_WRITECOMBINE |
					PVRSRV_HAP_KERNEL_ONLY,
				 hPDOSMemHandle);
err2:
	if (!psDeviceNode->psLocalDevMemArena)
		OSFreePages(PVRSRV_HAP_WRITECOMBINE | PVRSRV_HAP_KERNEL_ONLY,
			    SGX_MMU_PAGE_SIZE, pvPDCpuVAddr, hPDOSMemHandle);
	else
		RA_Free(psDeviceNode->psLocalDevMemArena,
			sSysPAddr.uiAddr, IMG_FALSE);
err1:
	OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct MMU_CONTEXT),
		  psMMUContext, NULL);

	return PVRSRV_ERROR_GENERIC;
}
static IMG_BOOL _DeferredAllocPagetables(struct MMU_HEAP *pMMUHeap,
				struct IMG_DEV_VIRTADDR DevVAddr, u32 ui32Size)
{
	u32 ui32PTPageCount;
	u32 ui32PDIndex;
	u32 i;
	u32 *pui32PDEntry;
	struct MMU_PT_INFO **ppsPTInfoList;
	struct SYS_DATA *psSysData;
	struct IMG_DEV_VIRTADDR sHighDevVAddr;

	PVR_ASSERT(DevVAddr.uiAddr < (1 << SGX_FEATURE_ADDRESS_SPACE_SIZE));

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

	ui32PDIndex =
	    DevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);

	if ((UINT32_MAX_VALUE - DevVAddr.uiAddr) <
	    (ui32Size + (1 << (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT)) - 1)) {

		sHighDevVAddr.uiAddr = UINT32_MAX_VALUE;
	} else {
		sHighDevVAddr.uiAddr = DevVAddr.uiAddr + ui32Size +
					(1 << (SGX_MMU_PAGE_SHIFT +
					       SGX_MMU_PT_SHIFT)) - 1;
	}

	ui32PTPageCount =
	    sHighDevVAddr.uiAddr >> (SGX_MMU_PAGE_SHIFT + SGX_MMU_PT_SHIFT);

	ui32PTPageCount -= ui32PDIndex;

	pui32PDEntry = (u32 *) pMMUHeap->psMMUContext->pvPDCpuVAddr;
	pui32PDEntry += ui32PDIndex;

	ppsPTInfoList = &pMMUHeap->psMMUContext->apsPTInfoList[ui32PDIndex];

	PDUMPCOMMENT("Alloc page table (page count == %08X)", ui32PTPageCount);
	PDUMPCOMMENT("Page directory mods (page count == %08X)",
		     ui32PTPageCount);

	for (i = 0; i < ui32PTPageCount; i++) {
		if (ppsPTInfoList[i] == NULL) {
			if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
				   sizeof(struct MMU_PT_INFO),
				   (void **) &ppsPTInfoList[i], NULL)
					!= PVRSRV_OK) {
				PVR_DPF(PVR_DBG_ERROR,
					"_DeferredAllocPagetables: "
					"ERROR call to OSAllocMem failed");
				return IMG_FALSE;
			}
			OSMemSet(ppsPTInfoList[i], 0,
				 sizeof(struct MMU_PT_INFO));
		}

		if (ppsPTInfoList[i]->hPTPageOSMemHandle == NULL &&
		    ppsPTInfoList[i]->PTPageCpuVAddr == NULL) {
			struct IMG_CPU_PHYADDR sCpuPAddr;
			struct IMG_DEV_PHYADDR sDevPAddr;

			PVR_ASSERT(pui32PDEntry[i] == 0);

			if (pMMUHeap->psDevArena->psDeviceMemoryHeapInfo->
			    psLocalDevMemArena == NULL) {
				if (OSAllocPages(PVRSRV_HAP_WRITECOMBINE |
						     PVRSRV_HAP_KERNEL_ONLY,
					     SGX_MMU_PAGE_SIZE,
					     SGX_MMU_PAGE_SIZE,
					     (void **)&ppsPTInfoList[i]->
						PTPageCpuVAddr,
					     &ppsPTInfoList[i]->
						hPTPageOSMemHandle) !=
				    PVRSRV_OK) {
					PVR_DPF(PVR_DBG_ERROR,
					   "_DeferredAllocPagetables: "
					   "ERROR call to OSAllocPages failed");
					return IMG_FALSE;
				}

				if (ppsPTInfoList[i]->PTPageCpuVAddr) {
					sCpuPAddr =
					    OSMapLinToCPUPhys(ppsPTInfoList[i]->
							      PTPageCpuVAddr);
				} else {
					sCpuPAddr =
					    OSMemHandleToCpuPAddr(
						ppsPTInfoList[i]->
							  hPTPageOSMemHandle,
						0);
				}
				sDevPAddr =
				    SysCpuPAddrToDevPAddr
					    (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);
			} else {
				struct IMG_SYS_PHYADDR sSysPAddr;

				if (RA_Alloc(pMMUHeap->psDevArena->
				     psDeviceMemoryHeapInfo->psLocalDevMemArena,
				     SGX_MMU_PAGE_SIZE, NULL, 0,
				     SGX_MMU_PAGE_SIZE,
				     &(sSysPAddr.uiAddr)) != IMG_TRUE) {
					PVR_DPF(PVR_DBG_ERROR,
					       "_DeferredAllocPagetables: "
					       "ERROR call to RA_Alloc failed");
					return IMG_FALSE;
				}

				sCpuPAddr = SysSysPAddrToCpuPAddr(sSysPAddr);
				ppsPTInfoList[i]->PTPageCpuVAddr =
				    (void __force *)
				    OSMapPhysToLin(sCpuPAddr, SGX_MMU_PAGE_SIZE,
						   PVRSRV_HAP_WRITECOMBINE |
						   PVRSRV_HAP_KERNEL_ONLY,
						   &ppsPTInfoList[i]->
						   hPTPageOSMemHandle);
				if (!ppsPTInfoList[i]->PTPageCpuVAddr) {
					PVR_DPF(PVR_DBG_ERROR,
					     "_DeferredAllocPagetables: "
					     "ERROR failed to map page tables");
					return IMG_FALSE;
				}

				sDevPAddr = SysCpuPAddrToDevPAddr
					    (PVRSRV_DEVICE_TYPE_SGX, sCpuPAddr);

			}


			OSMemSet(ppsPTInfoList[i]->PTPageCpuVAddr, 0,
				 SGX_MMU_PAGE_SIZE);

			PDUMPMALLOCPAGETABLE(ppsPTInfoList[i]->PTPageCpuVAddr,
					     PDUMP_PT_UNIQUETAG);

			PDUMPPAGETABLE(ppsPTInfoList[i]->PTPageCpuVAddr,
				       SGX_MMU_PAGE_SIZE, IMG_TRUE,
				       PDUMP_PT_UNIQUETAG, PDUMP_PT_UNIQUETAG);

			switch (pMMUHeap->psDevArena->DevMemHeapType) {
			case DEVICE_MEMORY_HEAP_SHARED:
			case DEVICE_MEMORY_HEAP_SHARED_EXPORTED:
				{
					struct MMU_CONTEXT *psMMUContext =
					    (struct MMU_CONTEXT *)pMMUHeap->
						    psMMUContext->psDevInfo->
							    pvMMUContextList;

					while (psMMUContext) {
						pui32PDEntry =
						    (u32 *)psMMUContext->
								pvPDCpuVAddr;
						pui32PDEntry += ui32PDIndex;

						pui32PDEntry[i] =
						    sDevPAddr.uiAddr |
							SGX_MMU_PDE_VALID;

						PDUMPPAGETABLE
						    ((void *)&pui32PDEntry[i],
						     sizeof(u32), IMG_FALSE,
						     PDUMP_PD_UNIQUETAG,
						     PDUMP_PT_UNIQUETAG);

						psMMUContext =
						    psMMUContext->psNext;
					}
					break;
				}
			case DEVICE_MEMORY_HEAP_PERCONTEXT:
			case DEVICE_MEMORY_HEAP_KERNEL:
				{
					pui32PDEntry[i] = sDevPAddr.uiAddr |
							     SGX_MMU_PDE_VALID;

					PDUMPPAGETABLE((void *)&pui32PDEntry[i],
						       sizeof(u32), IMG_FALSE,
						       PDUMP_PD_UNIQUETAG,
						       PDUMP_PT_UNIQUETAG);

					break;
				}
			default:
				{
					PVR_DPF(PVR_DBG_ERROR,
						"_DeferredAllocPagetables: "
						"ERROR invalid heap type");
					return IMG_FALSE;
				}
			}


			MMU_InvalidateDirectoryCache(pMMUHeap->psMMUContext->
						     psDevInfo);
		} else {

			PVR_ASSERT(pui32PDEntry[i] != 0);
		}
	}

	return IMG_TRUE;
}