/*************************************************************************/ /*!
@Title          Physmem_test
@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
@Description    Single entry point for testing of page factories
@License        Dual MIT/GPLv2

The contents of this file are subject to the MIT license as set out below.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

Alternatively, the contents of this file may be used under the terms of
the GNU General Public License Version 2 ("GPL") in which case the provisions
of GPL are applicable instead of those above.

If you wish to allow use of your version of this file only under the terms of
GPL, and not to allow others to use your version of this file under the terms
of the MIT license, indicate your decision by deleting the provisions above
and replace them with the notice and other provisions required by GPL as set
out in the file called "GPL-COPYING" included in this distribution. If you do
not delete the provisions above, a recipient may use your version of this file
under the terms of either the MIT license or GPL.

This License is also included in this distribution in the file called
"MIT-COPYING".

EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ /***************************************************************************/
#if defined(SUPPORT_PHYSMEM_TEST)
#include "img_defs.h"
#include "img_types.h"
#include "pvrsrv_error.h"
#include "physmem_test.h"
#include "device.h"
#include "syscommon.h"
#include "pmr.h"
#include "osfunc.h"
#include "physmem.h"
#include "physmem_osmem.h"
#include "physmem_lma.h"
#include "pvrsrv.h"

#define PHYSMEM_TEST_PAGES        2     /* Mem test pages */
#define PHYSMEM_TEST_PASSES_MAX   1000  /* Limit number of passes to some reasonable value */


/* Test patterns for mem test */

static const IMG_UINT64 gui64Patterns[] = {
	0,
	0xffffffffffffffffULL,
	0x5555555555555555ULL,
	0xaaaaaaaaaaaaaaaaULL,
	0x1111111111111111ULL,
	0x2222222222222222ULL,
	0x4444444444444444ULL,
	0x8888888888888888ULL,
	0x3333333333333333ULL,
	0x6666666666666666ULL,
	0x9999999999999999ULL,
	0xccccccccccccccccULL,
	0x7777777777777777ULL,
	0xbbbbbbbbbbbbbbbbULL,
	0xddddddddddddddddULL,
	0xeeeeeeeeeeeeeeeeULL,
	0x7a6c7258554e494cULL,
};

static const IMG_UINT32 gui32Patterns[] = {
	0,
	0xffffffffU,
	0x55555555U,
	0xaaaaaaaaU,
	0x11111111U,
	0x22222222U,
	0x44444444U,
	0x88888888U,
	0x33333333U,
	0x66666666U,
	0x99999999U,
	0xccccccccU,
	0x77777777U,
	0xbbbbbbbbU,
	0xddddddddU,
	0xeeeeeeeeU,
	0x7a6c725cU,
};

static const IMG_UINT16 gui16Patterns[] = {
	0,
	0xffffU,
	0x5555U,
	0xaaaaU,
	0x1111U,
	0x2222U,
	0x4444U,
	0x8888U,
	0x3333U,
	0x6666U,
	0x9999U,
	0xccccU,
	0x7777U,
	0xbbbbU,
	0xddddU,
	0xeeeeU,
	0x7a6cU,
};

static const IMG_UINT8 gui8Patterns[] = {
	0,
	0xffU,
	0x55U,
	0xaaU,
	0x11U,
	0x22U,
	0x44U,
	0x88U,
	0x33U,
	0x66U,
	0x99U,
	0xccU,
	0x77U,
	0xbbU,
	0xddU,
	0xeeU,
	0x6cU,
};


/* Following function does minimal required initialisation for mem test using dummy device node */
static PVRSRV_ERROR
PhysMemTestInit(PVRSRV_DEVICE_NODE **ppsDeviceNode, PVRSRV_DEVICE_CONFIG *psDevConfig)
{
	PVRSRV_ERROR			eError = PVRSRV_OK;
	PVRSRV_DEVICE_NODE		*psDeviceNode;

	/* Dummy device node */
	psDeviceNode = OSAllocZMem(sizeof(*psDeviceNode));
	PVR_LOGR_IF_NOMEM(psDeviceNode, "OSAllocZMem");

	psDeviceNode->eDevState = PVRSRV_DEVICE_STATE_INIT;
	psDeviceNode->psDevConfig = psDevConfig;
	psDeviceNode->eCurrentSysPowerState = PVRSRV_SYS_POWER_STATE_ON;

	/* Initialise Phys mem heaps */
	eError = PVRSRVPhysMemHeapsInit(psDeviceNode, psDevConfig);
	PVR_LOGG_IF_ERROR(eError, "PVRSRVPhysMemHeapsInit", ErrorSysDevDeInit);

	psDeviceNode->uiMMUPxLog2AllocGran = OSGetPageShift();

	*ppsDeviceNode = psDeviceNode;

	return PVRSRV_OK;

ErrorSysDevDeInit:
	psDevConfig->psDevNode = NULL;
	OSFreeMem(psDeviceNode);
	return eError;
}

/* Undo initialisation done for mem test */
static void
PhysMemTestDeInit(PVRSRV_DEVICE_NODE *psDeviceNode)
{
	/* Deinitialise Phys mem heaps */
	PVRSRVPhysMemHeapsDeinit(psDeviceNode);

	OSFreeMem(psDeviceNode);
}

/* Test for PMR factory validation */
static PVRSRV_ERROR
PMRValidationTest(PVRSRV_DEVICE_NODE *psDeviceNode, PVRSRV_MEMALLOCFLAGS_T uiFlags)
{
	PVRSRV_ERROR eError, eError1;
	IMG_UINT32 i = 0, j = 0, ui32Index = 0;
	IMG_UINT32 *pui32MappingTable = NULL;
	PMR *psPMR = NULL;
	IMG_BOOL *pbValid;
	IMG_DEV_PHYADDR *apsDevPAddr;
	IMG_UINT32 ui32NumOfPages = 10, ui32NumOfPhysPages = 5;
	size_t uiMappedSize, uiPageSize;
	IMG_UINT8 *pcWriteBuffer, *pcReadBuffer;
	IMG_HANDLE hPrivData = NULL;
	void *pvKernAddr = NULL;

	uiPageSize = OSGetPageSize();

	/* Allocate OS memory for PMR page list */
	apsDevPAddr = OSAllocMem(ui32NumOfPages * sizeof(IMG_DEV_PHYADDR));
	PVR_LOGR_IF_NOMEM(apsDevPAddr, "OSAllocMem");

	/* Allocate OS memory for PMR page state */
	pbValid = OSAllocMem(ui32NumOfPages * sizeof(IMG_BOOL));
	PVR_LOGG_IF_NOMEM(pbValid, "OSAllocMem", eError, ErrorFreePMRPageListMem);
	OSCachedMemSet(pbValid, 0, ui32NumOfPages * sizeof(IMG_BOOL));

	/* Allocate OS memory for write buffer */
	pcWriteBuffer = OSAllocMem(uiPageSize);
	PVR_LOGG_IF_NOMEM(pcWriteBuffer, "OSAllocMem", eError, ErrorFreePMRPageStateMem);
	OSCachedMemSet(pcWriteBuffer, 0xF, uiPageSize);

	/* Allocate OS memory for read buffer */
	pcReadBuffer = OSAllocMem(uiPageSize);
	PVR_LOGG_IF_NOMEM(pcWriteBuffer, "OSAllocMem", eError, ErrorFreeWriteBuffer);

	/* Allocate OS memory for mapping table */
	pui32MappingTable = (IMG_UINT32 *)OSAllocMem(ui32NumOfPhysPages * sizeof(*pui32MappingTable));
	PVR_LOGG_IF_NOMEM(pui32MappingTable, "OSAllocMem", eError, ErrorFreeReadBuffer);

	/* Pages having even index will have physical backing in PMR */
	for (ui32Index=0; ui32Index < ui32NumOfPages; ui32Index+=2)
	{
		pui32MappingTable[i++] = ui32Index;
	}

	/* Allocate Sparse PMR with SPARSE | READ | WRITE | UNCACHED attributes */
	uiFlags |= PVRSRV_MEMALLOCFLAG_SPARSE_NO_DUMMY_BACKING | \
				PVRSRV_MEMALLOCFLAG_CPU_READABLE | \
				PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \
				PVRSRV_MEMALLOCFLAG_CPU_UNCACHED;

	/* Allocate a sparse PMR from given physical heap - CPU/GPU/FW */
	eError = PhysmemNewRamBackedPMR(NULL,
									psDeviceNode,
									ui32NumOfPages * uiPageSize,
									uiPageSize,
									ui32NumOfPhysPages,
									ui32NumOfPages,
									pui32MappingTable,
									OSGetPageShift(),
									uiFlags,
									(strlen("PMR ValidationTest") + 1),
									"PMR ValidationTest",
									OSGetCurrentClientProcessIDKM(),
									&psPMR);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "Failed to allocate a PMR"));
		goto ErrorFreeMappingTable;
	}

	/* Check whether allocated PMR can be locked and obtain physical addresses of underlying memory pages */
	eError = PMRLockSysPhysAddresses(psPMR);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "Failed to lock PMR"));
		goto ErrorUnrefPMR;
	}

	/* Get the Device physical addresses of the pages */
	eError = PMR_DevPhysAddr(psPMR, OSGetPageShift(), ui32NumOfPages, 0, apsDevPAddr, pbValid);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "Failed to map PMR pages into device physical addresses"));
		goto ErrorUnlockPhysAddresses;
	}

	/* Check whether device address of each physical page is OS PAGE_SIZE aligned */
	for (i = 0; i < ui32NumOfPages; i++)
	{
		if (pbValid[i])
		{
			if ((apsDevPAddr[i].uiAddr & OSGetPageMask()) != 0)
			{
				PVR_DPF((PVR_DBG_ERROR, "Physical memory of PMR is not page aligned"));
				eError = PVRSRV_ERROR_MEMORY_TEST_FAILED;
				goto ErrorUnlockPhysAddresses;
			}
		}
	}

	/* Acquire kernel virtual address of each physical page and write to it and then release it */
	for (i = 0; i < ui32NumOfPages; i++)
	{
		if (pbValid[i])
		{
			eError = PMRAcquireSparseKernelMappingData(psPMR, (i * uiPageSize), uiPageSize, &pvKernAddr, &uiMappedSize, &hPrivData);
			if (eError != PVRSRV_OK)
			{
				PVR_DPF((PVR_DBG_ERROR, "Failed to Acquire Kernel Mapping of PMR"));
				goto ErrorUnlockPhysAddresses;
			}
			OSDeviceMemCopy(pvKernAddr, pcWriteBuffer, OSGetPageSize());

			eError = PMRReleaseKernelMappingData(psPMR, hPrivData);
			PVR_LOG_IF_ERROR(eError, "PMRReleaseKernelMappingData");
		}
	}

	/* Acquire kernel virtual address of each physical page and read from it and check where contents are intact */
	for (i = 0; i < ui32NumOfPages; i++)
	{
		if (pbValid[i])
		{
			eError = PMRAcquireSparseKernelMappingData(psPMR, (i * uiPageSize), uiPageSize, &pvKernAddr, &uiMappedSize, &hPrivData);
			if (eError != PVRSRV_OK)
			{
				PVR_DPF((PVR_DBG_ERROR, "Failed to Acquire Kernel Mapping of PMR"));
				goto ErrorUnlockPhysAddresses;
			}
			OSCachedMemSet(pcReadBuffer, 0x0, uiPageSize);
			OSDeviceMemCopy(pcReadBuffer, pvKernAddr, uiMappedSize);

			eError = PMRReleaseKernelMappingData(psPMR, hPrivData);
			PVR_LOG_IF_ERROR(eError, "PMRReleaseKernelMappingData");

			for (j = 0; j < uiPageSize; j++)
			{
				if (pcReadBuffer[j] != pcWriteBuffer[j])
				{
					PVR_DPF((PVR_DBG_ERROR, "%s: Test failed. Got (0x%hhx), expected (0x%hhx)!", __func__, pcReadBuffer[j], pcWriteBuffer[j]));
					eError = PVRSRV_ERROR_MEMORY_TEST_FAILED;
					goto ErrorUnlockPhysAddresses;
				}
			}
		}
	}

ErrorUnlockPhysAddresses:
	/* Unlock and Unref the PMR to destroy it */
	eError1 = PMRUnlockSysPhysAddresses(psPMR);
	if (eError1 != PVRSRV_OK)
	{
		eError = (eError == PVRSRV_OK)? eError1 : eError;
		PVR_DPF((PVR_DBG_ERROR, "Failed to unlock PMR"));
	}

ErrorUnrefPMR:
	eError1 = PMRUnrefPMR(psPMR);
	if (eError1 != PVRSRV_OK)
	{
		eError = (eError == PVRSRV_OK)? eError1 : eError;
		PVR_DPF((PVR_DBG_ERROR, "Failed to free PMR"));
	}
ErrorFreeMappingTable:
	OSFreeMem(pui32MappingTable);
ErrorFreeReadBuffer:
	OSFreeMem(pcReadBuffer);
ErrorFreeWriteBuffer:
	OSFreeMem(pcWriteBuffer);
ErrorFreePMRPageStateMem:
	OSFreeMem(pbValid);
ErrorFreePMRPageListMem:
	OSFreeMem(apsDevPAddr);

	return eError;
}

#define DO_MEMTEST_FOR_PATTERNS(StartAddr, EndAddr, Patterns, NumOfPatterns, Error, ptr, i) \
	for (i = 0; i < NumOfPatterns; i++) \
	{ \
		/* Write pattern */ \
		for (ptr = StartAddr; ptr < EndAddr; ptr++) \
		{ \
			*ptr = Patterns[i]; \
		} \
		\
		/* Read back and validate pattern */ \
		for (ptr = StartAddr; ptr < EndAddr ; ptr++) \
		{ \
			if (*ptr != Patterns[i]) \
			{ \
				Error = PVRSRV_ERROR_MEMORY_TEST_FAILED; \
				break; \
			} \
		} \
		\
		if (Error != PVRSRV_OK) \
		{ \
			break; \
		} \
	}

static PVRSRV_ERROR
TestPatternU8(void *pvKernAddr, size_t uiMappedSize)
{
	IMG_UINT8 *StartAddr = (IMG_UINT8 *) pvKernAddr;
	IMG_UINT8 *EndAddr = ((IMG_UINT8 *) pvKernAddr) + (uiMappedSize / sizeof(IMG_UINT8));
	IMG_UINT8 *p;
	IMG_UINT32 i;
	PVRSRV_ERROR eError = PVRSRV_OK;

	PVR_ASSERT((uiMappedSize % sizeof(IMG_UINT8)) == 0);

	DO_MEMTEST_FOR_PATTERNS(StartAddr, EndAddr, gui8Patterns, sizeof(gui8Patterns)/sizeof(IMG_UINT8), eError, p, i);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"%s: Test failed. Got (0x%hhx), expected (0x%hhx)!", __func__, *p, gui8Patterns[i])); \
	}

	return eError;
}


static PVRSRV_ERROR
TestPatternU16(void *pvKernAddr, size_t uiMappedSize)
{
	IMG_UINT16 *StartAddr = (IMG_UINT16 *) pvKernAddr;
	IMG_UINT16 *EndAddr = ((IMG_UINT16 *) pvKernAddr) + (uiMappedSize / sizeof(IMG_UINT16));
	IMG_UINT16 *p;
	IMG_UINT32 i;
	PVRSRV_ERROR eError = PVRSRV_OK;

	PVR_ASSERT((uiMappedSize % sizeof(IMG_UINT16)) == 0);

	DO_MEMTEST_FOR_PATTERNS(StartAddr, EndAddr, gui16Patterns, sizeof(gui16Patterns)/sizeof(IMG_UINT16), eError, p, i);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"%s: Test failed. Got (0x%hx), expected (0x%hx)!", __func__, *p, gui16Patterns[i])); \
	}

	return eError;
}

static PVRSRV_ERROR
TestPatternU32(void *pvKernAddr, size_t uiMappedSize)
{
	IMG_UINT32 *StartAddr = (IMG_UINT32 *) pvKernAddr;
	IMG_UINT32 *EndAddr = ((IMG_UINT32 *) pvKernAddr) + (uiMappedSize / sizeof(IMG_UINT32));
	IMG_UINT32 *p;
	IMG_UINT32 i;
	PVRSRV_ERROR eError = PVRSRV_OK;

	PVR_ASSERT((uiMappedSize % sizeof(IMG_UINT32)) == 0);

	DO_MEMTEST_FOR_PATTERNS(StartAddr, EndAddr, gui32Patterns, sizeof(gui32Patterns)/sizeof(IMG_UINT32), eError, p, i);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"%s: Test failed. Got (0x%x), expected (0x%x)!", __func__, *p, gui32Patterns[i])); \
	}

	return eError;
}

static PVRSRV_ERROR
TestPatternU64(void *pvKernAddr, size_t uiMappedSize)
{
	IMG_UINT64 *StartAddr = (IMG_UINT64 *) pvKernAddr;
	IMG_UINT64 *EndAddr = ((IMG_UINT64 *) pvKernAddr) + (uiMappedSize / sizeof(IMG_UINT64));
	IMG_UINT64 *p;
	IMG_UINT32 i;
	PVRSRV_ERROR eError = PVRSRV_OK;

	PVR_ASSERT((uiMappedSize % sizeof(IMG_UINT64)) == 0);

	DO_MEMTEST_FOR_PATTERNS(StartAddr, EndAddr, gui64Patterns, sizeof(gui64Patterns)/sizeof(IMG_UINT64), eError, p, i);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"%s: Test failed. Got (0x%llx), expected (0x%llx)!", __func__, *p, gui64Patterns[i])); \
	}

	return eError;
}

static PVRSRV_ERROR
TestSplitCacheline(void *pvKernAddr, size_t uiMappedSize)
{
	PVRSRV_ERROR eError = PVRSRV_OK;
	size_t uiCacheLineSize;
	size_t uiBlockSize;
	size_t j;
	IMG_UINT8 *pcWriteBuffer, *pcReadBuffer;
	IMG_UINT8 *StartAddr = (IMG_UINT8 *) pvKernAddr;
	IMG_UINT8 *EndAddr, *p;

	uiCacheLineSize = OSCPUCacheAttributeSize(PVR_DCACHE_LINE_SIZE);

	if (uiCacheLineSize > 0)
	{
		uiBlockSize = (uiCacheLineSize * 2)/3; /* split cacheline */

		pcWriteBuffer = OSAllocMem(uiBlockSize);
		PVR_LOGR_IF_NOMEM(pcWriteBuffer, "OSAllocMem");

		/* Fill the write buffer with test data, 0xAB*/
		OSCachedMemSet(pcWriteBuffer, 0xAB, uiBlockSize);

		pcReadBuffer = OSAllocMem(uiBlockSize);
		PVR_LOGG_IF_NOMEM(pcWriteBuffer, "OSAllocMem", eError, ErrorFreeWriteBuffer);

		/* Fit only complete blocks in uiMappedSize, ignore leftover bytes */
		EndAddr = StartAddr + (uiBlockSize * (uiMappedSize / uiBlockSize));

		/* Write blocks into the memory */
		for (p = StartAddr; p < EndAddr; p += uiBlockSize)
		{
			OSCachedMemCopy(p, pcWriteBuffer, uiBlockSize);
		}

		/* Read back blocks and check */
		for (p = StartAddr; p < EndAddr; p += uiBlockSize)
		{
			OSCachedMemCopy(pcReadBuffer, p, uiBlockSize);

			for (j = 0; j < uiBlockSize; j++)
			{
				if (pcReadBuffer[j] != pcWriteBuffer[j])
				{
					PVR_DPF((PVR_DBG_ERROR, "%s: Test failed. Got (0x%hhx), expected (0x%hhx)!", __func__, pcReadBuffer[j], pcWriteBuffer[j]));
					eError = PVRSRV_ERROR_MEMORY_TEST_FAILED;
					goto ErrorMemTestFailed;
				}
			}
		}

ErrorMemTestFailed:
		OSFreeMem(pcReadBuffer);
ErrorFreeWriteBuffer:
		OSFreeMem(pcWriteBuffer);
	}

	return eError;
}

/* Memory test - writes and reads back different patterns to memory and validate the same */
static PVRSRV_ERROR
MemTestPatterns(PVRSRV_DEVICE_NODE *psDeviceNode, PVRSRV_MEMALLOCFLAGS_T uiFlags)
{
	PVRSRV_ERROR eError;
	IMG_UINT32 ui32MappingTable = 0;
	PMR *psPMR = NULL;
	size_t uiMappedSize, uiPageSize;
	IMG_HANDLE hPrivData = NULL;
	void *pvKernAddr = NULL;

	uiPageSize = OSGetPageSize();

	/* Allocate PMR with READ | WRITE | WRITE_COMBINE attributes */
	uiFlags |= PVRSRV_MEMALLOCFLAG_CPU_READABLE | \
			   PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE | \
			   PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE;

	/*Allocate a PMR from given physical heap */
	eError = PhysmemNewRamBackedPMR(NULL,
									psDeviceNode,
									uiPageSize * PHYSMEM_TEST_PAGES,
									uiPageSize * PHYSMEM_TEST_PAGES,
									1,
									1,
									&ui32MappingTable,
									OSGetPageShift(),
									uiFlags,
									(strlen("PMR PhysMemTest") + 1),
									"PMR PhysMemTest",
									OSGetCurrentClientProcessIDKM(),
									&psPMR);
	PVR_LOGR_IF_ERROR(eError, "PhysmemNewRamBackedPMR");

	/* Check whether allocated PMR can be locked and obtain physical addresses of underlying memory pages */
	eError = PMRLockSysPhysAddresses(psPMR);
	PVR_LOGG_IF_ERROR(eError, "PMRLockSysPhysAddresses", ErrorUnrefPMR);

	/* Map the physical page(s) into kernel space, acquire kernel mapping for PMR */
	eError = PMRAcquireKernelMappingData(psPMR, 0, uiPageSize * PHYSMEM_TEST_PAGES, &pvKernAddr, &uiMappedSize, &hPrivData);
	PVR_LOGG_IF_ERROR(eError, "PMRAcquireKernelMappingData", ErrorUnlockPhysAddresses);

	PVR_ASSERT((uiPageSize * PHYSMEM_TEST_PAGES) == uiMappedSize);

	/* Test various patterns */
	eError = TestPatternU64(pvKernAddr, uiMappedSize);
	if (eError != PVRSRV_OK)
	{
		goto ErrorReleaseKernelMappingData;
	}

	eError = TestPatternU32(pvKernAddr, uiMappedSize);
	if (eError != PVRSRV_OK)
	{
		goto ErrorReleaseKernelMappingData;
	}

	eError = TestPatternU16(pvKernAddr, uiMappedSize);
	if (eError != PVRSRV_OK)
	{
		goto ErrorReleaseKernelMappingData;
	}

	eError = TestPatternU8(pvKernAddr, uiMappedSize);
	if (eError != PVRSRV_OK)
	{
		goto ErrorReleaseKernelMappingData;
	}

	/* Test split cachelines */
	eError = TestSplitCacheline(pvKernAddr, uiMappedSize);

ErrorReleaseKernelMappingData:
	(void) PMRReleaseKernelMappingData(psPMR, hPrivData);

ErrorUnlockPhysAddresses:
	/* Unlock and Unref the PMR to destroy it, ignore returned value */
	(void) PMRUnlockSysPhysAddresses(psPMR);
ErrorUnrefPMR:
	(void) PMRUnrefPMR(psPMR);

	return eError;
}

static PVRSRV_ERROR
PhysMemTestRun(PVRSRV_DEVICE_NODE *psDeviceNode, PVRSRV_MEMALLOCFLAGS_T uiFlags, IMG_UINT32 ui32Passes)
{
	PVRSRV_ERROR eError;
	IMG_UINT32 i;

	/* PMR validation test */
	eError = PMRValidationTest(psDeviceNode, uiFlags);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"%s: PMR validation test failed!", __func__));
		return eError;
	}

	for (i = 0; i < ui32Passes; i++)
	{
		/* Mem test */
		eError = MemTestPatterns(psDeviceNode, uiFlags);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,"%s: [Pass#%u] MemTestPatterns failed!", __func__, i));
			break;
		}
	}

	return eError;
}

PVRSRV_ERROR
PhysMemTest(void *pvDevConfig, IMG_UINT32 ui32MemTestPasses)
{
	PVRSRV_ERROR eError = PVRSRV_OK;
	PVRSRV_DEVICE_NODE *psDeviceNode;
	PVRSRV_DEVICE_CONFIG *psDevConfig = pvDevConfig;

	/* validate memtest passes requested */
	ui32MemTestPasses = (ui32MemTestPasses > PHYSMEM_TEST_PASSES_MAX)? PHYSMEM_TEST_PASSES_MAX : ui32MemTestPasses;

	/* Do minimal initialisation before test */
	eError = PhysMemTestInit(&psDeviceNode, psDevConfig);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Test failed to initialize", __func__));
		return eError;
	}

	/* GPU local mem */
	eError = PhysMemTestRun(psDeviceNode, 0, ui32MemTestPasses);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "GPU local memory test failed!"));
		goto ErrorPhysMemTestDeinit;
	}

	/* FW local mem */
	eError = PhysMemTestRun(psDeviceNode, PVRSRV_MEMALLOCFLAG_FW_LOCAL, ui32MemTestPasses);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "FW local memory test failed!"));
		goto ErrorPhysMemTestDeinit;
	}

	/* CPU local mem */
	eError = PhysMemTestRun(psDeviceNode, PVRSRV_MEMALLOCFLAG_CPU_LOCAL, ui32MemTestPasses);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "CPU local memory test failed!"));
		goto ErrorPhysMemTestDeinit;
	}

	PVR_DPF((PVR_DBG_ERROR, "PhysMemTest: Passed."));
	goto PhysMemTestPassed;

ErrorPhysMemTestDeinit:
	PVR_DPF((PVR_DBG_ERROR, "PhysMemTest: Failed."));
PhysMemTestPassed:
	PhysMemTestDeInit(psDeviceNode);

	return eError;
}
#endif
