/*************************************************************************/ /*!
@File
@Title          Devicemem history functions
@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
@Description    Devicemem history functions
@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.
*/ /**************************************************************************/

#include "allocmem.h"
#include "img_defs.h"
#include "pmr.h"
#include "pvrsrv.h"
#include "pvrsrv_device.h"
#include "pvr_debug.h"
#include "devicemem_server.h"
#include "lock.h"
#include "devicemem_history_server.h"
#include "pdump_km.h"

#define ALLOCATION_LIST_NUM_ENTRIES 10000

/* data type to hold an allocation index.
 * we make it 16 bits wide if possible
 */
#if ALLOCATION_LIST_NUM_ENTRIES <= 0xFFFF
typedef uint16_t ALLOC_INDEX_T;
#else
typedef uint32_t ALLOC_INDEX_T;
#endif

/* a record describing a single allocation known to DeviceMemHistory.
 * this is an element in a doubly linked list of allocations
 */
typedef struct _RECORD_ALLOCATION_
{
	/* time when this RECORD_ALLOCATION was created/initialised */
	IMG_UINT64 ui64CreationTime;
	/* serial number of the PMR relating to this allocation */
	IMG_UINT64 ui64Serial;
	/* base DevVAddr of this allocation */
	IMG_DEV_VIRTADDR sDevVAddr;
	/* size in bytes of this allocation */
	IMG_DEVMEM_SIZE_T uiSize;
	/* Log2 page size of this allocation's GPU pages */
	IMG_UINT32 ui32Log2PageSize;
	/* Process ID (PID) this allocation belongs to */
	IMG_PID uiPID;
	/* index of previous allocation in the list */
	ALLOC_INDEX_T ui32Prev;
	/* index of next allocation in the list */
	ALLOC_INDEX_T ui32Next;
	/* annotation/name of this allocation */
	IMG_CHAR szName[DEVMEM_ANNOTATION_MAX_LEN];
} RECORD_ALLOCATION;

/* each command in the circular buffer is prefixed with an 8-bit value
 * denoting the command type
 */
typedef enum _COMMAND_TYPE_
{
	COMMAND_TYPE_NONE,
	COMMAND_TYPE_TIMESTAMP,
	COMMAND_TYPE_MAP_ALL,
	COMMAND_TYPE_UNMAP_ALL,
	COMMAND_TYPE_MAP_RANGE,
	COMMAND_TYPE_UNMAP_RANGE,
	/* sentinel value */
	COMMAND_TYPE_COUNT,
} COMMAND_TYPE;

/* Timestamp command:
 * This command is inserted into the circular buffer to provide an updated
 * timestamp.
 * The nanosecond-accuracy timestamp is packed into a 56-bit integer, in order
 * for the whole command to fit into 8 bytes.
 */
typedef struct _COMMAND_TIMESTAMP_
{
	IMG_UINT8 aui8TimeNs[7];
} COMMAND_TIMESTAMP;

/* MAP_ALL command:
 * This command denotes the allocation at the given index was wholly mapped
 * in to the GPU MMU
 */
typedef struct _COMMAND_MAP_ALL_
{
	ALLOC_INDEX_T uiAllocIndex;
} COMMAND_MAP_ALL;

/* UNMAP_ALL command:
 * This command denotes the allocation at the given index was wholly unmapped
 * from the GPU MMU
 * Note: COMMAND_MAP_ALL and COMMAND_UNMAP_ALL commands have the same layout.
 */
typedef COMMAND_MAP_ALL COMMAND_UNMAP_ALL;

/* packing attributes for the MAP_RANGE command */
#define MAP_RANGE_MAX_START ((1 << 18) - 1)
#define MAP_RANGE_MAX_RANGE ((1 << 12) - 1)

/* MAP_RANGE command:
 * Denotes a range of pages within the given allocation being mapped.
 * The range is expressed as [Page Index] + [Page Count]
 * This information is packed into a 40-bit integer, in order to make
 * the command size 8 bytes.
 */

typedef struct _COMMAND_MAP_RANGE_
{
	IMG_UINT8 aui8Data[5];
	ALLOC_INDEX_T uiAllocIndex;
} COMMAND_MAP_RANGE;

/* UNMAP_RANGE command:
 * Denotes a range of pages within the given allocation being mapped.
 * The range is expressed as [Page Index] + [Page Count]
 * This information is packed into a 40-bit integer, in order to make
 * the command size 8 bytes.
 * Note: COMMAND_MAP_RANGE and COMMAND_UNMAP_RANGE commands have the same layout.
 */
typedef COMMAND_MAP_RANGE COMMAND_UNMAP_RANGE;

/* wrapper structure for a command */
typedef struct _COMMAND_WRAPPER_
{
	IMG_UINT8 ui8Type;
	union {
		COMMAND_TIMESTAMP sTimeStamp;
		COMMAND_MAP_ALL sMapAll;
		COMMAND_UNMAP_ALL sUnmapAll;
		COMMAND_MAP_RANGE sMapRange;
		COMMAND_UNMAP_RANGE sUnmapRange;
	} u;
} COMMAND_WRAPPER;

/* target size for the circular buffer of commands */
#define CIRCULAR_BUFFER_SIZE_KB 2048
/* turn the circular buffer target size into a number of commands */
#define CIRCULAR_BUFFER_NUM_COMMANDS ((CIRCULAR_BUFFER_SIZE_KB * 1024) / sizeof(COMMAND_WRAPPER))

/* index value denoting the end of a list */
#define END_OF_LIST 0xFFFFFFFF
#define ALLOC_INDEX_TO_PTR(idx) (&(gsDevicememHistoryData.sRecords.pasAllocations[idx]))
#define CHECK_ALLOC_INDEX(idx) (idx < ALLOCATION_LIST_NUM_ENTRIES)

/* wrapper structure for the allocation records and the commands circular buffer */
typedef struct _RECORDS_
{
	RECORD_ALLOCATION *pasAllocations;
	IMG_UINT32 ui32AllocationsListHead;

	IMG_UINT32 ui32Head;
	IMG_UINT32 ui32Tail;
	COMMAND_WRAPPER *pasCircularBuffer;
} RECORDS;

typedef struct _DEVICEMEM_HISTORY_DATA_
{
	/* debugfs entry */
	void *pvStatsEntry;

	RECORDS sRecords;
	POS_LOCK hLock;
} DEVICEMEM_HISTORY_DATA;

static DEVICEMEM_HISTORY_DATA gsDevicememHistoryData;

static void DevicememHistoryLock(void)
{
	OSLockAcquire(gsDevicememHistoryData.hLock);
}

static void DevicememHistoryUnlock(void)
{
	OSLockRelease(gsDevicememHistoryData.hLock);
}

/* given a time stamp, calculate the age in nanoseconds */
static IMG_UINT64 _CalculateAge(IMG_UINT64 ui64Now,
						IMG_UINT64 ui64Then,
						IMG_UINT64 ui64Max)
{
	if (ui64Now >= ui64Then)
	{
		/* no clock wrap */
		return ui64Now - ui64Then;
	}
	else
	{
		/* clock has wrapped */
		return (ui64Max - ui64Then) + ui64Now + 1;
	}
}

/* AcquireCBSlot:
 * Acquire the next slot in the circular buffer and
 * move the circular buffer head along by one
 * Returns a pointer to the acquired slot.
 */
static COMMAND_WRAPPER *AcquireCBSlot(void)
{
	COMMAND_WRAPPER *psSlot;

	psSlot = &gsDevicememHistoryData.sRecords.pasCircularBuffer[gsDevicememHistoryData.sRecords.ui32Head];

	gsDevicememHistoryData.sRecords.ui32Head =
		(gsDevicememHistoryData.sRecords.ui32Head + 1)
				% CIRCULAR_BUFFER_NUM_COMMANDS;

	return psSlot;
}

/* TimeStampPack:
 * Packs the given timestamp value into the COMMAND_TIMESTAMP structure.
 * This takes a 64-bit nanosecond timestamp and packs it in to a 56-bit
 * integer in the COMMAND_TIMESTAMP command.
 */
static void TimeStampPack(COMMAND_TIMESTAMP *psTimeStamp, IMG_UINT64 ui64Now)
{
	IMG_UINT32 i;

	for (i = 0; i < ARRAY_SIZE(psTimeStamp->aui8TimeNs); i++)
	{
		psTimeStamp->aui8TimeNs[i] = ui64Now & 0xFF;
		ui64Now >>= 8;
	}
}

/* packing a 64-bit nanosecond into a 7-byte integer loses the
 * top 8 bits of data. This must be taken into account when
 * comparing a full timestamp against an unpacked timestamp
 */
#define TIME_STAMP_MASK ((1LLU << 56) - 1)
#define DO_TIME_STAMP_MASK(ns64) (ns64 & TIME_STAMP_MASK)

/* TimeStampUnpack:
 * Unpack the timestamp value from the given COMMAND_TIMESTAMP command
 */
static IMG_UINT64 TimeStampUnpack(COMMAND_TIMESTAMP *psTimeStamp)
{
	IMG_UINT64 ui64TimeNs = 0;
	IMG_UINT32 i;

	for (i = ARRAY_SIZE(psTimeStamp->aui8TimeNs); i > 0; i--)
	{
		ui64TimeNs <<= 8;
		ui64TimeNs |= (IMG_UINT64) psTimeStamp->aui8TimeNs[i - 1];
	}

	return ui64TimeNs;
}

#if defined(PDUMP)

static void EmitPDumpAllocation(IMG_UINT32 ui32AllocationIndex,
					RECORD_ALLOCATION *psAlloc)
{
	PDUMPCOMMENT("[SrvPFD] Allocation: %u"
			" Addr: " IMG_DEV_VIRTADDR_FMTSPEC
			" Size: " IMG_DEVMEM_SIZE_FMTSPEC
			" Page size: %u"
			" PID: %u"
			" Process: %s"
			" Name: %s",
			ui32AllocationIndex,
			psAlloc->sDevVAddr.uiAddr,
			psAlloc->uiSize,
			1U << psAlloc->ui32Log2PageSize,
			psAlloc->uiPID,
			OSGetCurrentClientProcessNameKM(),
			psAlloc->szName);
}

static void EmitPDumpMapUnmapAll(COMMAND_TYPE eType,
					IMG_UINT32 ui32AllocationIndex)
{
	const IMG_CHAR *pszOpName;

	switch (eType)
	{
		case COMMAND_TYPE_MAP_ALL:
			pszOpName = "MAP_ALL";
			break;
		case COMMAND_TYPE_UNMAP_ALL:
			pszOpName = "UNMAP_ALL";
			break;
		default:
			PVR_DPF((PVR_DBG_ERROR, "EmitPDumpMapUnmapAll: Invalid type: %u",
										eType));
			return;

	}

	PDUMPCOMMENT("[SrvPFD] Op: %s Allocation: %u",
								pszOpName,
								ui32AllocationIndex);
}

static void EmitPDumpMapUnmapRange(COMMAND_TYPE eType,
					IMG_UINT32 ui32AllocationIndex,
					IMG_UINT32 ui32StartPage,
					IMG_UINT32 ui32Count)
{
	const IMG_CHAR *pszOpName;

	switch (eType)
	{
		case COMMAND_TYPE_MAP_RANGE:
			pszOpName = "MAP_RANGE";
			break;
		case COMMAND_TYPE_UNMAP_RANGE:
			pszOpName = "UNMAP_RANGE";
			break;
		default:
			PVR_DPF((PVR_DBG_ERROR, "EmitPDumpMapUnmapRange: Invalid type: %u",
										eType));
			return;
	}

	PDUMPCOMMENT("[SrvPFD] Op: %s Allocation: %u Start Page: %u Count: %u",
									pszOpName,
									ui32AllocationIndex,
									ui32StartPage,
									ui32Count);
}

#endif

/* InsertTimeStampCommand:
 * Insert a timestamp command into the circular buffer.
 */
static void InsertTimeStampCommand(IMG_UINT64 ui64Now)
{
	COMMAND_WRAPPER *psCommand;

	psCommand = AcquireCBSlot();

	psCommand->ui8Type = COMMAND_TYPE_TIMESTAMP;

	TimeStampPack(&psCommand->u.sTimeStamp, ui64Now);
}

/* InsertMapAllCommand:
 * Insert a "MAP_ALL" command for the given allocation into the circular buffer
 */
static void InsertMapAllCommand(IMG_UINT32 ui32AllocIndex)
{
	COMMAND_WRAPPER *psCommand;

	psCommand = AcquireCBSlot();

	psCommand->ui8Type = COMMAND_TYPE_MAP_ALL;
	psCommand->u.sMapAll.uiAllocIndex = ui32AllocIndex;

#if defined(PDUMP)
	EmitPDumpMapUnmapAll(COMMAND_TYPE_MAP_ALL, ui32AllocIndex);
#endif
}

/* InsertUnmapAllCommand:
 * Insert a "UNMAP_ALL" command for the given allocation into the circular buffer
 */
static void InsertUnmapAllCommand(IMG_UINT32 ui32AllocIndex)
{
	COMMAND_WRAPPER *psCommand;

	psCommand = AcquireCBSlot();

	psCommand->ui8Type = COMMAND_TYPE_UNMAP_ALL;
	psCommand->u.sUnmapAll.uiAllocIndex = ui32AllocIndex;

#if defined(PDUMP)
	EmitPDumpMapUnmapAll(COMMAND_TYPE_UNMAP_ALL, ui32AllocIndex);
#endif
}

/* MapRangePack:
 * Pack the given StartPage and Count values into the 40-bit representation
 * in the MAP_RANGE command.
 */
static void MapRangePack(COMMAND_MAP_RANGE *psMapRange,
						IMG_UINT32 ui32StartPage,
						IMG_UINT32 ui32Count)
{
	IMG_UINT64 ui64Data;
	IMG_UINT32 i;

	/* we must encode the data into 40 bits:
	 *   18 bits for the start page index
	 *   12 bits for the range
	*/

	PVR_ASSERT(ui32StartPage <= MAP_RANGE_MAX_START);
	PVR_ASSERT(ui32Count <= MAP_RANGE_MAX_RANGE);

	ui64Data = (((IMG_UINT64) ui32StartPage) << 12) | ui32Count;

	for (i = 0; i < ARRAY_SIZE(psMapRange->aui8Data); i++)
	{
		psMapRange->aui8Data[i] = ui64Data & 0xFF;
		ui64Data >>= 8;
	}
}

/* MapRangePack:
 * Unpack the StartPage and Count values from the 40-bit representation
 * in the MAP_RANGE command.
 */
static void MapRangeUnpack(COMMAND_MAP_RANGE *psMapRange,
						IMG_UINT32 *pui32StartPage,
						IMG_UINT32 *pui32Count)
{
	IMG_UINT64 ui64Data = 0;
	IMG_UINT32 i;

	for (i = ARRAY_SIZE(psMapRange->aui8Data); i > 0; i--)
	{
		ui64Data <<= 8;
		ui64Data |= (IMG_UINT64) psMapRange->aui8Data[i - 1];
	}

	*pui32StartPage = (ui64Data >> 12);
	*pui32Count = ui64Data & ((1 << 12) - 1);
}

/* InsertMapRangeCommand:
 * Insert a MAP_RANGE command into the circular buffer with the given
 * StartPage and Count values.
 */
static void InsertMapRangeCommand(IMG_UINT32 ui32AllocIndex,
						IMG_UINT32 ui32StartPage,
						IMG_UINT32 ui32Count)
{
	COMMAND_WRAPPER *psCommand;

	psCommand = AcquireCBSlot();

	psCommand->ui8Type = COMMAND_TYPE_MAP_RANGE;
	psCommand->u.sMapRange.uiAllocIndex = ui32AllocIndex;

	MapRangePack(&psCommand->u.sMapRange, ui32StartPage, ui32Count);

#if defined(PDUMP)
	EmitPDumpMapUnmapRange(COMMAND_TYPE_MAP_RANGE,
							ui32AllocIndex,
							ui32StartPage,
							ui32Count);
#endif
}

/* InsertUnmapRangeCommand:
 * Insert a UNMAP_RANGE command into the circular buffer with the given
 * StartPage and Count values.
 */
static void InsertUnmapRangeCommand(IMG_UINT32 ui32AllocIndex,
						IMG_UINT32 ui32StartPage,
						IMG_UINT32 ui32Count)
{
	COMMAND_WRAPPER *psCommand;

	psCommand = AcquireCBSlot();

	psCommand->ui8Type = COMMAND_TYPE_UNMAP_RANGE;
	psCommand->u.sMapRange.uiAllocIndex = ui32AllocIndex;

	MapRangePack(&psCommand->u.sMapRange, ui32StartPage, ui32Count);

#if defined(PDUMP)
	EmitPDumpMapUnmapRange(COMMAND_TYPE_UNMAP_RANGE,
							ui32AllocIndex,
							ui32StartPage,
							ui32Count);
#endif
}

/* InsertAllocationToList:
 * Helper function for the allocation list.
 * Inserts the given allocation at the head of the list, whose current head is
 * pointed to by pui32ListHead
 */
static void InsertAllocationToList(IMG_UINT32 *pui32ListHead, IMG_UINT32 ui32Alloc)
{
	RECORD_ALLOCATION *psAlloc;

	psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc);

	if (*pui32ListHead == END_OF_LIST)
	{
		/* list is currently empty, so just replace it */
		*pui32ListHead = ui32Alloc;
		psAlloc->ui32Next = psAlloc->ui32Prev = *pui32ListHead;
	}
	else
	{
		RECORD_ALLOCATION *psHeadAlloc;
		RECORD_ALLOCATION *psTailAlloc;

		psHeadAlloc = ALLOC_INDEX_TO_PTR(*pui32ListHead);
		psTailAlloc = ALLOC_INDEX_TO_PTR(psHeadAlloc->ui32Prev);

		/* make the new alloc point forwards to the previous head */
		psAlloc->ui32Next = *pui32ListHead;
		/* make the new alloc point backwards to the previous tail */
		psAlloc->ui32Prev = psHeadAlloc->ui32Prev;

		/* the head is now our new alloc */
		*pui32ListHead = ui32Alloc;

		/* the old head now points back to the new head */
		psHeadAlloc->ui32Prev = *pui32ListHead;

		/* the tail now points forward to the new head */
		psTailAlloc->ui32Next = ui32Alloc;
	}
}

static void InsertAllocationToBusyList(IMG_UINT32 ui32Alloc)
{
	InsertAllocationToList(&gsDevicememHistoryData.sRecords.ui32AllocationsListHead, ui32Alloc);
}

/* RemoveAllocationFromList:
 * Helper function for the allocation list.
 * Removes the given allocation from the list, whose head is
 * pointed to by pui32ListHead
 */
static void RemoveAllocationFromList(IMG_UINT32 *pui32ListHead, IMG_UINT32 ui32Alloc)
{
	RECORD_ALLOCATION *psAlloc;

	psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc);

	/* if this is the only element in the list then just make the list empty */
	if ((*pui32ListHead == ui32Alloc) && (psAlloc->ui32Next == ui32Alloc))
	{
		*pui32ListHead = END_OF_LIST;
	}
	else
	{
		RECORD_ALLOCATION *psPrev, *psNext;

		psPrev = ALLOC_INDEX_TO_PTR(psAlloc->ui32Prev);
		psNext = ALLOC_INDEX_TO_PTR(psAlloc->ui32Next);

		/* remove the allocation from the list */
		psPrev->ui32Next = psAlloc->ui32Next;
		psNext->ui32Prev = psAlloc->ui32Prev;

		/* if this allocation is the head then update the head */
		if (*pui32ListHead == ui32Alloc)
		{
			*pui32ListHead = psAlloc->ui32Prev;
		}
	}
}

static void RemoveAllocationFromBusyList(IMG_UINT32 ui32Alloc)
{
	RemoveAllocationFromList(&gsDevicememHistoryData.sRecords.ui32AllocationsListHead, ui32Alloc);
}

/* TouchBusyAllocation:
 * Move the given allocation to the head of the list
 */
static void TouchBusyAllocation(IMG_UINT32 ui32Alloc)
{
	RemoveAllocationFromBusyList(ui32Alloc);
	InsertAllocationToBusyList(ui32Alloc);
}

static INLINE IMG_BOOL IsAllocationListEmpty(IMG_UINT32 ui32ListHead)
{
	return ui32ListHead == END_OF_LIST;
}

/* GetOldestBusyAllocation:
 * Returns the index of the oldest allocation in the MRU list
 */
static IMG_UINT32 GetOldestBusyAllocation(void)
{
	IMG_UINT32 ui32Alloc;
	RECORD_ALLOCATION *psAlloc;

	ui32Alloc = gsDevicememHistoryData.sRecords.ui32AllocationsListHead;

	if (ui32Alloc == END_OF_LIST)
	{
		return END_OF_LIST;
	}

	psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc);

	return psAlloc->ui32Prev;
}

static IMG_UINT32 GetFreeAllocation(void)
{
	IMG_UINT32 ui32Alloc;

	ui32Alloc = GetOldestBusyAllocation();

	return ui32Alloc;
}


/* InitialiseAllocation:
 * Initialise the given allocation structure with the given properties
 */
static void InitialiseAllocation(RECORD_ALLOCATION *psAlloc,
							const IMG_CHAR *pszName,
							IMG_UINT64 ui64Serial,
							IMG_PID uiPID,
							IMG_DEV_VIRTADDR sDevVAddr,
							IMG_DEVMEM_SIZE_T uiSize,
							IMG_UINT32 ui32Log2PageSize)
{
	OSStringLCopy(psAlloc->szName, pszName, sizeof(psAlloc->szName));
	psAlloc->ui64Serial = ui64Serial;
	psAlloc->uiPID = uiPID;
	psAlloc->sDevVAddr = sDevVAddr;
	psAlloc->uiSize = uiSize;
	psAlloc->ui32Log2PageSize = ui32Log2PageSize;
	psAlloc->ui64CreationTime = OSClockns64();
}

/* CreateAllocation:
 * Creates a new allocation with the given properties then outputs the
 * index of the allocation
 */
static PVRSRV_ERROR CreateAllocation(const IMG_CHAR *pszName,
							IMG_UINT64 ui64Serial,
							IMG_PID uiPID,
							IMG_DEV_VIRTADDR sDevVAddr,
							IMG_DEVMEM_SIZE_T uiSize,
							IMG_UINT32 ui32Log2PageSize,
							IMG_BOOL bAutoPurge,
							IMG_UINT32 *puiAllocationIndex)
{
	IMG_UINT32 ui32Alloc;
	RECORD_ALLOCATION *psAlloc;

	ui32Alloc = GetFreeAllocation();

	psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc);

	InitialiseAllocation(ALLOC_INDEX_TO_PTR(ui32Alloc),
						pszName,
						ui64Serial,
						uiPID,
						sDevVAddr,
						uiSize,
						ui32Log2PageSize);

	/* put the newly initialised allocation at the front of the MRU list */
	TouchBusyAllocation(ui32Alloc);

	*puiAllocationIndex = ui32Alloc;

#if defined(PDUMP)
	EmitPDumpAllocation(ui32Alloc, psAlloc);
#endif

	return PVRSRV_OK;
}

/* MatchAllocation:
 * Tests if the allocation at the given index matches the supplied properties.
 * Returns IMG_TRUE if it is a match, otherwise IMG_FALSE.
 */
static IMG_BOOL MatchAllocation(IMG_UINT32 ui32AllocationIndex,
						IMG_UINT64 ui64Serial,
						IMG_DEV_VIRTADDR sDevVAddr,
						IMG_DEVMEM_SIZE_T uiSize,
						const IMG_CHAR *pszName,
						IMG_UINT32 ui32Log2PageSize,
						IMG_PID uiPID)
{
	RECORD_ALLOCATION *psAlloc;

	psAlloc = ALLOC_INDEX_TO_PTR(ui32AllocationIndex);

	return 	(psAlloc->ui64Serial == ui64Serial) &&
			(psAlloc->sDevVAddr.uiAddr == sDevVAddr.uiAddr) &&
			(psAlloc->uiSize == uiSize) &&
			(psAlloc->ui32Log2PageSize == ui32Log2PageSize) &&
			(OSStringCompare(psAlloc->szName, pszName) == 0);
}

/* FindOrCreateAllocation:
 * Convenience function.
 * Given a set of allocation properties (serial, DevVAddr, size, name, etc),
 * this function will look for an existing record of this allocation and
 * create the allocation if there is no existing record
 */
static PVRSRV_ERROR FindOrCreateAllocation(IMG_UINT32 ui32AllocationIndexHint,
							IMG_UINT64 ui64Serial,
							IMG_DEV_VIRTADDR sDevVAddr,
							IMG_DEVMEM_SIZE_T uiSize,
							const char *pszName,
							IMG_UINT32 ui32Log2PageSize,
							IMG_PID uiPID,
							IMG_BOOL bSparse,
							IMG_UINT32 *pui32AllocationIndexOut,
							IMG_BOOL *pbCreated)
{
	IMG_UINT32 ui32AllocationIndex;
	PVRSRV_ERROR eError;

	if (ui32AllocationIndexHint != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE)
	{
		IMG_BOOL bHaveAllocation;

		/* first, try to match against the index given by the client.
		 * if the caller provided a hint but the allocation record is no longer
		 * there, it must have been purged, so go ahead and create a new allocation
		 */
		bHaveAllocation = MatchAllocation(ui32AllocationIndexHint,
								ui64Serial,
								sDevVAddr,
								uiSize,
								pszName,
								ui32Log2PageSize,
								uiPID);
		if (bHaveAllocation)
		{
			*pbCreated = IMG_FALSE;
			*pui32AllocationIndexOut = ui32AllocationIndexHint;
			return PVRSRV_OK;
		}
	}

	/* if there is no record of the allocation then we
	 * create it now
	 */
	eError = CreateAllocation(pszName,
					ui64Serial,
					uiPID,
					sDevVAddr,
					uiSize,
					ui32Log2PageSize,
					IMG_TRUE,
					&ui32AllocationIndex);

	if (eError == PVRSRV_OK)
	{
		*pui32AllocationIndexOut = ui32AllocationIndex;
		*pbCreated = IMG_TRUE;
	}
	else
	{
		PVR_DPF((PVR_DBG_ERROR,
			"%s: Failed to create record for allocation %s",
								__func__,
								pszName));
	}

	return eError;
}

/* GenerateMapUnmapCommandsForSparsePMR:
 * Generate the MAP_RANGE or UNMAP_RANGE commands for the sparse PMR, using the PMR's
 * current mapping table
 *
 * PMR: The PMR whose mapping table to read.
 * ui32AllocIndex: The allocation to attribute the MAP_RANGE/UNMAP range commands to.
 * bMap: Set to TRUE for mapping or IMG_FALSE for unmapping
 *
 * This function goes through every page in the PMR's mapping table and looks for
 * virtually contiguous ranges to record as being mapped or unmapped.
 */
static void GenerateMapUnmapCommandsForSparsePMR(PMR *psPMR,
							IMG_UINT32 ui32AllocIndex,
							IMG_BOOL bMap)
{
	PMR_MAPPING_TABLE *psMappingTable;
	IMG_UINT32 ui32DonePages = 0;
	IMG_UINT32 ui32NumPages;
	IMG_UINT32 i;
	IMG_BOOL bInARun = IMG_FALSE;
	IMG_UINT32 ui32CurrentStart = 0;
	IMG_UINT32 ui32RunCount = 0;

	psMappingTable = PMR_GetMappigTable(psPMR);
	ui32NumPages = psMappingTable->ui32NumPhysChunks;

	if (ui32NumPages == 0)
	{
		/* nothing to do */
		return;
	}

	for (i = 0; i < psMappingTable->ui32NumVirtChunks; i++)
	{
		if (psMappingTable->aui32Translation[i] != TRANSLATION_INVALID)
		{
			if (!bInARun)
			{
				bInARun = IMG_TRUE;
				ui32CurrentStart = i;
				ui32RunCount = 1;
			}
			else
			{
				ui32RunCount++;
			}
		}

		if (bInARun)
		{
			/* test if we need to end this current run and generate the command,
			 * either because the next page is not virtually contiguous
			 * to the current page, we have reached the maximum range,
			 * or this is the last page in the mapping table
			 */
			if ((psMappingTable->aui32Translation[i] == TRANSLATION_INVALID) ||
				(ui32RunCount == MAP_RANGE_MAX_RANGE) ||
				(i == (psMappingTable->ui32NumVirtChunks - 1)))
			{
				if (bMap)
				{
					InsertMapRangeCommand(ui32AllocIndex,
										ui32CurrentStart,
										ui32RunCount);
				}
				else
				{
					InsertUnmapRangeCommand(ui32AllocIndex,
										ui32CurrentStart,
										ui32RunCount);
				}

				ui32DonePages += ui32RunCount;

				if (ui32DonePages == ui32NumPages)
				{
					 break;
				}

				bInARun = IMG_FALSE;
			}
		}
	}

}

/* GenerateMapUnmapCommandsForChangeList:
 * Generate the MAP_RANGE or UNMAP_RANGE commands for the sparse PMR, using the
 * list of page change (page map or page unmap) indices given.
 *
 * ui32NumPages: Number of pages which have changed.
 * pui32PageList: List of indices of the pages which have changed.
 * ui32AllocIndex: The allocation to attribute the MAP_RANGE/UNMAP range commands to.
 * bMap: Set to TRUE for mapping or IMG_FALSE for unmapping
 *
 * This function goes through every page in the list and looks for
 * virtually contiguous ranges to record as being mapped or unmapped.
 */
static void GenerateMapUnmapCommandsForChangeList(IMG_UINT32 ui32NumPages,
							IMG_UINT32 *pui32PageList,
							IMG_UINT32 ui32AllocIndex,
							IMG_BOOL bMap)
{
	IMG_UINT32 i;
	IMG_BOOL bInARun = IMG_FALSE;
	IMG_UINT32 ui32CurrentStart = 0;
	IMG_UINT32 ui32RunCount = 0;

	for (i = 0; i < ui32NumPages; i++)
	{
		if (!bInARun)
		{
			bInARun = IMG_TRUE;
			ui32CurrentStart = pui32PageList[i];
		}

		ui32RunCount++;

		 /* we flush if:
		 * - the next page in the list is not one greater than the current page
		 * - this is the last page in the list
		 * - we have reached the maximum range size
		 */
		if ((i == (ui32NumPages - 1)) ||
			((pui32PageList[i] + 1) != pui32PageList[i + 1]) ||
			(ui32RunCount == MAP_RANGE_MAX_RANGE))
		{
			if (bMap)
			{
				InsertMapRangeCommand(ui32AllocIndex,
									ui32CurrentStart,
									ui32RunCount);
			}
			else
			{
				InsertUnmapRangeCommand(ui32AllocIndex,
									ui32CurrentStart,
									ui32RunCount);
			}

			bInARun = IMG_FALSE;
			ui32RunCount = 0;
		}
	}
}

/* DevicememHistoryMapKM:
 * Entry point for when an allocation is mapped into the MMU GPU
 *
 * psPMR: The PMR to which the allocation belongs.
 * ui32Offset: The offset within the PMR at which the allocation begins.
 * sDevVAddr: The DevVAddr at which the allocation begins.
 * szName: Annotation/name for the allocation.
 * ui32Log2PageSize: Page size of the allocation, expressed in log2 form.
 * ui32AllocationIndex: Allocation index as provided by the client.
 *                      We will use this as a short-cut to find the allocation
 *                      in our records.
 * pui32AllocationIndexOut: An updated allocation index for the client.
 *                          This may be a new value if we just created the
 *                          allocation record.
 */
PVRSRV_ERROR DevicememHistoryMapKM(PMR *psPMR,
							IMG_UINT32 ui32Offset,
							IMG_DEV_VIRTADDR sDevVAddr,
							IMG_DEVMEM_SIZE_T uiSize,
							const char szName[DEVMEM_ANNOTATION_MAX_LEN],
							IMG_UINT32 ui32Log2PageSize,
							IMG_UINT32 ui32AllocationIndex,
							IMG_UINT32 *pui32AllocationIndexOut)
{
	IMG_BOOL bSparse = PMR_IsSparse(psPMR);
	IMG_UINT64 ui64Serial;
	IMG_PID uiPID = OSGetCurrentClientProcessIDKM();
	PVRSRV_ERROR eError;
	IMG_BOOL bCreated;

	if ((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) &&
		!CHECK_ALLOC_INDEX(ui32AllocationIndex))
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u",
								__func__,
								ui32AllocationIndex));
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	PMRGetUID(psPMR, &ui64Serial);

	DevicememHistoryLock();

	eError = FindOrCreateAllocation(ui32AllocationIndex,
						ui64Serial,
						sDevVAddr,
						uiSize,
						szName,
						ui32Log2PageSize,
						uiPID,
						bSparse,
						&ui32AllocationIndex,
						&bCreated);

	if ((eError == PVRSRV_OK) && !bCreated)
	{
		/* touch the allocation so it goes to the head of our MRU list */
		TouchBusyAllocation(ui32AllocationIndex);
	}
	else if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)",
									__func__,
									szName,
									PVRSRVGETERRORSTRING(eError)));
		goto out_unlock;
	}

	if (!bSparse)
	{
		InsertMapAllCommand(ui32AllocationIndex);
	}
	else
	{
		GenerateMapUnmapCommandsForSparsePMR(psPMR,
								ui32AllocationIndex,
								IMG_TRUE);
	}

	InsertTimeStampCommand(OSClockns64());

	*pui32AllocationIndexOut = ui32AllocationIndex;

out_unlock:
	DevicememHistoryUnlock();

	return eError;
}

static void VRangeInsertMapUnmapCommands(IMG_BOOL bMap,
							IMG_UINT32 ui32AllocationIndex,
							IMG_DEV_VIRTADDR sBaseDevVAddr,
							IMG_UINT32 ui32StartPage,
							IMG_UINT32 ui32NumPages,
							const IMG_CHAR *pszName)
{
	while (ui32NumPages > 0)
	{
		IMG_UINT32 ui32PagesToAdd;

		ui32PagesToAdd = MIN(ui32NumPages, MAP_RANGE_MAX_RANGE);

		if (ui32StartPage > MAP_RANGE_MAX_START)
		{
			PVR_DPF((PVR_DBG_WARNING, "Cannot record %s range beginning at page "
									"%u on allocation %s",
									bMap ? "map" : "unmap",
									ui32StartPage,
									pszName));
			return;
		}

		if (bMap)
		{
			InsertMapRangeCommand(ui32AllocationIndex,
								ui32StartPage,
								ui32PagesToAdd);
		}
		else
		{
			InsertUnmapRangeCommand(ui32AllocationIndex,
								ui32StartPage,
								ui32PagesToAdd);
		}

		ui32StartPage += ui32PagesToAdd;
		ui32NumPages -= ui32PagesToAdd;
	}
}

PVRSRV_ERROR DevicememHistoryMapVRangeKM(IMG_DEV_VIRTADDR sBaseDevVAddr,
						IMG_UINT32 ui32StartPage,
						IMG_UINT32 ui32NumPages,
						IMG_DEVMEM_SIZE_T uiAllocSize,
						const IMG_CHAR szName[DEVMEM_ANNOTATION_MAX_LEN],
						IMG_UINT32 ui32Log2PageSize,
						IMG_UINT32 ui32AllocationIndex,
						IMG_UINT32 *pui32AllocationIndexOut)
{
	IMG_PID uiPID = OSGetCurrentClientProcessIDKM();
	PVRSRV_ERROR eError;
	IMG_BOOL bCreated;

	if ((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) &&
		!CHECK_ALLOC_INDEX(ui32AllocationIndex))
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u",
								__func__,
							ui32AllocationIndex));
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	DevicememHistoryLock();

	eError = FindOrCreateAllocation(ui32AllocationIndex,
						0,
						sBaseDevVAddr,
						uiAllocSize,
						szName,
						ui32Log2PageSize,
						uiPID,
						IMG_FALSE,
						&ui32AllocationIndex,
						&bCreated);

	if ((eError == PVRSRV_OK) && !bCreated)
	{
		/* touch the allocation so it goes to the head of our MRU list */
		TouchBusyAllocation(ui32AllocationIndex);
	}
	else if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)",
									__func__,
									szName,
									PVRSRVGETERRORSTRING(eError)));
		goto out_unlock;
	}

	VRangeInsertMapUnmapCommands(IMG_TRUE,
						ui32AllocationIndex,
						sBaseDevVAddr,
						ui32StartPage,
						ui32NumPages,
						szName);

	*pui32AllocationIndexOut = ui32AllocationIndex;

out_unlock:
	DevicememHistoryUnlock();

	return eError;

}

PVRSRV_ERROR DevicememHistoryUnmapVRangeKM(IMG_DEV_VIRTADDR sBaseDevVAddr,
						IMG_UINT32 ui32StartPage,
						IMG_UINT32 ui32NumPages,
						IMG_DEVMEM_SIZE_T uiAllocSize,
						const IMG_CHAR szName[DEVMEM_ANNOTATION_MAX_LEN],
						IMG_UINT32 ui32Log2PageSize,
						IMG_UINT32 ui32AllocationIndex,
						IMG_UINT32 *pui32AllocationIndexOut)
{
	IMG_PID uiPID = OSGetCurrentClientProcessIDKM();
	PVRSRV_ERROR eError;
	IMG_BOOL bCreated;

	if ((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) &&
		!CHECK_ALLOC_INDEX(ui32AllocationIndex))
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u",
								__func__,
							ui32AllocationIndex));
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	DevicememHistoryLock();

	eError = FindOrCreateAllocation(ui32AllocationIndex,
						0,
						sBaseDevVAddr,
						uiAllocSize,
						szName,
						ui32Log2PageSize,
						uiPID,
						IMG_FALSE,
						&ui32AllocationIndex,
						&bCreated);

	if ((eError == PVRSRV_OK) && !bCreated)
	{
		/* touch the allocation so it goes to the head of our MRU list */
		TouchBusyAllocation(ui32AllocationIndex);
	}
	else if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)",
									__func__,
									szName,
									PVRSRVGETERRORSTRING(eError)));
		goto out_unlock;
	}

	VRangeInsertMapUnmapCommands(IMG_FALSE,
						ui32AllocationIndex,
						sBaseDevVAddr,
						ui32StartPage,
						ui32NumPages,
						szName);

	*pui32AllocationIndexOut = ui32AllocationIndex;

out_unlock:
	DevicememHistoryUnlock();

	return eError;
}



/* DevicememHistoryUnmapKM:
 * Entry point for when an allocation is unmapped from the MMU GPU
 *
 * psPMR: The PMR to which the allocation belongs.
 * ui32Offset: The offset within the PMR at which the allocation begins.
 * sDevVAddr: The DevVAddr at which the allocation begins.
 * szName: Annotation/name for the allocation.
 * ui32Log2PageSize: Page size of the allocation, expressed in log2 form.
 * ui32AllocationIndex: Allocation index as provided by the client.
 *                      We will use this as a short-cut to find the allocation
 *                      in our records.
 * pui32AllocationIndexOut: An updated allocation index for the client.
 *                          This may be a new value if we just created the
 *                          allocation record.
 */
PVRSRV_ERROR DevicememHistoryUnmapKM(PMR *psPMR,
							IMG_UINT32 ui32Offset,
							IMG_DEV_VIRTADDR sDevVAddr,
							IMG_DEVMEM_SIZE_T uiSize,
							const char szName[DEVMEM_ANNOTATION_MAX_LEN],
							IMG_UINT32 ui32Log2PageSize,
							IMG_UINT32 ui32AllocationIndex,
							IMG_UINT32 *pui32AllocationIndexOut)
{
	IMG_BOOL bSparse = PMR_IsSparse(psPMR);
	IMG_UINT64 ui64Serial;
	IMG_PID uiPID = OSGetCurrentClientProcessIDKM();
	PVRSRV_ERROR eError;
	IMG_BOOL bCreated;

	if ((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) &&
		!CHECK_ALLOC_INDEX(ui32AllocationIndex))
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u",
								__func__,
								ui32AllocationIndex));
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	PMRGetUID(psPMR, &ui64Serial);

	DevicememHistoryLock();

	eError = FindOrCreateAllocation(ui32AllocationIndex,
						ui64Serial,
						sDevVAddr,
						uiSize,
						szName,
						ui32Log2PageSize,
						uiPID,
						bSparse,
						&ui32AllocationIndex,
						&bCreated);

	if ((eError == PVRSRV_OK) && !bCreated)
	{
		/* touch the allocation so it goes to the head of our MRU list */
		TouchBusyAllocation(ui32AllocationIndex);
	}
	else if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)",
									__func__,
									szName,
									PVRSRVGETERRORSTRING(eError)));
		goto out_unlock;
	}

	if (!bSparse)
	{
		InsertUnmapAllCommand(ui32AllocationIndex);
	}
	else
	{
		GenerateMapUnmapCommandsForSparsePMR(psPMR,
								ui32AllocationIndex,
								IMG_FALSE);
	}

	InsertTimeStampCommand(OSClockns64());

	*pui32AllocationIndexOut = ui32AllocationIndex;

out_unlock:
	DevicememHistoryUnlock();

	return eError;
}

/* DevicememHistorySparseChangeKM:
 * Entry point for when a sparse allocation is changed, such that some of the
 * pages within the sparse allocation are mapped or unmapped.
 *
 * psPMR: The PMR to which the allocation belongs.
 * ui32Offset: The offset within the PMR at which the allocation begins.
 * sDevVAddr: The DevVAddr at which the allocation begins.
 * szName: Annotation/name for the allocation.
 * ui32Log2PageSize: Page size of the allocation, expressed in log2 form.
 * ui32AllocPageCount: Number of pages which have been mapped.
 * paui32AllocPageIndices: Indices of pages which have been mapped.
 * ui32FreePageCount: Number of pages which have been unmapped.
 * paui32FreePageIndices: Indices of pages which have been unmapped.
 * ui32AllocationIndex: Allocation index as provided by the client.
 *                      We will use this as a short-cut to find the allocation
 *                      in our records.
 * pui32AllocationIndexOut: An updated allocation index for the client.
 *                          This may be a new value if we just created the
 *                          allocation record.
 */
PVRSRV_ERROR DevicememHistorySparseChangeKM(PMR *psPMR,
							IMG_UINT32 ui32Offset,
							IMG_DEV_VIRTADDR sDevVAddr,
							IMG_DEVMEM_SIZE_T uiSize,
							const char szName[DEVMEM_ANNOTATION_MAX_LEN],
							IMG_UINT32 ui32Log2PageSize,
							IMG_UINT32 ui32AllocPageCount,
							IMG_UINT32 *paui32AllocPageIndices,
							IMG_UINT32 ui32FreePageCount,
							IMG_UINT32 *paui32FreePageIndices,
							IMG_UINT32 ui32AllocationIndex,
							IMG_UINT32 *pui32AllocationIndexOut)
{
	IMG_UINT64 ui64Serial;
	IMG_PID uiPID = OSGetCurrentClientProcessIDKM();
	PVRSRV_ERROR eError;
	IMG_BOOL bCreated;

	if ((ui32AllocationIndex != DEVICEMEM_HISTORY_ALLOC_INDEX_NONE) &&
		!CHECK_ALLOC_INDEX(ui32AllocationIndex))
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid allocation index: %u",
								__func__,
								ui32AllocationIndex));
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	PMRGetUID(psPMR, &ui64Serial);

	DevicememHistoryLock();

	eError = FindOrCreateAllocation(ui32AllocationIndex,
						ui64Serial,
						sDevVAddr,
						uiSize,
						szName,
						ui32Log2PageSize,
						uiPID,
						IMG_TRUE /* bSparse */,
						&ui32AllocationIndex,
						&bCreated);

	if ((eError == PVRSRV_OK) && !bCreated)
	{
		/* touch the allocation so it goes to the head of our MRU list */
		TouchBusyAllocation(ui32AllocationIndex);
	}
	else if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Failed to Find or Create allocation %s (%s)",
									__func__,
									szName,
									PVRSRVGETERRORSTRING(eError)));
		goto out_unlock;
	}

	GenerateMapUnmapCommandsForChangeList(ui32AllocPageCount,
							paui32AllocPageIndices,
							ui32AllocationIndex,
							IMG_TRUE);

	GenerateMapUnmapCommandsForChangeList(ui32FreePageCount,
							paui32FreePageIndices,
							ui32AllocationIndex,
							IMG_FALSE);

	InsertTimeStampCommand(OSClockns64());

	*pui32AllocationIndexOut = ui32AllocationIndex;

out_unlock:
	DevicememHistoryUnlock();

	return eError;

}

/* CircularBufferIterateStart:
 * Initialise local state for iterating over the circular buffer
 */
static void CircularBufferIterateStart(IMG_UINT32 *pui32Head, IMG_UINT32 *pui32Iter)
{
	*pui32Head = gsDevicememHistoryData.sRecords.ui32Head;

	if (*pui32Head != 0)
	{
		*pui32Iter = *pui32Head - 1;
	}
	else
	{
		*pui32Iter = CIRCULAR_BUFFER_NUM_COMMANDS - 1;
	}
}

/* CircularBufferIteratePrevious:
 * Iterate to the previous item in the circular buffer.
 * This is called repeatedly to iterate over the whole circular buffer.
 */
static COMMAND_WRAPPER *CircularBufferIteratePrevious(IMG_UINT32 ui32Head,
							IMG_UINT32 *pui32Iter,
							COMMAND_TYPE *peType,
							IMG_BOOL *pbLast)
{
	IMG_UINT8 *pui8Header;
	COMMAND_WRAPPER *psOut = NULL;

	psOut = gsDevicememHistoryData.sRecords.pasCircularBuffer + *pui32Iter;

	pui8Header = (IMG_UINT8 *) psOut;

	/* sanity check the command looks valid.
	 * this condition should never happen, but check for it anyway
	 * and try to handle it
	 */
	if (*pui8Header >= COMMAND_TYPE_COUNT)
	{
		/* invalid header detected. Circular buffer corrupted? */
		PVR_DPF((PVR_DBG_ERROR, "CircularBufferIteratePrevious: "
							"Invalid header: %u",
							*pui8Header));
		*pbLast = IMG_TRUE;
		return NULL;
	}

	*peType = *pui8Header;

	if (*pui32Iter != 0)
	{
		(*pui32Iter)--;
	}
	else
	{
		*pui32Iter = CIRCULAR_BUFFER_NUM_COMMANDS - 1;
	}


	/* inform the caller this is the last command if either we have reached
	 * the head (where we started) or if we have reached an empty command,
	 * which means we have covered all populated entries
	 */
	if ((*pui32Iter == ui32Head) || (*peType == COMMAND_TYPE_NONE))
	{
		/* this is the final iteration */
		*pbLast = IMG_TRUE;
	}

	return psOut;
}

/* MapUnmapCommandGetInfo:
 * Helper function to get the address and mapping information from a MAP_ALL, UNMAP_ALL,
 * MAP_RANGE or UNMAP_RANGE command
 */
static void MapUnmapCommandGetInfo(COMMAND_WRAPPER *psCommand,
					COMMAND_TYPE eType,
					IMG_DEV_VIRTADDR *psDevVAddrStart,
					IMG_DEV_VIRTADDR *psDevVAddrEnd,
					IMG_BOOL *pbMap,
					IMG_UINT32 *pui32AllocIndex)
{
	if ((eType == COMMAND_TYPE_MAP_ALL) || ((eType == COMMAND_TYPE_UNMAP_ALL)))
	{
		COMMAND_MAP_ALL *psMapAll = &psCommand->u.sMapAll;
		RECORD_ALLOCATION *psAlloc;

		*pbMap = (eType == COMMAND_TYPE_MAP_ALL);
		*pui32AllocIndex = psMapAll->uiAllocIndex;

		psAlloc = ALLOC_INDEX_TO_PTR(psMapAll->uiAllocIndex);

		*psDevVAddrStart = psAlloc->sDevVAddr;
		psDevVAddrEnd->uiAddr = psDevVAddrStart->uiAddr + psAlloc->uiSize - 1;
	}
	else if ((eType == COMMAND_TYPE_MAP_RANGE) || ((eType == COMMAND_TYPE_UNMAP_RANGE)))
	{
		COMMAND_MAP_RANGE *psMapRange = &psCommand->u.sMapRange;
		RECORD_ALLOCATION *psAlloc;
		IMG_UINT32 ui32StartPage, ui32Count;

		*pbMap = (eType == COMMAND_TYPE_MAP_RANGE);
		*pui32AllocIndex = psMapRange->uiAllocIndex;

		psAlloc = ALLOC_INDEX_TO_PTR(psMapRange->uiAllocIndex);

		MapRangeUnpack(psMapRange, &ui32StartPage, &ui32Count);

		psDevVAddrStart->uiAddr = psAlloc->sDevVAddr.uiAddr +
				((1ULL << psAlloc->ui32Log2PageSize) * ui32StartPage);

		psDevVAddrEnd->uiAddr = psDevVAddrStart->uiAddr +
				((1ULL << psAlloc->ui32Log2PageSize) * ui32Count) - 1;
	}
	else
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid command type: %u",
								__func__,
								eType));
	}
}

/* DevicememHistoryQuery:
 * Entry point for rgxdebug to look up addresses relating to a page fault
 */
IMG_BOOL DevicememHistoryQuery(DEVICEMEM_HISTORY_QUERY_IN *psQueryIn,
                               DEVICEMEM_HISTORY_QUERY_OUT *psQueryOut,
                               IMG_UINT32 ui32PageSizeBytes,
                               IMG_BOOL bMatchAnyAllocInPage)
{
	IMG_UINT32 ui32Head, ui32Iter;
	COMMAND_TYPE eType = COMMAND_TYPE_NONE;
	COMMAND_WRAPPER *psCommand = NULL;
	IMG_BOOL bLast = IMG_FALSE;
	IMG_UINT64 ui64StartTime = OSClockns64();
	IMG_UINT64 ui64TimeNs = 0;

	/* initialise the results count for the caller */
	psQueryOut->ui32NumResults = 0;

	DevicememHistoryLock();

	/* if the search is constrained to a particular PID then we
	 * first search the list of allocations to see if this
	 * PID is known to us
	 */
	if (psQueryIn->uiPID != DEVICEMEM_HISTORY_PID_ANY)
	{
		IMG_UINT32 ui32Alloc;
		ui32Alloc = gsDevicememHistoryData.sRecords.ui32AllocationsListHead;

		while (ui32Alloc != END_OF_LIST)
		{
			RECORD_ALLOCATION *psAlloc;

			psAlloc = ALLOC_INDEX_TO_PTR(ui32Alloc);

			if (psAlloc->uiPID == psQueryIn->uiPID)
			{
				goto found_pid;
			}

			if (ui32Alloc == gsDevicememHistoryData.sRecords.ui32AllocationsListHead)
			{
				/* gone through whole list */
				break;
			}
		}

		/* PID not found, so we do not have any suitable data for this
		 * page fault
		 */
		goto out_unlock;
	}

found_pid:

	CircularBufferIterateStart(&ui32Head, &ui32Iter);

	while (!bLast)
	{
		psCommand = CircularBufferIteratePrevious(ui32Head, &ui32Iter, &eType, &bLast);

		if (eType == COMMAND_TYPE_TIMESTAMP)
		{
			ui64TimeNs = TimeStampUnpack(&psCommand->u.sTimeStamp);
			continue;
		}

		if ((eType == COMMAND_TYPE_MAP_ALL) ||
			(eType == COMMAND_TYPE_UNMAP_ALL) ||
			(eType == COMMAND_TYPE_MAP_RANGE) ||
			(eType == COMMAND_TYPE_UNMAP_RANGE))
		{
			RECORD_ALLOCATION *psAlloc;
			IMG_DEV_VIRTADDR sAllocStartAddrOrig, sAllocEndAddrOrig;
			IMG_DEV_VIRTADDR sAllocStartAddr, sAllocEndAddr;
			IMG_BOOL bMap;
			IMG_UINT32 ui32AllocIndex;

			MapUnmapCommandGetInfo(psCommand,
							eType,
							&sAllocStartAddrOrig,
							&sAllocEndAddrOrig,
							&bMap,
							&ui32AllocIndex);

			sAllocStartAddr = sAllocStartAddrOrig;
			sAllocEndAddr = sAllocEndAddrOrig;

			psAlloc = ALLOC_INDEX_TO_PTR(ui32AllocIndex);

			/* skip this command if we need to search within
			 * a particular PID, and this allocation is not from
			 * that PID
			 */
			if ((psQueryIn->uiPID != DEVICEMEM_HISTORY_PID_ANY) &&
				(psAlloc->uiPID != psQueryIn->uiPID))
			{
				continue;
			}

			/* if the allocation was created after this event, then this
			 * event must be for an old/removed allocation, so skip it
			 */
			if (DO_TIME_STAMP_MASK(psAlloc->ui64CreationTime) > ui64TimeNs)
			{
				continue;
			}

			/* if the caller wants us to match any allocation in the
			 * same page as the allocation then tweak the real start/end
			 * addresses of the allocation here
			 */
			if (bMatchAnyAllocInPage)
			{
				sAllocStartAddr.uiAddr = sAllocStartAddr.uiAddr & ~(IMG_UINT64) (ui32PageSizeBytes - 1);
				sAllocEndAddr.uiAddr = (sAllocEndAddr.uiAddr + ui32PageSizeBytes - 1) & ~(IMG_UINT64) (ui32PageSizeBytes - 1);
			}

			if ((psQueryIn->sDevVAddr.uiAddr >= sAllocStartAddr.uiAddr) &&
				(psQueryIn->sDevVAddr.uiAddr <  sAllocEndAddr.uiAddr))
			{
				DEVICEMEM_HISTORY_QUERY_OUT_RESULT *psResult = &psQueryOut->sResults[psQueryOut->ui32NumResults];

				OSStringLCopy(psResult->szString, psAlloc->szName, sizeof(psResult->szString));
				psResult->sBaseDevVAddr = psAlloc->sDevVAddr;
				psResult->uiSize = psAlloc->uiSize;
				psResult->bMap = bMap;
				psResult->ui64Age = _CalculateAge(ui64StartTime, ui64TimeNs, TIME_STAMP_MASK);
				psResult->ui64When = ui64TimeNs;
				/* write the responsible PID in the placeholder */
				psResult->sProcessInfo.uiPID = psAlloc->uiPID;

				if ((eType == COMMAND_TYPE_MAP_ALL) || (eType == COMMAND_TYPE_UNMAP_ALL))
				{
					psResult->bRange = IMG_FALSE;
					psResult->bAll = IMG_TRUE;
				}
				else
				{
					psResult->bRange = IMG_TRUE;
					MapRangeUnpack(&psCommand->u.sMapRange,
										&psResult->ui32StartPage,
										&psResult->ui32PageCount);
					psResult->bAll = (psResult->ui32PageCount * (1U << psAlloc->ui32Log2PageSize))
											== psAlloc->uiSize;
					psResult->sMapStartAddr = sAllocStartAddrOrig;
					psResult->sMapEndAddr = sAllocEndAddrOrig;
				}

				psQueryOut->ui32NumResults++;

				if (psQueryOut->ui32NumResults == DEVICEMEM_HISTORY_QUERY_OUT_MAX_RESULTS)
				{
					break;
				}
			}
		}
	}

out_unlock:
	DevicememHistoryUnlock();

	return psQueryOut->ui32NumResults > 0;
}

static void DeviceMemHistoryFmt(IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN],
							IMG_PID uiPID,
							const IMG_CHAR *pszName,
							const IMG_CHAR *pszAction,
							IMG_DEV_VIRTADDR sDevVAddrStart,
							IMG_DEV_VIRTADDR sDevVAddrEnd,
							IMG_UINT64 ui64TimeNs)
{

	OSSNPrintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN,
				/* PID NAME MAP/UNMAP MIN-MAX SIZE AbsUS AgeUS*/
				"%04u %-40s %-10s "
				IMG_DEV_VIRTADDR_FMTSPEC "-" IMG_DEV_VIRTADDR_FMTSPEC " "
				"0x%08" IMG_UINT64_FMTSPECX
				"%013" IMG_UINT64_FMTSPEC, /* 13 digits is over 2 hours of ns */
				uiPID,
				pszName,
				pszAction,
				sDevVAddrStart.uiAddr,
				sDevVAddrEnd.uiAddr,
				sDevVAddrEnd.uiAddr - sDevVAddrStart.uiAddr,
				ui64TimeNs);
}

static void DeviceMemHistoryFmtHeader(IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN])
{
	OSSNPrintf(szBuffer, PVR_MAX_DEBUG_MESSAGE_LEN,
				"%-4s %-40s %-6s   %10s   %10s   %8s %13s",
				"PID",
				"NAME",
				"ACTION",
				"ADDR MIN",
				"ADDR MAX",
				"SIZE",
				"ABS NS");
}

static const char *CommandTypeToString(COMMAND_TYPE eType)
{
	switch (eType)
	{
		case COMMAND_TYPE_MAP_ALL:
			return "MapAll";
		case COMMAND_TYPE_UNMAP_ALL:
			return "UnmapAll";
		case COMMAND_TYPE_MAP_RANGE:
			return "MapRange";
		case COMMAND_TYPE_UNMAP_RANGE:
			return "UnmapRange";
		case COMMAND_TYPE_TIMESTAMP:
			return "TimeStamp";
		default:
			return "???";
	}
}

static void DevicememHistoryPrintAll(void *pvFilePtr, OS_STATS_PRINTF_FUNC* pfnOSStatsPrintf)
{
	IMG_CHAR szBuffer[PVR_MAX_DEBUG_MESSAGE_LEN];
	IMG_UINT32 ui32Iter;
	IMG_UINT32 ui32Head;
	IMG_BOOL bLast = IMG_FALSE;
	IMG_UINT64 ui64TimeNs = 0;
	IMG_UINT64 ui64StartTime = OSClockns64();

	DeviceMemHistoryFmtHeader(szBuffer);
	pfnOSStatsPrintf(pvFilePtr, "%s\n", szBuffer);

	CircularBufferIterateStart(&ui32Head, &ui32Iter);

	while (!bLast)
	{
		COMMAND_WRAPPER *psCommand;
		COMMAND_TYPE eType = COMMAND_TYPE_NONE;

		psCommand = CircularBufferIteratePrevious(ui32Head, &ui32Iter, &eType, &bLast);

		if (eType == COMMAND_TYPE_TIMESTAMP)
		{
			ui64TimeNs = TimeStampUnpack(&psCommand->u.sTimeStamp);
			continue;
		}


		if ((eType == COMMAND_TYPE_MAP_ALL) ||
			(eType == COMMAND_TYPE_UNMAP_ALL) ||
			(eType == COMMAND_TYPE_MAP_RANGE) ||
			(eType == COMMAND_TYPE_UNMAP_RANGE))
		{
			RECORD_ALLOCATION *psAlloc;
			IMG_DEV_VIRTADDR sDevVAddrStart, sDevVAddrEnd;
			IMG_BOOL bMap;
			IMG_UINT32 ui32AllocIndex;

			MapUnmapCommandGetInfo(psCommand,
								eType,
								&sDevVAddrStart,
								&sDevVAddrEnd,
								&bMap,
								&ui32AllocIndex);

			psAlloc = ALLOC_INDEX_TO_PTR(ui32AllocIndex);

			if (DO_TIME_STAMP_MASK(psAlloc->ui64CreationTime) > ui64TimeNs)
			{
				/* if this event relates to an allocation we
				 * are no longer tracking then do not print it
				 */
				continue;
			}

			DeviceMemHistoryFmt(szBuffer,
								psAlloc->uiPID,
								psAlloc->szName,
								CommandTypeToString(eType),
								sDevVAddrStart,
								sDevVAddrEnd,
								ui64TimeNs);

			pfnOSStatsPrintf(pvFilePtr, "%s\n", szBuffer);
		}
	}

	pfnOSStatsPrintf(pvFilePtr, "\nTimestamp reference: %013" IMG_UINT64_FMTSPEC "\n", ui64StartTime);
}

static void DevicememHistoryPrintAllWrapper(void *pvFilePtr, void *pvData, OS_STATS_PRINTF_FUNC* pfnOSStatsPrintf)
{
	PVR_UNREFERENCED_PARAMETER(pvData);
	DevicememHistoryLock();
	DevicememHistoryPrintAll(pvFilePtr, pfnOSStatsPrintf);
	DevicememHistoryUnlock();
}

static PVRSRV_ERROR CreateRecords(void)
{
	gsDevicememHistoryData.sRecords.pasAllocations =
			OSAllocMem(sizeof(RECORD_ALLOCATION) * ALLOCATION_LIST_NUM_ENTRIES);

	if (gsDevicememHistoryData.sRecords.pasAllocations == NULL)
	{
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	/* Allocated and initialise the circular buffer with zeros so every
	 * command is initialised as a command of type COMMAND_TYPE_NONE. */
	gsDevicememHistoryData.sRecords.pasCircularBuffer =
			OSAllocZMem(sizeof(COMMAND_WRAPPER) * CIRCULAR_BUFFER_NUM_COMMANDS);

	if (gsDevicememHistoryData.sRecords.pasCircularBuffer == NULL)
	{
		OSFreeMem(gsDevicememHistoryData.sRecords.pasAllocations);
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	return PVRSRV_OK;
}

static void DestroyRecords(void)
{
	OSFreeMem(gsDevicememHistoryData.sRecords.pasCircularBuffer);
	OSFreeMem(gsDevicememHistoryData.sRecords.pasAllocations);
}

static void InitialiseRecords(void)
{
	IMG_UINT32 i;

	/* initialise the allocations list */

	gsDevicememHistoryData.sRecords.pasAllocations[0].ui32Prev = ALLOCATION_LIST_NUM_ENTRIES - 1;
	gsDevicememHistoryData.sRecords.pasAllocations[0].ui32Next = 1;

	for (i = 1; i < ALLOCATION_LIST_NUM_ENTRIES; i++)
	{
		gsDevicememHistoryData.sRecords.pasAllocations[i].ui32Prev = i - 1;
		gsDevicememHistoryData.sRecords.pasAllocations[i].ui32Next = i + 1;
	}

	gsDevicememHistoryData.sRecords.pasAllocations[ALLOCATION_LIST_NUM_ENTRIES - 1].ui32Next = 0;

	gsDevicememHistoryData.sRecords.ui32AllocationsListHead = 0;
}

PVRSRV_ERROR DevicememHistoryInitKM(void)
{
	PVRSRV_ERROR eError;

	eError = OSLockCreate(&gsDevicememHistoryData.hLock);

	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "DevicememHistoryInitKM: Failed to create lock"));
		goto err_lock;
	}

	eError = CreateRecords();

	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "DevicememHistoryInitKM: Failed to create records"));
		goto err_allocations;
	}

	InitialiseRecords();

	gsDevicememHistoryData.pvStatsEntry = OSCreateStatisticEntry("devicemem_history",
						NULL,
						DevicememHistoryPrintAllWrapper,
						NULL);

	return PVRSRV_OK;

err_allocations:
	OSLockDestroy(gsDevicememHistoryData.hLock);
err_lock:
	return eError;
}

void DevicememHistoryDeInitKM(void)
{
	if (gsDevicememHistoryData.pvStatsEntry != NULL)
	{
		OSRemoveStatisticEntry(&gsDevicememHistoryData.pvStatsEntry);
	}

	DestroyRecords();

	OSLockDestroy(gsDevicememHistoryData.hLock);
}


