kernel/eka/memmodel/epoc/flexible/mmu/mm.h
changeset 0 a41df078684a
child 87 2f92ad2dc5db
child 121 661475905584
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mm.h	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,1187 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#ifndef MM_H
+#define MM_H
+
+#include <mmtypes.h>
+#include <platform.h>
+
+
+class DMemoryObject;
+class DMemoryMapping;
+class DMemModelThread;
+class DPhysicalPinMapping;
+
+/**
+Memory object types for MM::MemoryNew which indicates how the
+contents of a memory object are to be managed.
+*/
+enum TMemoryObjectType
+	{
+	/**
+	Memory object for containing memory mapped hardware devices or special
+	purpose memory for which the physical addresses are fixed. The contents of
+	these type of objects are manipulated with the functions:
+	- MM::MemoryAddPages
+	- MM::MemoryAddContiguous
+	- MM::MemoryRemovePages
+	*/
+	EMemoryObjectHardware				= 0,
+
+	/**
+	Memory object containing normal program memory (RAM) which is allocated from a
+	system wide pool. The contents of these type of objects are manipulated with
+	the functions:
+	- MM::MemoryAlloc
+	- MM::MemoryAllocContiguous
+	- MM::MemoryFree
+	*/
+	EMemoryObjectUnpaged				= 1,
+
+	/**
+	Memory object containing normal program memory (RAM) which is allocated from a
+	system wide pool. This is the same basic management as EMemoryObjectUnpaged however
+	RAM defragmentation activity may substituted physical RAM pages with others and
+	this process may cause transient page faults which make this memory not suitable
+	for most kernel-side usage.
+
+	The contents of these type of objects are manipulated with the functions:
+	- MM::MemoryAlloc
+	- MM::MemoryAllocContiguous
+	- MM::MemoryFree
+	*/
+	EMemoryObjectMovable				= 2,
+
+	/**
+	Memory object containing normal program memory (RAM) which is demand paged
+	from a backing store. The contents of these type of objects are manipulated
+	with the functions.
+	- MM::MemoryAlloc
+	- MM::MemoryFree
+	*/
+	EMemoryObjectPaged					= 3,
+
+	/**
+	Memory object containing normal program memory (RAM) in the same way as
+	EMemoryObjectMovable but with the additional option of marking pages as
+	'discardable'. Discardable pages may be reclaimed (remove) by the system at
+	any time, this state is controlled using the functions:
+	- MM::MemoryAllowDiscard
+	- MM::MemoryDisallowDiscard
+	*/
+	EMemoryObjectDiscardable			= 4
+	};
+
+
+/**
+Bitmask of flags to specify options to MM:MemoryNew.
+*/
+enum TMemoryCreateFlags
+	{
+	/**
+	Default value which has all flags false.
+	*/
+	EMemoryCreateDefault				= 0,
+
+	/**
+	Memory allocated for the memory object contents does not need wiping.
+	IMPORTANT, memory is normally wiped for security purposes, this attribute
+	should only be used when the old contents of any memory allocated can not
+	be read by any process without TCB capability.
+	*/
+	EMemoryCreateNoWipe					= 1<<0,
+
+	/**
+	Use the custom wipe byte value when wiping memory, rather than the default value.
+	@see EMemoryCreateUseCustomWipeByte
+	*/
+	EMemoryCreateUseCustomWipeByte		= 1<<1,
+
+	/**
+	Pre-create all resources the memory object needs so that operations on it
+	can not fail due to low memory conditions. This excludes any explicit
+	allocation of memory pages for use as the objects contents.
+	*/
+	EMemoryCreateReserveAllResources	= 1<<2,
+
+	/**
+	Memory object contents are not allowed to be pinned.
+	*/
+	EMemoryCreateDisallowPinning		= 1<<3,
+
+	/**
+	Memory object contents are read-only. Mappings with write permissions are
+	not allowed.
+	*/
+	EMemoryCreateReadOnly				= 1<<4,
+
+	/**
+	Memory object contents may be executed. Mappings with execute permissions
+	are allowed.
+	*/
+	EMemoryCreateAllowExecution			= 1<<5,
+
+	/**
+	Bit position for the least significant bit of an 8 bit value to use for
+	wiping newly allocated memory.
+	@see EMemoryCreateUseCustomWipeByte
+	@see EMemoryCreateNoWipe
+	*/
+	EMemoryCreateWipeByteShift			= 8,
+
+	// for selected internal use only...
+
+	/**
+	The TMemoryObjectType specified is actually a pointer to the DMemoryManager to use.
+	*/
+	EMemoryCreateCustomManager			= 1<<30,
+
+	/**
+	Memory object contents are to be demand paged. 
+	*/
+	EMemoryCreateDemandPaged			= 1<<31
+	};
+
+
+/**
+Attributes that the memory in a memory object has.
+
+These govern how the MMU and caching systems treat the memory. The following
+terms have meanings as specified in the ARM Architecture Reference Manual - see
+the section 'Memory types and attributes and the Memory order model'.
+
+- Memory types 'normal', 'device' and 'strongly-ordered'.
+- 'Shareable' attribute.
+*/
+enum TMemoryAttributes
+	{
+	// memory types (copy of TMemoryType)...
+
+	EMemoryAttributeStronglyOrdered 	= EMemAttStronglyOrdered,
+	EMemoryAttributeDevice 				= EMemAttDevice,
+	EMemoryAttributeNormalUncached 		= EMemAttNormalUncached,
+	EMemoryAttributeNormalCached 		= EMemAttNormalCached,
+	EMemoryAttributeKernelInternal4 	= EMemAttKernelInternal4,
+	EMemoryAttributePlatformSpecific5 	= EMemAttPlatformSpecific5,
+	EMemoryAttributePlatformSpecific6	= EMemAttPlatformSpecific6,
+	EMemoryAttributePlatformSpecific7	= EMemAttPlatformSpecific7,
+
+	/**
+	Bitmask to extract TMemoryType value from this enum. E.g.
+	@code
+	TMemoryAttributes attr;
+	TMemoryType type = (TMemoryType)(attr&EMemoryAttributeTypeMask);
+	@endcode
+	*/
+	EMemoryAttributeTypeMask			= KMemoryTypeMask,
+
+	/**
+	Set if memory is Shareable.
+	*/
+	EMemoryAttributeShareable			= 0x08,
+
+	/**
+	Legacy (and little-used/unused?) ARM attribute.
+	*/
+	EMemoryAttributeUseECC				= 0x10,
+
+
+	/**
+	Number of bits required to store memory attribute value.
+	@internalComponent
+	*/
+	EMemoryAttributeShift				= 5,
+
+	/**
+	Bitmask for all significant attribute bits.
+	@internalComponent
+	*/
+	EMemoryAttributeMask				= (1<<EMemoryAttributeShift)-1,
+
+	// pseudo attributes...
+
+	/**
+	Indicates the Shareable attribute should be the default value for the system.
+	See macro __CPU_USE_SHARED_MEMORY
+	*/
+	EMemoryAttributeDefaultShareable	= 0x80000000,
+
+	// popular combinations...
+
+	/**
+	Normal program memory for use by software.
+	*/
+	EMemoryAttributeStandard			= EMemoryAttributeNormalCached|EMemoryAttributeDefaultShareable
+	};
+
+
+/**
+Access permissions applied to Memory Mappings.
+*/
+enum TMappingPermissions
+	{
+	EUser	    = 1<<0, ///< Unprivileged (user mode) access allowed.
+	EReadWrite  = 1<<1, ///< Memory contents may be modified
+	EExecute	= 1<<2, ///< Memory contents may be executed as code.
+
+	// popular combinations...
+	EUserReadOnly = EUser,
+	EUserReadWrite = EUser|EReadWrite,
+	EUserExecute = EUser|EExecute,
+	ESupervisorReadOnly = 0,
+	ESupervisorReadWrite = EReadWrite,
+	ESupervisorExecute = EExecute
+	};
+
+
+/**
+Bitmask of flags to specify options to MM::MappingNew.
+*/
+enum TMappingCreateFlags
+	{
+	/**
+	Default value which has all flags false.
+	*/
+	EMappingCreateDefault				= 0,
+
+	/**
+	Allocate the specified virtual address.
+	*/
+	EMappingCreateExactVirtual			= 1<<0,
+
+	/**
+	Pre-create all resources (like page tables) that the memory mapping
+	needs so that operations on it can not fail due to low memory conditions.
+	*/
+	EMappingCreateReserveAllResources	= 1<<1,
+
+	// for selected internal use only...
+
+	/**
+	Flag memory as being demand paged.
+	Exclusive with EMappingCreatePinning and EMappingCreateReserveAllResources.
+	@internalTechnology
+	*/
+	EMappingCreateDemandPaged			= 1<<27,
+
+	/**
+	Flag memory as requiring a common address across all address spaces, also
+	implies EMappingCreateExactVirtual.
+	@internalTechnology
+	*/
+	EMappingCreateCommonVirtual			= 1<<28,
+
+	/**
+	Allocate virtual address in the global region which it to be used for
+	user-mode access. (KGlobalMemoryBase<=address<KUserMemoryLimit).
+	@internalTechnology
+	*/
+	EMappingCreateUserGlobalVirtual		= 1<<29,
+
+	/**
+	Don't allocate any virtual memory in the address space, use the specified
+	address and assume ownership of this.
+	@internalTechnology
+	*/
+	EMappingCreateAdoptVirtual			= 1<<30,
+
+	/**
+	Don't allocate any virtual memory in the address space, just used the
+	specified address.
+	@internalTechnology
+	*/
+	EMappingCreateFixedVirtual	= 1<<31
+	};
+
+
+class DMemModelChunk;
+class TPagedCodeInfo;
+
+/**
+Static interface to the Flexible Memory Model implementation
+for use by the Symbian OS aware part of the memory model codebase.
+*/
+class MM
+	{
+public:
+	//
+	// Memory Object functions
+	//
+
+	/**
+	Create a new memory object.
+
+	A memory object is a sparse array of memory pages to which memory mappings
+	may be attached. All pages in the array are managed using the same methods
+	(see TMemoryObjectType) and have the same attributes (see TMemoryAttributes).
+
+	On creation it contains no pages.
+
+	@param[out] aMemory	Pointer reference which on success is set to the address
+						of the created memory object.
+	@param aType		Value from TMemoryObjectType which indicates how the
+						contents of the memory object are to be managed.
+	@param aPageCount	Size of the memory object, in number of pages.
+	@param aCreateFlags	Bitmask of option flags from enum TMemoryCreateFlags.
+	@param aAttributes	Bitmask of values from enum TMemoryAttributes.
+
+	@return KErrNone, if successful;
+			otherwise another of the system wide error codes.
+	*/
+	static TInt MemoryNew(DMemoryObject*& aMemory, TMemoryObjectType aType, TUint aPageCount, TMemoryCreateFlags aCreateFlags=EMemoryCreateDefault, TMemoryAttributes aAttributes=EMemoryAttributeStandard);
+
+	/**
+	Assign a mutex which will be used to serialise explicit modifications to the
+	specified memory object.
+
+	If a lock hasn't been specified for a particular object, it will make use of
+	one allocated dynamically allocated from a shared pool; this mutex will be of 'order'
+	#KMutexOrdMemoryObject.
+
+	@see MemoryObjectLock.
+	*/
+	static void MemorySetLock(DMemoryObject* aMemory, DMutex* aLock);
+
+	/**
+	Wait on the specified memory object's lock mutex.
+	*/
+	static void MemoryLock(DMemoryObject* aMemory);
+
+	/**
+	Signal the specified memory object's lock mutex.
+	*/
+	static void MemoryUnlock(DMemoryObject* aMemory);
+
+	/**
+	Remove all memory from a memory object and close a reference on it.
+
+	If there are no longer any mappings to the memory, or other references,
+	this will result in the memory object being destroyed. However whilst
+	other references exist, cleanup of memory and other resources may be
+	delayed indefinitely.
+
+	This function acquires and releases the memory objects lock.
+	See MM::MemorySetLock.
+
+	@param aMemory	Pointer reference to memory object to be destroyed.
+					On return from the function this is set to the null-pointer.
+					No action is performed if the reference was already the
+					null-pointer on entry to this function.
+	*/
+	static void MemoryDestroy(DMemoryObject*& aMemory);
+
+	/**
+	Allocate memory for a specified region within a memory object.
+	Memory is allocated as appropriate for the object type, e.g.
+	For Unpaged objects, from the system RAM pool; for Paged objects, in the
+	backing store.
+
+	This function acquires and releases the memory objects lock.
+	See MM::MemorySetLock.
+
+	Supported for memory object types:
+	- EMemoryObjectUnpaged
+	- EMemoryObjectMovable
+	- EMemoryObjectPaged
+	- EMemoryObjectDiscardable
+
+	@param aMemory	The memory object.
+	@param aIndex	Page index for start of the region.
+	@param aCount	Number of pages in the region.
+
+	@return KErrNone, if successful;
+			KErrAlreadyExists, if any part of the region was already allocated;
+			KErrArgument, if the region exceeds the bounds of the memory object;
+			KErrNotSupported, if the memory object doesn't support this operation;
+			otherwise another of the system wide error codes.
+	*/
+	static TInt MemoryAlloc(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
+
+	/**
+	Allocate memory for a specified region within a memory object.
+	The allocated memory will have contiguous physical addresses.
+
+	This function acquires and releases the memory objects lock.
+	See MM::MemorySetLock.
+
+	Important note, this function can unexpectedly fail with KErrAlreadyExists
+	if any part of the the region previously contained allocated memory which
+	had been freed but which was pinned. It is therefore not suitable for general
+	use.
+
+	Supported for memory object types:
+	- EMemoryObjectUnpaged
+	- EMemoryObjectDiscardable
+
+	@param aMemory	The memory object.
+	@param aIndex	Page index for start of the region.
+	@param aCount	Number of pages in the region.
+	@param aAlign	Log2 of the alignment (in bytes) that the address of the allocated physical RAM must have.
+	@param[out] aPhysAddr	On success, this is set to the start address of the allocated physical RAM.
+
+	@return KErrNone, if successful;
+			KErrAlreadyExists, if any part of the region was already allocated;
+			KErrArgument, if the region exceeds the bounds of the memory object;
+			KErrNotSupported, if the memory object doesn't support this operation;
+			otherwise another of the system wide error codes.
+	*/
+	static TInt MemoryAllocContiguous(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TUint aAlign, TPhysAddr& aPhysAddr);
+
+	/**
+	Free (unallocate) memory for a specified region within a memory object.
+	This is the inverse operation to MemoryAlloc and MemoryAllocContiguous.
+
+	This function acquires and releases the memory objects lock.
+	See MM::MemorySetLock.
+
+	Supported for memory object types:
+	- EMemoryObjectUnpaged
+	- EMemoryObjectMovable
+	- EMemoryObjectPaged
+	- EMemoryObjectDiscardable
+
+	@param aMemory	The memory object.
+	@param aIndex	Page index for start of the region.
+	@param aCount	Number of pages in the region.
+	*/
+	static void MemoryFree(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
+
+	/**
+	Add the specified pages to a region in a memory object.
+
+	This function acquires and releases the memory objects lock.
+	See MM::MemorySetLock.
+
+	Supported for memory object types:
+	- EMemoryObjectHardware
+
+	@param aMemory	The memory object.
+	@param aIndex	Page index for start of the region.
+	@param aCount	Number of pages in the region.
+	@param aPages	Pointer to array of pages to add. This must contain \a aCount
+					number of physical page addresses which are page aligned.
+
+	@return KErrNone, if successful;
+			KErrAlreadyExists, if any part of the region already contains pages;
+			KErrArgument, if the region exceeds the bounds of the memory object;
+			KErrNotSupported, if the memory object doesn't support this operation;
+			otherwise another of the system wide error codes.
+	*/
+	static TInt MemoryAddPages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages);
+
+	/**
+	Add a contiguous range of pages to a region in a memory object.
+
+	This function acquires and releases the memory objects lock.
+	See MM::MemorySetLock.
+
+	Supported for memory object types:
+	- EMemoryObjectHardware
+
+	@param aMemory		The memory object.
+	@param aIndex		Page index for start of the region.
+	@param aCount		Number of pages in the region.
+	@param aPhysAddr	The page aligned start address of the pages to be added.
+
+	@return KErrNone, if successful;
+			KErrAlreadyExists, if any part of the region already contains pages;
+			KErrArgument, if the region exceeds the bounds of the memory object;
+			KErrNotSupported, if the memory object doesn't support this operation;
+			otherwise another of the system wide error codes.
+	*/
+	static TInt MemoryAddContiguous(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr aPhysAddr);
+
+	/**
+	Remove pages from a region in a memory object.
+
+	This is the inverse operation to MemoryAdd and MemoryAddContiguous.
+
+	This function acquires and releases the memory objects lock.
+	See MM::MemorySetLock.
+
+	Supported for memory object types:
+	- EMemoryObjectHardware
+
+	@param aMemory		The memory object.
+	@param aIndex		Page index for start of the region.
+	@param aCount		Number of pages in the region.
+	@param[out] aPages	Pointer to an array of physical addresses which has a
+						length of \a aCount. The contents of this will be set to
+						the addresses of the pages which were removed by this
+						function. The number of valid entries in this array is
+						given by the return value of this function.
+						aPages may be the null-pointer, to indicate that these
+						page addresses aren't required by the caller.
+
+	@return The number of pages successfully removed from the memory object.
+			This gives the number of valid entries in the array \a aPages and is
+			less-than or equal to \a aCount.
+	*/
+	static TUint MemoryRemovePages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages);
+
+	/**
+	Mark a region in a memory object as discardable.
+
+	The system may remove discardable pages from the memory object at any time,
+	to be reused for other purposes.
+
+	This function acquires and releases the memory objects lock.
+	See MM::MemorySetLock.
+
+	Supported for memory object types:
+	- EMemoryObjectDiscardable
+
+	@see MemoryDisallowDiscard
+
+	@param aMemory	The memory object.
+	@param aIndex	Page index for start of the region.
+	@param aCount	Number of pages in the region.
+
+	@return KErrNone, if successful;
+			KErrNotSupported, if the memory object doesn't support this operation;
+			otherwise another of the system wide error codes.
+
+	*/
+	static TInt MemoryAllowDiscard(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
+
+	/**
+	Mark a region in a memory object as no longer discardable.
+	This undoes the operation of MemoryAllowDiscard.
+
+	If any pages in the region are no longer present, then the operation will
+	fail with KErrNotFound. In this case, the state of the pages in the region
+	is indeterminate; they may be either still discardable, not discardable, or
+	not present.
+
+	Supported for memory object types:
+	- EMemoryObjectDiscardable
+
+	@see MemoryAllowDiscard
+
+	@param aMemory	The memory object.
+	@param aIndex	Page index for start of the region.
+	@param aCount	Number of pages in the region.
+
+	@return KErrNone, if successful;
+			KErrNotFound, if any page in the region was no longer present;
+			KErrNotSupported, if the memory object doesn't support this operation;
+			otherwise another of the system wide error codes.
+	*/
+	static TInt MemoryDisallowDiscard(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
+
+	/**
+	This function only exists to support DMemModelChunk::PhysicalAddress and may be removed.
+	DO NOT USE.
+	*/
+	static TInt MemoryPhysAddr(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr& aPhysicalAddress, TPhysAddr* aPhysicalPageList);
+
+	/**
+	Prime BTrace for a memory object - internal use only.
+	*/
+	static void MemoryBTracePrime(DMemoryObject* aMemory);
+
+	/**
+	Close a memory object.
+
+	This should be called on the memory object returned by #MappingGetAndOpenMemory.
+	*/
+	static void MemoryClose(DMemoryObject* aMemory);
+
+	/**
+	Return true if aMemory has any mappings associated with it.
+	*/
+	static TBool MemoryIsNotMapped(DMemoryObject* aMemory);
+
+	/**
+	Wipe the entire memory contents of the memory object so they are in the
+	same state as if the memory had been newly allocated with #MemoryAlloc.
+
+	This is useful for situations where a memory object is being re-purposed and
+	confidentiality requires that the old memory contents are not disclosed.
+	For this reason, the function asserts that the memory object has no mappings.
+
+	@see EMemoryCreateUseCustomWipeByte
+	@see EMemoryCreateNoWipe
+
+	@return KErrNone, if successful;
+			otherwise KErrNotSupported, to indicate the memory object doesn't support this operation.
+	*/
+	static TInt MemoryWipe(DMemoryObject* aMemory);
+
+	/**
+	Set the memory object to be read only, i.e. to no longer allow writable mappings.
+
+	NOTE - This can't be undone, page moving will break if a memory object is made 
+	writable again.
+
+	@param aMemory	The memory object to update.
+	@return KErrNone on success, KErrInUse if the memory object has writable mappings
+			KErrNotSupported if the objects manager doesn't support this.
+	*/
+	static TInt MemorySetReadOnly(DMemoryObject* aMemory);
+
+	/**
+	Pins physical memory associated with the memory object and returns the physical
+	memory characteristics, e.g. address, map attributes and colour
+
+	@param aMemory	        The memory object.
+	@param aPinObject	    The physical pin mapping.
+	@param aIndex	        Page index for start of the region.
+	@param aCount   	    Number of pages in the region.
+	@param aReadOnly   	    Indicates whether memory should be pinned as read only.
+	@param aAddress[out]	The value is the physical address of the first page
+						    in the region.
+	@param aPages[out]      If not zero, this points to an array of TPhysAddr
+	                        objects. On success, this array will be filled
+						    with the addresses of the physical pages which
+						    contain the specified region. If aPages is
+						    zero, then the function will fail with
+						    KErrNotFound if the specified region is not
+						    physically contiguous.
+	@param aMapAttr[out]    Memory attributes defined by TMappingAttributes2.
+	@param aColour[out]     The mapping colour of the first physical page.
+
+
+	@return The number of pages successfully removed from the memory object.
+			This gives the number of entries in the array aPages and is
+			less-than or equal to aCount.
+	*/
+
+	static TInt PinPhysicalMemory(DMemoryObject* aMemory, DPhysicalPinMapping* aPinObject, TUint aIndex,
+								  TUint aCount, TBool aReadOnly, TPhysAddr& aAddress, TPhysAddr* aPages,
+								  TUint32& aMapAttr, TUint& aColour);
+
+	//
+	// Memory Mapping functions
+	//
+
+	/**
+	Create a new memory mapping for a specific memory object.
+
+	A memory mapping represents the MMU resources required to make a region of a
+	memory object accessible to software within a single address space (process).
+	Each mapping has an associated set of access permissions (see
+	#TMappingPermissions).
+
+	@param[out] aMapping Pointer reference which on success is set to the address
+						of the created memory mapping.
+	@param aMemory		The memory object with which the mapping is associated.
+	@param aPermissions	Bitmask of values from enum #TMappingPermissions which
+						give the access permissions for this mapping.
+	@param aOsAsid		The identifier for the address space in which this
+						mapping is to appear.
+	@param aFlags		Bitmask of option flags from enum #TMappingCreateFlags
+	@param aAddr		Optional virtual address at which the memory mapped
+						by this mapping is to appear within the specified
+						address space.
+	@param aIndex		Optional start page index within \a aMemory for this
+						mapping.
+	@param aCount		Optional page count for size of mapping. A value of
+						the maximum integer indicates that the mapping is to
+						extend to the end of the memory object.
+
+	@return KErrNone, if successful;
+			otherwise another of the system wide error codes.
+	*/
+	static TInt MappingNew(DMemoryMapping*& aMapping, DMemoryObject* aMemory, TMappingPermissions aPermissions, TInt aOsAsid, TMappingCreateFlags aFlags=EMappingCreateDefault, TLinAddr aAddr=0, TUint aIndex=0, TUint aCount=~0u);
+
+	/**
+	Create a new memory mapping with is not associated with any memory object.
+
+	This mapping may be used and reused with different memory objects by using
+	the #MappingMap and #MappingUnmap methods.
+
+	@param[out] aMapping	Pointer reference which on success is set to the address
+							of the created memory mapping.
+	@param aCount			Page count for size of mapping.
+	@param aOsAsid			The identifier for the address space in which this
+							mapping is to appear.
+	@param aFlags			Bitmask of option flags from enum #TMappingCreateFlags
+	@param aAddr			Optional virtual address at which the mapping is to
+							appear within the specified address space.
+	@param aColourOffset	The byte offset within a memory object's memory which this mapping
+							is to start. This is used to adjust virtual memory allocation to
+							meet page colouring restrictions. If this value is not known leave
+							this argument unspecified; however, it must be specified if \a aAddr
+							is specified.
+
+	@return KErrNone, if successful;
+			otherwise another of the system wide error codes.
+	*/
+	static TInt MappingNew(DMemoryMapping*& aMapping, TUint aCount, TInt aOsAsid, TMappingCreateFlags aFlags=EMappingCreateDefault, TLinAddr aAddr=0, TLinAddr aColourOffset=~0);
+
+	/**
+	Apply a memory mapping to a memory object.
+
+	@param aMapping		The memory mapping to be used to map \a aMemory.
+	@param aPermissions	Bitmask of values from enum #TMappingPermissions which
+						give the access permissions for this mapping.
+	@param aMemory		The memory object with which the mapping is to be associated.
+	@param aIndex		Optional start page index within aMemory for this
+						mapping.
+	@param aCount		Optional page count for size of mapping. A value of
+						the maximum integer indicates that the mapping is to
+						extend to the end of the memory object.
+
+	@return KErrNone, if successful;
+			otherwise another of the system wide error codes.
+	*/
+	static TInt MappingMap(DMemoryMapping* aMapping, TMappingPermissions aPermissions, DMemoryObject* aMemory, TUint aIndex=0, TUint aCount=~0u);
+
+	/**
+	Remove a mapping from the memory object with which it is associated.
+	*/
+	static void MappingUnmap(DMemoryMapping* aMapping);
+
+	/**
+	Remove a memory mapping from its associated address space and close a
+	reference on it.
+
+	If there are no longer any other references, this will result in the memory
+	object being destroyed,
+
+	@param aMapping	Pointer reference to memory mapping to be destroyed.
+					On return from the function this is set to the null-pointer.
+					No action is performed if the reference was already the
+					null-pointer on entry to this function.
+	*/
+	static void MappingDestroy(DMemoryMapping*& aMapping);
+
+	/**
+	Remove a memory mapping from its associated address space and close a
+	reference on it.
+
+	The mapping is found based on the virtual address region within which it
+	maps memory. The caller must that such a mapping exists and that it will not
+	be unmapped by another thread.
+
+	@param aAddr	Virtual address which lies within the region covered by the
+					memory mapping.
+	@param aOsAsid	Address space in which the mapping appears.
+	*/
+	static void MappingDestroy(TLinAddr aAddr, TInt aOsAsid);
+
+	/**
+	Perform the action of #MappingDestroy on a memory mapping then #MemoryDestroy
+	on its associated memory object.
+
+	This function acquires and releases the memory objects lock.
+	See MM::MemorySetLock.
+
+	NOTE - This should not be used on mappings that are reused as the mapping's 
+	instance count is not checked.
+
+	@param aMapping	Pointer reference to memory mapping to be destroyed.
+					On return from the function this is set to the null-pointer.
+					No action is performed if the reference was already the
+					null-pointer on entry to this function.
+	*/
+	static void MappingAndMemoryDestroy(DMemoryMapping*& aMapping);
+
+	/**
+	Perform the action of #MappingDestroy on a memory mapping then #MemoryDestroy
+	on its associated memory object.
+
+	The mapping is found based on the virtual address region within which it
+	maps memory. The caller must that such a mapping exists and that it will not
+	be unmapped by another thread.
+
+	This function acquires and releases the memory objects lock.
+	See MM::MemorySetLock.
+
+	NOTE - This should not be used on mappings that are reused as the mapping's 
+	instance count is not checked.
+
+	@param aAddr	Virtual address which lies within the region covered by the
+					memory mapping.
+	@param aOsAsid	Address space in which the mapping appears.
+	*/
+	static void MappingAndMemoryDestroy(TLinAddr aAddr, TInt aOsAsid);
+
+	/**
+	Return the virtual address at which the memory mapped by a memory mapping
+	starts.
+
+	@param aMapping	A memory mapping.
+
+	@return The base address.
+	*/
+	static TLinAddr MappingBase(DMemoryMapping* aMapping);
+
+	/**
+	Return the OS Address Space ID (OS ASID) of the address space the mapping is within.
+
+	@param aMapping	A memory mapping.
+
+	@return OS Address Space ID (OS ASID).
+	*/
+	static TInt MappingOsAsid(DMemoryMapping* aMapping);
+
+	/**
+	Open the memory object mapped by a mapping and return it.
+
+	The memory object can be closed again by calling #MemoryClose.
+
+	NOTE - This should not be used on mappings that are reused as the mapping's 
+	instance count is not checked.
+
+	@param aMapping			A memory mapping.
+
+	@return The memory object, or NULL.
+	*/
+	static DMemoryObject* MappingGetAndOpenMemory(DMemoryMapping* aMapping);
+
+	/**
+	Close a mapping
+
+	@param aMapping	A memory mapping.
+	*/
+	static void MappingClose(DMemoryMapping* aMapping);
+
+	/**
+	Find and open the mapping that maps a virtual address in the address space of the specified
+	thread.
+
+	The caller must close the mapping when it has finished using it.
+
+	@param aThread The thread whose address space is to be searched.
+	@param aAddr The virtual address for which the mapping is to be found.
+	@param aSize The size, in bytes, of the region at aAddr.
+	@param aOffsetInMapping A reference which is set to the offset, in bytes, into the
+							mapping of the start address.
+	@param aInstanceCount	The instance count of the found mapping.
+
+	@return The mapping, or NULL if no mapping was found.
+
+	@pre Calling thread must be in a critical section.
+	*/
+	static DMemoryMapping* FindMappingInThread(	DMemModelThread* aThread, TLinAddr aAddr, TUint aSize, 
+												TUint& aOffsetInMapping, TUint& aInstanceCount);
+
+	/**
+	Find and open the mapping that maps a virtual address in the address space of the specified
+	process.
+
+	The caller must close the mapping when it has finished using it.  The caller must ensure that
+	the process can't be destroyed while calling this method.
+
+	@param aOsAsid The identifier for the address space in which the mapping appears.
+	@param aAddr The virtual address for which the mapping is to be found.
+	@param aSize The size, in bytes, of the region at aAddr.
+	@param aOffsetInMapping A reference which is set to the offset, in bytes, into the
+							mapping of the start address.
+	@param aInstanceCount	The instance count of the found mapping.
+
+	@return The mapping, or NULL if no mapping was found.
+
+	@pre Calling thread must be in a critical section.
+	*/
+	static DMemoryMapping* FindMappingInAddressSpace(	TUint aOsAsid, TLinAddr aAddr, TUint aSize, 
+														TUint& aOffsetInMapping, TUint& aInstanceCount);
+
+
+	//
+	// Conversion utilities
+	//
+
+	/**
+	Round a size in bytes up to the next integer multiple of the page size.
+
+	@param aSize A size in bytes.
+
+	@return The rounded size.
+	*/
+	static TUint RoundToPageSize(TUint aSize);
+
+	/**
+	Round a size in bytes up to the next integer multiple of the page size
+	then convert it into a page count by dividing it by the page size.
+
+	@param aSize A size in bytes.
+
+	@return The rounded page count.
+	*/
+	static TUint RoundToPageCount(TUint aSize);
+
+	/**
+	Round a bit shift value representing the log2 of a size in bytes, up to
+	a shift value representing the log2 of a size in pages.
+
+	@param aShift log2 of a size in bytes.
+
+	@return aShift-KPageShift, or zero if aShift<=KPageShift.
+	*/
+	static TUint RoundToPageShift(TUint aShift);
+
+	/**
+	Convert a size in bytes to a size in pages.
+
+	@param aBytes A size in bytes.
+
+	@return aBytes/KPageSize.
+
+	@panic MemModel #EBadBytesToPages if aBytes is not an integer multiple of
+		   the page size.
+	*/
+	static TUint BytesToPages(TUint aBytes);
+
+	/**
+	Construct a #TMappingPermissions value base on individual permission flags.
+
+	@param aUser	True to allow unprivileged (user mode) access.
+	@param aWrite	True to allow memory contents to be modified.
+	@param aExecute	True to allow memory contents to be executed as code.
+
+	@return Permissions expressed as an #TMappingPermissions value.
+	*/
+	static TMappingPermissions MappingPermissions(TBool aUser, TBool aWrite, TBool aExecute);
+
+	/**
+	Extract the mapping permissions from a TMappingAttributes2
+	(or TMappingAttributes) value.
+
+	@param[out] aPermissions	If successful, mapping permissions extracted from aLegacyAttributes.
+	@param aLegacyAttributes	A legacy combined permission/attribute value.
+
+	@return KErrNone, if successful;
+			otherwise another of the system wide error codes.
+	*/
+	static TInt MappingPermissions(TMappingPermissions& aPermissions, TMappingAttributes2 aLegacyAttributes);
+
+	/**
+	Extract the memory attributes from a TMappingAttributes2
+	(or TMappingAttributes) value.
+
+	@param[out] aAttributes		If successful, memory attributes extracted from \a aLegacyAttributes.
+	@param aLegacyAttributes	A legacy combined permission/attribute value.
+
+	@return KErrNone, if successful;
+			otherwise another of the system wide error codes.
+	*/
+	static TInt MemoryAttributes(TMemoryAttributes& aAttributes, TMappingAttributes2 aLegacyAttributes);
+
+	/**
+	Construct a legacy combined permission/memory-type value based on a
+	#TMemoryAttributes and #TMappingPermissions value.
+
+	@param aAttributes	A memory attributes value.
+	@param aPermissions	A mapping permissions value.
+
+	@return A TMappingAttributes2 value combining \a aAttributes and \a aPermissions.
+	*/
+	static TMappingAttributes2 LegacyMappingAttributes(TMemoryAttributes aAttributes, TMappingPermissions aPermissions);
+
+	//
+	// Code paging
+	//
+
+	/**
+	Create a new memory object which will contain demand paged code.
+
+	@param[out] aMemory	Pointer reference which on success is set to the address
+						of the created memory object.
+	@param aPageCount	Size of the memory object, in number of pages.
+	@param aInfo		Pointer reference which on success it set to a #TPagedCodeInfo
+						object which should be initialised with information required
+						for demand paging the code. (Call #PagedCodeLoaded when this is done.)
+
+	@return KErrNone, if successful;
+			otherwise another of the system wide error codes.
+	*/
+	static TInt PagedCodeNew(DMemoryObject*& aMemory, TUint aPageCount, TPagedCodeInfo*& aInfo);
+
+	/**
+	Call this to indicate that a memory object created with #PagedCodeNew has had its
+	#TPagedCodeInfo object initialised.
+
+	@param aMemory		The memory object.
+	@param aLoadAddress	An address at which \a aMemory is mapped with write permissions.
+	*/
+	static void PagedCodeLoaded(DMemoryObject* aMemory, TLinAddr aLoadAddress);
+
+	//
+	// Misc
+	//
+
+	// Initialisation...
+	static void Init1();
+	static void Init2();
+	static void Init3();
+	static TInt InitFixedKernelMemory(DMemoryObject*& aMemory, TLinAddr aStart, TLinAddr aEnd, TUint aInitSize, TMemoryObjectType aType, TMemoryCreateFlags aMemoryCreateFlags, TMemoryAttributes aMemoryAttributes, TMappingCreateFlags aMappingCreateFlags);
+	static TInt MemoryClaimInitialPages(DMemoryObject* aMemory, TLinAddr aBase, TUint aSize, TMappingPermissions aPermissions, TBool aAllowGaps=false, TBool aAllowNonRamPages=false);
+
+	// IPC helpers...
+	static void ValidateLocalIpcAddress(TLinAddr aAddr, TUint aSize, TBool aWrite);
+#ifndef __SMP__
+	static void IpcAliasPde(TPde*& aPdePtr, TUint aOsAsid);
+#endif
+	static void UserPermissionFault(TLinAddr aAddr, TBool aWrite);
+
+	// Address space...
+	static TInt AddressSpaceAlloc(TPhysAddr& aPageDirectory);
+	static void AddressSpaceFree(TUint aOsAsid);
+	static void AsyncAddressSpaceFree(TUint aOsAsid);
+	static TInt VirtualAllocCommon(TLinAddr& aLinAddr, TUint aSize, TBool aDemandPaged);
+	static void VirtualFreeCommon(TLinAddr aLinAddr, TUint aSize);
+	static TInt VirtualAlloc(TInt aOsAsid, TLinAddr& aLinAddr, TUint aSize, TBool aDemandPaged);
+	static void VirtualFree(TInt aOsAsid, TLinAddr aLinAddr, TUint aSize);
+
+	/**
+	Enumeration of panic values for category "MemModel".
+	*/
+	enum TMemModelPanic
+		{
+		EFsRegisterThread,
+		EProcessDestructChunksRemaining,
+		ECommitInvalidDllDataAddress,
+		ECodeSegLoadedNotCreator,
+		ETempMappingAlreadyInUse,
+		EUnsupportedOperation,
+		EBadBytesToPages,
+		ECodeSegSetReadOnlyFailure,
+		EProcessDestructOsAsidRemaining,
+		};
+	static void Panic(TMemModelPanic aPanic);
+	};
+
+
+
+template <class T>
+FORCE_INLINE void FlagSet(T& a,const T b)
+	{ a = (T)(a|b); }
+
+template <class T>
+FORCE_INLINE void FlagSet(T& a,const T b,const T c)
+	{ a = (T)(a|b|c); }
+
+template <class T>
+FORCE_INLINE void FlagSet(T& a,const T b,const T c,const T d)
+	{ a = (T)(a|b|c|d); }
+
+template <class T>
+FORCE_INLINE void FlagClear(T& a,const T b)
+	{ a = (T)(a&~b); }
+
+template <class T>
+FORCE_INLINE void FlagClear(T& a,const T b,const T c)
+	{ a = (T)(a&~b&~c); }
+
+template <class T>
+FORCE_INLINE void FlagClear(T& a,const T b,const T c,const T d)
+	{ a = (T)(a&~b&~c&~d); }
+
+
+#include <memmodel/epoc/mmubase/kblockmap.h>
+
+/**
+Structure containing the information about a demand paged code segment
+which is required to load and fixup its code section.
+*/
+class TPagedCodeInfo
+	{
+public:
+	~TPagedCodeInfo();
+	TInt ReadBlockMap(const TCodeSegCreateInfo& aInfo);
+	TInt ReadFixupTables(const TCodeSegCreateInfo& aInfo);
+	void ApplyFixups(TLinAddr aBuffer, TUint iIndex);
+public:
+	TBool iLoaded;						///< True once initial loading has finished and paging should start applying fixups.
+	TUint iCodeRelocTableSize;			///< Size, in bytes, of #iCodeRelocTable.
+	TUint8* iCodeRelocTable;			///< Code relocation information.
+	TUint iImportFixupTableSize;		///< Size, in bytes, of #iImportFixupTable.
+	TUint8* iImportFixupTable;			///< Import fixup information.
+	TUint32 iCodeDelta;					///< Delta to apply to relocate words referring to the code section.
+	TUint32 iDataDelta;					///< Delta to apply to relocate words referring to the data section.
+
+	TUint iCodeSize;					///< Size, in bytes, of the code section.
+	TUint32 iCompressionType;			///< Compression scheme in use, (KUidCompressionBytePair or KFormatNotCompressed).
+	TInt32* iCodePageOffsets;			///< Array of compressed page offsets within the file.
+	TInt iCodeLocalDrive;				///< Local drive number.
+	TInt iCodeStartInFile;				///< Offset of (possibly compressed) code from start of file.
+	TBlockMap iBlockMap;				///< Kernel-side representation of block map.
+	};
+
+
+
+/**
+A pool of DMutex objects that can be dynamically assigned for use.
+
+This is intended as a memory saving alternative to having each object in a class of objects
+owning their own mutex for locking purposes and provides a concurrency improvement over using
+a single global lock.
+*/
+class DMutexPool : public DBase
+	{
+public:
+	/**
+	@param aCount	Number of mutexes to allocated in the pool.
+					Must be smaller than #EMaxPoolSize.
+	@param aName	Base name for mutexes. Each mutex in the pool has a number appended to this base name.
+	@param aOrder	A value representing the order of the mutex with respect to deadlock prevention.
+	*/
+	TInt Create(TUint aCount, const TDesC* aName, TUint aOrder);
+
+	~DMutexPool();
+
+	/**
+	Wait on the mutex specified by \a aMutexRef.
+
+	If \a aMutexRef contains the null pointer then a member of this pool is selected and waited on,
+	and \a aMutexRef is set to a cookie value identifying that mutex; this cookie has its least
+	significant bit set to distinguish it from a normal DMutex pointer. Subsequent concurrent
+	Wait operations will use the same pool mutex; possibly modifying the value of the cookie.
+	*/
+	void Wait(DMutex*& aMutexRef);
+
+	/**
+	Signal the mutex specified by \a aMutexRef.
+
+	If mutex is identified as one from this pool then the value of \a aMutexRef will be modified
+	and if there are no pending Wait operations it will be set to the null pointer to indicate
+	that no mutex is assigned.
+	*/
+	void Signal(DMutex*& aMutexRef);
+
+	/**
+	Return true if the mutex specified by \a aMutexRef is held by the current thread.
+	*/
+	TBool IsHeld(DMutex*& aMutexRef);
+
+	enum
+		{
+		/** Maximum number of mutexes allowed in a pool. */
+		EMaxPoolSize = 64
+		};
+
+private:
+	/** Structure for storing information about each member of the pool. */
+	struct SMember
+		{
+		DMutex* iMutex;		///< The mutex
+		TUint iUseCount;	///< Number of times this mutex has been used
+		};
+	TUint iCount;		///< Number of mutexes in pool. (Number of entries in iMembers).
+	TUint iNext;		///< Index of next pool mutex to use.
+	SMember* iMembers;	///< Info about each memory of pool.
+	};
+
+
+#endif