os/kernelhwsrv/kernel/eka/memmodel/epoc/flexible/mmu/mm.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 /**
    17  @file
    18  @internalComponent
    19 */
    20 
    21 #ifndef MM_H
    22 #define MM_H
    23 
    24 #include <mmtypes.h>
    25 #include <platform.h>
    26 
    27 
    28 class DMemoryObject;
    29 class DMemoryMapping;
    30 class DMemModelThread;
    31 class DPhysicalPinMapping;
    32 
    33 /**
    34 Memory object types for MM::MemoryNew which indicates how the
    35 contents of a memory object are to be managed.
    36 */
    37 enum TMemoryObjectType
    38 	{
    39 	/**
    40 	Memory object for containing memory mapped hardware devices or special
    41 	purpose memory for which the physical addresses are fixed. The contents of
    42 	these type of objects are manipulated with the functions:
    43 	- MM::MemoryAddPages
    44 	- MM::MemoryAddContiguous
    45 	- MM::MemoryRemovePages
    46 	*/
    47 	EMemoryObjectHardware				= 0,
    48 
    49 	/**
    50 	Memory object containing normal program memory (RAM) which is allocated from a
    51 	system wide pool. The contents of these type of objects are manipulated with
    52 	the functions:
    53 	- MM::MemoryAlloc
    54 	- MM::MemoryAllocContiguous
    55 	- MM::MemoryFree
    56 	*/
    57 	EMemoryObjectUnpaged				= 1,
    58 
    59 	/**
    60 	Memory object containing normal program memory (RAM) which is allocated from a
    61 	system wide pool. This is the same basic management as EMemoryObjectUnpaged however
    62 	RAM defragmentation activity may substituted physical RAM pages with others and
    63 	this process may cause transient page faults which make this memory not suitable
    64 	for most kernel-side usage.
    65 
    66 	The contents of these type of objects are manipulated with the functions:
    67 	- MM::MemoryAlloc
    68 	- MM::MemoryAllocContiguous
    69 	- MM::MemoryFree
    70 	*/
    71 	EMemoryObjectMovable				= 2,
    72 
    73 	/**
    74 	Memory object containing normal program memory (RAM) which is demand paged
    75 	from a backing store. The contents of these type of objects are manipulated
    76 	with the functions.
    77 	- MM::MemoryAlloc
    78 	- MM::MemoryFree
    79 	*/
    80 	EMemoryObjectPaged					= 3,
    81 
    82 	/**
    83 	Memory object containing normal program memory (RAM) in the same way as
    84 	EMemoryObjectMovable but with the additional option of marking pages as
    85 	'discardable'. Discardable pages may be reclaimed (remove) by the system at
    86 	any time, this state is controlled using the functions:
    87 	- MM::MemoryAllowDiscard
    88 	- MM::MemoryDisallowDiscard
    89 	*/
    90 	EMemoryObjectDiscardable			= 4
    91 	};
    92 
    93 
    94 /**
    95 Bitmask of flags to specify options to MM:MemoryNew.
    96 */
    97 enum TMemoryCreateFlags
    98 	{
    99 	/**
   100 	Default value which has all flags false.
   101 	*/
   102 	EMemoryCreateDefault				= 0,
   103 
   104 	/**
   105 	Memory allocated for the memory object contents does not need wiping.
   106 	IMPORTANT, memory is normally wiped for security purposes, this attribute
   107 	should only be used when the old contents of any memory allocated can not
   108 	be read by any process without TCB capability.
   109 	*/
   110 	EMemoryCreateNoWipe					= 1<<0,
   111 
   112 	/**
   113 	Use the custom wipe byte value when wiping memory, rather than the default value.
   114 	@see EMemoryCreateUseCustomWipeByte
   115 	*/
   116 	EMemoryCreateUseCustomWipeByte		= 1<<1,
   117 
   118 	/**
   119 	Pre-create all resources the memory object needs so that operations on it
   120 	can not fail due to low memory conditions. This excludes any explicit
   121 	allocation of memory pages for use as the objects contents.
   122 	*/
   123 	EMemoryCreateReserveAllResources	= 1<<2,
   124 
   125 	/**
   126 	Memory object contents are not allowed to be pinned.
   127 	*/
   128 	EMemoryCreateDisallowPinning		= 1<<3,
   129 
   130 	/**
   131 	Memory object contents are read-only. Mappings with write permissions are
   132 	not allowed.
   133 	*/
   134 	EMemoryCreateReadOnly				= 1<<4,
   135 
   136 	/**
   137 	Memory object contents may be executed. Mappings with execute permissions
   138 	are allowed.
   139 	*/
   140 	EMemoryCreateAllowExecution			= 1<<5,
   141 
   142 	/**
   143 	Bit position for the least significant bit of an 8 bit value to use for
   144 	wiping newly allocated memory.
   145 	@see EMemoryCreateUseCustomWipeByte
   146 	@see EMemoryCreateNoWipe
   147 	*/
   148 	EMemoryCreateWipeByteShift			= 8,
   149 
   150 	// for selected internal use only...
   151 
   152 	/**
   153 	The TMemoryObjectType specified is actually a pointer to the DMemoryManager to use.
   154 	*/
   155 	EMemoryCreateCustomManager			= 1<<30,
   156 
   157 	/**
   158 	Memory object contents are to be demand paged. 
   159 	*/
   160 	EMemoryCreateDemandPaged			= 1<<31
   161 	};
   162 
   163 
   164 /**
   165 Attributes that the memory in a memory object has.
   166 
   167 These govern how the MMU and caching systems treat the memory. The following
   168 terms have meanings as specified in the ARM Architecture Reference Manual - see
   169 the section 'Memory types and attributes and the Memory order model'.
   170 
   171 - Memory types 'normal', 'device' and 'strongly-ordered'.
   172 - 'Shareable' attribute.
   173 */
   174 enum TMemoryAttributes
   175 	{
   176 	// memory types (copy of TMemoryType)...
   177 
   178 	EMemoryAttributeStronglyOrdered 	= EMemAttStronglyOrdered,
   179 	EMemoryAttributeDevice 				= EMemAttDevice,
   180 	EMemoryAttributeNormalUncached 		= EMemAttNormalUncached,
   181 	EMemoryAttributeNormalCached 		= EMemAttNormalCached,
   182 	EMemoryAttributeKernelInternal4 	= EMemAttKernelInternal4,
   183 	EMemoryAttributePlatformSpecific5 	= EMemAttPlatformSpecific5,
   184 	EMemoryAttributePlatformSpecific6	= EMemAttPlatformSpecific6,
   185 	EMemoryAttributePlatformSpecific7	= EMemAttPlatformSpecific7,
   186 
   187 	/**
   188 	Bitmask to extract TMemoryType value from this enum. E.g.
   189 	@code
   190 	TMemoryAttributes attr;
   191 	TMemoryType type = (TMemoryType)(attr&EMemoryAttributeTypeMask);
   192 	@endcode
   193 	*/
   194 	EMemoryAttributeTypeMask			= KMemoryTypeMask,
   195 
   196 	/**
   197 	Set if memory is Shareable.
   198 	*/
   199 	EMemoryAttributeShareable			= 0x08,
   200 
   201 	/**
   202 	Legacy (and little-used/unused?) ARM attribute.
   203 	*/
   204 	EMemoryAttributeUseECC				= 0x10,
   205 
   206 
   207 	/**
   208 	Number of bits required to store memory attribute value.
   209 	@internalComponent
   210 	*/
   211 	EMemoryAttributeShift				= 5,
   212 
   213 	/**
   214 	Bitmask for all significant attribute bits.
   215 	@internalComponent
   216 	*/
   217 	EMemoryAttributeMask				= (1<<EMemoryAttributeShift)-1,
   218 
   219 	// pseudo attributes...
   220 
   221 	/**
   222 	Indicates the Shareable attribute should be the default value for the system.
   223 	See macro __CPU_USE_SHARED_MEMORY
   224 	*/
   225 	EMemoryAttributeDefaultShareable	= 0x80000000,
   226 
   227 	// popular combinations...
   228 
   229 	/**
   230 	Normal program memory for use by software.
   231 	*/
   232 	EMemoryAttributeStandard			= EMemoryAttributeNormalCached|EMemoryAttributeDefaultShareable
   233 	};
   234 
   235 
   236 /**
   237 Access permissions applied to Memory Mappings.
   238 */
   239 enum TMappingPermissions
   240 	{
   241 	EUser	    = 1<<0, ///< Unprivileged (user mode) access allowed.
   242 	EReadWrite  = 1<<1, ///< Memory contents may be modified
   243 	EExecute	= 1<<2, ///< Memory contents may be executed as code.
   244 
   245 	// popular combinations...
   246 	EUserReadOnly = EUser,
   247 	EUserReadWrite = EUser|EReadWrite,
   248 	EUserExecute = EUser|EExecute,
   249 	ESupervisorReadOnly = 0,
   250 	ESupervisorReadWrite = EReadWrite,
   251 	ESupervisorExecute = EExecute
   252 	};
   253 
   254 
   255 /**
   256 Bitmask of flags to specify options to MM::MappingNew.
   257 */
   258 enum TMappingCreateFlags
   259 	{
   260 	/**
   261 	Default value which has all flags false.
   262 	*/
   263 	EMappingCreateDefault				= 0,
   264 
   265 	/**
   266 	Allocate the specified virtual address.
   267 	*/
   268 	EMappingCreateExactVirtual			= 1<<0,
   269 
   270 	/**
   271 	Pre-create all resources (like page tables) that the memory mapping
   272 	needs so that operations on it can not fail due to low memory conditions.
   273 	*/
   274 	EMappingCreateReserveAllResources	= 1<<1,
   275 
   276 	// for selected internal use only...
   277 
   278 	/**
   279 	Flag memory as being demand paged.
   280 	Exclusive with EMappingCreatePinning and EMappingCreateReserveAllResources.
   281 	@internalTechnology
   282 	*/
   283 	EMappingCreateDemandPaged			= 1<<27,
   284 
   285 	/**
   286 	Flag memory as requiring a common address across all address spaces, also
   287 	implies EMappingCreateExactVirtual.
   288 	@internalTechnology
   289 	*/
   290 	EMappingCreateCommonVirtual			= 1<<28,
   291 
   292 	/**
   293 	Allocate virtual address in the global region which it to be used for
   294 	user-mode access. (KGlobalMemoryBase<=address<KUserMemoryLimit).
   295 	@internalTechnology
   296 	*/
   297 	EMappingCreateUserGlobalVirtual		= 1<<29,
   298 
   299 	/**
   300 	Don't allocate any virtual memory in the address space, use the specified
   301 	address and assume ownership of this.
   302 	@internalTechnology
   303 	*/
   304 	EMappingCreateAdoptVirtual			= 1<<30,
   305 
   306 	/**
   307 	Don't allocate any virtual memory in the address space, just used the
   308 	specified address.
   309 	@internalTechnology
   310 	*/
   311 	EMappingCreateFixedVirtual	= 1<<31
   312 	};
   313 
   314 
   315 class DMemModelChunk;
   316 class TPagedCodeInfo;
   317 
   318 /**
   319 Static interface to the Flexible Memory Model implementation
   320 for use by the Symbian OS aware part of the memory model codebase.
   321 */
   322 class MM
   323 	{
   324 public:
   325 	//
   326 	// Memory Object functions
   327 	//
   328 
   329 	/**
   330 	Create a new memory object.
   331 
   332 	A memory object is a sparse array of memory pages to which memory mappings
   333 	may be attached. All pages in the array are managed using the same methods
   334 	(see TMemoryObjectType) and have the same attributes (see TMemoryAttributes).
   335 
   336 	On creation it contains no pages.
   337 
   338 	@param[out] aMemory	Pointer reference which on success is set to the address
   339 						of the created memory object.
   340 	@param aType		Value from TMemoryObjectType which indicates how the
   341 						contents of the memory object are to be managed.
   342 	@param aPageCount	Size of the memory object, in number of pages.
   343 	@param aCreateFlags	Bitmask of option flags from enum TMemoryCreateFlags.
   344 	@param aAttributes	Bitmask of values from enum TMemoryAttributes.
   345 
   346 	@return KErrNone, if successful;
   347 			otherwise another of the system wide error codes.
   348 	*/
   349 	static TInt MemoryNew(DMemoryObject*& aMemory, TMemoryObjectType aType, TUint aPageCount, TMemoryCreateFlags aCreateFlags=EMemoryCreateDefault, TMemoryAttributes aAttributes=EMemoryAttributeStandard);
   350 
   351 	/**
   352 	Assign a mutex which will be used to serialise explicit modifications to the
   353 	specified memory object.
   354 
   355 	If a lock hasn't been specified for a particular object, it will make use of
   356 	one allocated dynamically allocated from a shared pool; this mutex will be of 'order'
   357 	#KMutexOrdMemoryObject.
   358 
   359 	@see MemoryObjectLock.
   360 	*/
   361 	static void MemorySetLock(DMemoryObject* aMemory, DMutex* aLock);
   362 
   363 	/**
   364 	Wait on the specified memory object's lock mutex.
   365 	*/
   366 	static void MemoryLock(DMemoryObject* aMemory);
   367 
   368 	/**
   369 	Signal the specified memory object's lock mutex.
   370 	*/
   371 	static void MemoryUnlock(DMemoryObject* aMemory);
   372 
   373 	/**
   374 	Remove all memory from a memory object and close a reference on it.
   375 
   376 	If there are no longer any mappings to the memory, or other references,
   377 	this will result in the memory object being destroyed. However whilst
   378 	other references exist, cleanup of memory and other resources may be
   379 	delayed indefinitely.
   380 
   381 	This function acquires and releases the memory objects lock.
   382 	See MM::MemorySetLock.
   383 
   384 	@param aMemory	Pointer reference to memory object to be destroyed.
   385 					On return from the function this is set to the null-pointer.
   386 					No action is performed if the reference was already the
   387 					null-pointer on entry to this function.
   388 	*/
   389 	static void MemoryDestroy(DMemoryObject*& aMemory);
   390 
   391 	/**
   392 	Allocate memory for a specified region within a memory object.
   393 	Memory is allocated as appropriate for the object type, e.g.
   394 	For Unpaged objects, from the system RAM pool; for Paged objects, in the
   395 	backing store.
   396 
   397 	This function acquires and releases the memory objects lock.
   398 	See MM::MemorySetLock.
   399 
   400 	Supported for memory object types:
   401 	- EMemoryObjectUnpaged
   402 	- EMemoryObjectMovable
   403 	- EMemoryObjectPaged
   404 	- EMemoryObjectDiscardable
   405 
   406 	@param aMemory	The memory object.
   407 	@param aIndex	Page index for start of the region.
   408 	@param aCount	Number of pages in the region.
   409 
   410 	@return KErrNone, if successful;
   411 			KErrAlreadyExists, if any part of the region was already allocated;
   412 			KErrArgument, if the region exceeds the bounds of the memory object;
   413 			KErrNotSupported, if the memory object doesn't support this operation;
   414 			otherwise another of the system wide error codes.
   415 	*/
   416 	static TInt MemoryAlloc(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
   417 
   418 	/**
   419 	Allocate memory for a specified region within a memory object.
   420 	The allocated memory will have contiguous physical addresses.
   421 
   422 	This function acquires and releases the memory objects lock.
   423 	See MM::MemorySetLock.
   424 
   425 	Important note, this function can unexpectedly fail with KErrAlreadyExists
   426 	if any part of the the region previously contained allocated memory which
   427 	had been freed but which was pinned. It is therefore not suitable for general
   428 	use.
   429 
   430 	Supported for memory object types:
   431 	- EMemoryObjectUnpaged
   432 	- EMemoryObjectDiscardable
   433 
   434 	@param aMemory	The memory object.
   435 	@param aIndex	Page index for start of the region.
   436 	@param aCount	Number of pages in the region.
   437 	@param aAlign	Log2 of the alignment (in bytes) that the address of the allocated physical RAM must have.
   438 	@param[out] aPhysAddr	On success, this is set to the start address of the allocated physical RAM.
   439 
   440 	@return KErrNone, if successful;
   441 			KErrAlreadyExists, if any part of the region was already allocated;
   442 			KErrArgument, if the region exceeds the bounds of the memory object;
   443 			KErrNotSupported, if the memory object doesn't support this operation;
   444 			otherwise another of the system wide error codes.
   445 	*/
   446 	static TInt MemoryAllocContiguous(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TUint aAlign, TPhysAddr& aPhysAddr);
   447 
   448 	/**
   449 	Free (unallocate) memory for a specified region within a memory object.
   450 	This is the inverse operation to MemoryAlloc and MemoryAllocContiguous.
   451 
   452 	This function acquires and releases the memory objects lock.
   453 	See MM::MemorySetLock.
   454 
   455 	Supported for memory object types:
   456 	- EMemoryObjectUnpaged
   457 	- EMemoryObjectMovable
   458 	- EMemoryObjectPaged
   459 	- EMemoryObjectDiscardable
   460 
   461 	@param aMemory	The memory object.
   462 	@param aIndex	Page index for start of the region.
   463 	@param aCount	Number of pages in the region.
   464 	*/
   465 	static void MemoryFree(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
   466 
   467 	/**
   468 	Add the specified pages to a region in a memory object.
   469 
   470 	This function acquires and releases the memory objects lock.
   471 	See MM::MemorySetLock.
   472 
   473 	Supported for memory object types:
   474 	- EMemoryObjectHardware
   475 
   476 	@param aMemory	The memory object.
   477 	@param aIndex	Page index for start of the region.
   478 	@param aCount	Number of pages in the region.
   479 	@param aPages	Pointer to array of pages to add. This must contain \a aCount
   480 					number of physical page addresses which are page aligned.
   481 
   482 	@return KErrNone, if successful;
   483 			KErrAlreadyExists, if any part of the region already contains pages;
   484 			KErrArgument, if the region exceeds the bounds of the memory object;
   485 			KErrNotSupported, if the memory object doesn't support this operation;
   486 			otherwise another of the system wide error codes.
   487 	*/
   488 	static TInt MemoryAddPages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages);
   489 
   490 	/**
   491 	Add a contiguous range of pages to a region in a memory object.
   492 
   493 	This function acquires and releases the memory objects lock.
   494 	See MM::MemorySetLock.
   495 
   496 	Supported for memory object types:
   497 	- EMemoryObjectHardware
   498 
   499 	@param aMemory		The memory object.
   500 	@param aIndex		Page index for start of the region.
   501 	@param aCount		Number of pages in the region.
   502 	@param aPhysAddr	The page aligned start address of the pages to be added.
   503 
   504 	@return KErrNone, if successful;
   505 			KErrAlreadyExists, if any part of the region already contains pages;
   506 			KErrArgument, if the region exceeds the bounds of the memory object;
   507 			KErrNotSupported, if the memory object doesn't support this operation;
   508 			otherwise another of the system wide error codes.
   509 	*/
   510 	static TInt MemoryAddContiguous(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr aPhysAddr);
   511 
   512 	/**
   513 	Remove pages from a region in a memory object.
   514 
   515 	This is the inverse operation to MemoryAdd and MemoryAddContiguous.
   516 
   517 	This function acquires and releases the memory objects lock.
   518 	See MM::MemorySetLock.
   519 
   520 	Supported for memory object types:
   521 	- EMemoryObjectHardware
   522 
   523 	@param aMemory		The memory object.
   524 	@param aIndex		Page index for start of the region.
   525 	@param aCount		Number of pages in the region.
   526 	@param[out] aPages	Pointer to an array of physical addresses which has a
   527 						length of \a aCount. The contents of this will be set to
   528 						the addresses of the pages which were removed by this
   529 						function. The number of valid entries in this array is
   530 						given by the return value of this function.
   531 						aPages may be the null-pointer, to indicate that these
   532 						page addresses aren't required by the caller.
   533 
   534 	@return The number of pages successfully removed from the memory object.
   535 			This gives the number of valid entries in the array \a aPages and is
   536 			less-than or equal to \a aCount.
   537 	*/
   538 	static TUint MemoryRemovePages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages);
   539 
   540 	/**
   541 	Mark a region in a memory object as discardable.
   542 
   543 	The system may remove discardable pages from the memory object at any time,
   544 	to be reused for other purposes.
   545 
   546 	This function acquires and releases the memory objects lock.
   547 	See MM::MemorySetLock.
   548 
   549 	Supported for memory object types:
   550 	- EMemoryObjectDiscardable
   551 
   552 	@see MemoryDisallowDiscard
   553 
   554 	@param aMemory	The memory object.
   555 	@param aIndex	Page index for start of the region.
   556 	@param aCount	Number of pages in the region.
   557 
   558 	@return KErrNone, if successful;
   559 			KErrNotSupported, if the memory object doesn't support this operation;
   560 			otherwise another of the system wide error codes.
   561 
   562 	*/
   563 	static TInt MemoryAllowDiscard(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
   564 
   565 	/**
   566 	Mark a region in a memory object as no longer discardable.
   567 	This undoes the operation of MemoryAllowDiscard.
   568 
   569 	If any pages in the region are no longer present, then the operation will
   570 	fail with KErrNotFound. In this case, the state of the pages in the region
   571 	is indeterminate; they may be either still discardable, not discardable, or
   572 	not present.
   573 
   574 	Supported for memory object types:
   575 	- EMemoryObjectDiscardable
   576 
   577 	@see MemoryAllowDiscard
   578 
   579 	@param aMemory	The memory object.
   580 	@param aIndex	Page index for start of the region.
   581 	@param aCount	Number of pages in the region.
   582 
   583 	@return KErrNone, if successful;
   584 			KErrNotFound, if any page in the region was no longer present;
   585 			KErrNotSupported, if the memory object doesn't support this operation;
   586 			otherwise another of the system wide error codes.
   587 	*/
   588 	static TInt MemoryDisallowDiscard(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
   589 
   590 	/**
   591 	This function only exists to support DMemModelChunk::PhysicalAddress and may be removed.
   592 	DO NOT USE.
   593 	*/
   594 	static TInt MemoryPhysAddr(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr& aPhysicalAddress, TPhysAddr* aPhysicalPageList);
   595 
   596 	/**
   597 	Prime BTrace for a memory object - internal use only.
   598 	*/
   599 	static void MemoryBTracePrime(DMemoryObject* aMemory);
   600 
   601 	/**
   602 	Close a memory object.
   603 
   604 	This should be called on the memory object returned by #MappingGetAndOpenMemory.
   605 	*/
   606 	static void MemoryClose(DMemoryObject* aMemory);
   607 
   608 	/**
   609 	Return true if aMemory has any mappings associated with it.
   610 	*/
   611 	static TBool MemoryIsNotMapped(DMemoryObject* aMemory);
   612 
   613 	/**
   614 	Wipe the entire memory contents of the memory object so they are in the
   615 	same state as if the memory had been newly allocated with #MemoryAlloc.
   616 
   617 	This is useful for situations where a memory object is being re-purposed and
   618 	confidentiality requires that the old memory contents are not disclosed.
   619 	For this reason, the function asserts that the memory object has no mappings.
   620 
   621 	@see EMemoryCreateUseCustomWipeByte
   622 	@see EMemoryCreateNoWipe
   623 
   624 	@return KErrNone, if successful;
   625 			otherwise KErrNotSupported, to indicate the memory object doesn't support this operation.
   626 	*/
   627 	static TInt MemoryWipe(DMemoryObject* aMemory);
   628 
   629 	/**
   630 	Set the memory object to be read only, i.e. to no longer allow writable mappings.
   631 
   632 	NOTE - This can't be undone, page moving will break if a memory object is made 
   633 	writable again.
   634 
   635 	@param aMemory	The memory object to update.
   636 	@return KErrNone on success, KErrInUse if the memory object has writable mappings
   637 			KErrNotSupported if the objects manager doesn't support this.
   638 	*/
   639 	static TInt MemorySetReadOnly(DMemoryObject* aMemory);
   640 
   641 	/**
   642 	Pins physical memory associated with the memory object and returns the physical
   643 	memory characteristics, e.g. address, map attributes and colour
   644 
   645 	@param aMemory	        The memory object.
   646 	@param aPinObject	    The physical pin mapping.
   647 	@param aIndex	        Page index for start of the region.
   648 	@param aCount   	    Number of pages in the region.
   649 	@param aReadOnly   	    Indicates whether memory should be pinned as read only.
   650 	@param aAddress[out]	The value is the physical address of the first page
   651 						    in the region.
   652 	@param aPages[out]      If not zero, this points to an array of TPhysAddr
   653 	                        objects. On success, this array will be filled
   654 						    with the addresses of the physical pages which
   655 						    contain the specified region. If aPages is
   656 						    zero, then the function will fail with
   657 						    KErrNotFound if the specified region is not
   658 						    physically contiguous.
   659 	@param aMapAttr[out]    Memory attributes defined by TMappingAttributes2.
   660 	@param aColour[out]     The mapping colour of the first physical page.
   661 
   662 
   663 	@return The number of pages successfully removed from the memory object.
   664 			This gives the number of entries in the array aPages and is
   665 			less-than or equal to aCount.
   666 	*/
   667 
   668 	static TInt PinPhysicalMemory(DMemoryObject* aMemory, DPhysicalPinMapping* aPinObject, TUint aIndex,
   669 								  TUint aCount, TBool aReadOnly, TPhysAddr& aAddress, TPhysAddr* aPages,
   670 								  TUint32& aMapAttr, TUint& aColour);
   671 
   672 	//
   673 	// Memory Mapping functions
   674 	//
   675 
   676 	/**
   677 	Create a new memory mapping for a specific memory object.
   678 
   679 	A memory mapping represents the MMU resources required to make a region of a
   680 	memory object accessible to software within a single address space (process).
   681 	Each mapping has an associated set of access permissions (see
   682 	#TMappingPermissions).
   683 
   684 	@param[out] aMapping Pointer reference which on success is set to the address
   685 						of the created memory mapping.
   686 	@param aMemory		The memory object with which the mapping is associated.
   687 	@param aPermissions	Bitmask of values from enum #TMappingPermissions which
   688 						give the access permissions for this mapping.
   689 	@param aOsAsid		The identifier for the address space in which this
   690 						mapping is to appear.
   691 	@param aFlags		Bitmask of option flags from enum #TMappingCreateFlags
   692 	@param aAddr		Optional virtual address at which the memory mapped
   693 						by this mapping is to appear within the specified
   694 						address space.
   695 	@param aIndex		Optional start page index within \a aMemory for this
   696 						mapping.
   697 	@param aCount		Optional page count for size of mapping. A value of
   698 						the maximum integer indicates that the mapping is to
   699 						extend to the end of the memory object.
   700 
   701 	@return KErrNone, if successful;
   702 			otherwise another of the system wide error codes.
   703 	*/
   704 	static TInt MappingNew(DMemoryMapping*& aMapping, DMemoryObject* aMemory, TMappingPermissions aPermissions, TInt aOsAsid, TMappingCreateFlags aFlags=EMappingCreateDefault, TLinAddr aAddr=0, TUint aIndex=0, TUint aCount=~0u);
   705 
   706 	/**
   707 	Create a new memory mapping with is not associated with any memory object.
   708 
   709 	This mapping may be used and reused with different memory objects by using
   710 	the #MappingMap and #MappingUnmap methods.
   711 
   712 	@param[out] aMapping	Pointer reference which on success is set to the address
   713 							of the created memory mapping.
   714 	@param aCount			Page count for size of mapping.
   715 	@param aOsAsid			The identifier for the address space in which this
   716 							mapping is to appear.
   717 	@param aFlags			Bitmask of option flags from enum #TMappingCreateFlags
   718 	@param aAddr			Optional virtual address at which the mapping is to
   719 							appear within the specified address space.
   720 	@param aColourOffset	The byte offset within a memory object's memory which this mapping
   721 							is to start. This is used to adjust virtual memory allocation to
   722 							meet page colouring restrictions. If this value is not known leave
   723 							this argument unspecified; however, it must be specified if \a aAddr
   724 							is specified.
   725 
   726 	@return KErrNone, if successful;
   727 			otherwise another of the system wide error codes.
   728 	*/
   729 	static TInt MappingNew(DMemoryMapping*& aMapping, TUint aCount, TInt aOsAsid, TMappingCreateFlags aFlags=EMappingCreateDefault, TLinAddr aAddr=0, TLinAddr aColourOffset=~0);
   730 
   731 	/**
   732 	Apply a memory mapping to a memory object.
   733 
   734 	@param aMapping		The memory mapping to be used to map \a aMemory.
   735 	@param aPermissions	Bitmask of values from enum #TMappingPermissions which
   736 						give the access permissions for this mapping.
   737 	@param aMemory		The memory object with which the mapping is to be associated.
   738 	@param aIndex		Optional start page index within aMemory for this
   739 						mapping.
   740 	@param aCount		Optional page count for size of mapping. A value of
   741 						the maximum integer indicates that the mapping is to
   742 						extend to the end of the memory object.
   743 
   744 	@return KErrNone, if successful;
   745 			otherwise another of the system wide error codes.
   746 	*/
   747 	static TInt MappingMap(DMemoryMapping* aMapping, TMappingPermissions aPermissions, DMemoryObject* aMemory, TUint aIndex=0, TUint aCount=~0u);
   748 
   749 	/**
   750 	Remove a mapping from the memory object with which it is associated.
   751 	*/
   752 	static void MappingUnmap(DMemoryMapping* aMapping);
   753 
   754 	/**
   755 	Remove a memory mapping from its associated address space and close a
   756 	reference on it.
   757 
   758 	If there are no longer any other references, this will result in the memory
   759 	object being destroyed,
   760 
   761 	@param aMapping	Pointer reference to memory mapping to be destroyed.
   762 					On return from the function this is set to the null-pointer.
   763 					No action is performed if the reference was already the
   764 					null-pointer on entry to this function.
   765 	*/
   766 	static void MappingDestroy(DMemoryMapping*& aMapping);
   767 
   768 	/**
   769 	Remove a memory mapping from its associated address space and close a
   770 	reference on it.
   771 
   772 	The mapping is found based on the virtual address region within which it
   773 	maps memory. The caller must that such a mapping exists and that it will not
   774 	be unmapped by another thread.
   775 
   776 	@param aAddr	Virtual address which lies within the region covered by the
   777 					memory mapping.
   778 	@param aOsAsid	Address space in which the mapping appears.
   779 	*/
   780 	static void MappingDestroy(TLinAddr aAddr, TInt aOsAsid);
   781 
   782 	/**
   783 	Perform the action of #MappingDestroy on a memory mapping then #MemoryDestroy
   784 	on its associated memory object.
   785 
   786 	This function acquires and releases the memory objects lock.
   787 	See MM::MemorySetLock.
   788 
   789 	NOTE - This should not be used on mappings that are reused as the mapping's 
   790 	instance count is not checked.
   791 
   792 	@param aMapping	Pointer reference to memory mapping to be destroyed.
   793 					On return from the function this is set to the null-pointer.
   794 					No action is performed if the reference was already the
   795 					null-pointer on entry to this function.
   796 	*/
   797 	static void MappingAndMemoryDestroy(DMemoryMapping*& aMapping);
   798 
   799 	/**
   800 	Perform the action of #MappingDestroy on a memory mapping then #MemoryDestroy
   801 	on its associated memory object.
   802 
   803 	The mapping is found based on the virtual address region within which it
   804 	maps memory. The caller must that such a mapping exists and that it will not
   805 	be unmapped by another thread.
   806 
   807 	This function acquires and releases the memory objects lock.
   808 	See MM::MemorySetLock.
   809 
   810 	NOTE - This should not be used on mappings that are reused as the mapping's 
   811 	instance count is not checked.
   812 
   813 	@param aAddr	Virtual address which lies within the region covered by the
   814 					memory mapping.
   815 	@param aOsAsid	Address space in which the mapping appears.
   816 	*/
   817 	static void MappingAndMemoryDestroy(TLinAddr aAddr, TInt aOsAsid);
   818 
   819 	/**
   820 	Return the virtual address at which the memory mapped by a memory mapping
   821 	starts.
   822 
   823 	@param aMapping	A memory mapping.
   824 
   825 	@return The base address.
   826 	*/
   827 	static TLinAddr MappingBase(DMemoryMapping* aMapping);
   828 
   829 	/**
   830 	Return the OS Address Space ID (OS ASID) of the address space the mapping is within.
   831 
   832 	@param aMapping	A memory mapping.
   833 
   834 	@return OS Address Space ID (OS ASID).
   835 	*/
   836 	static TInt MappingOsAsid(DMemoryMapping* aMapping);
   837 
   838 	/**
   839 	Open the memory object mapped by a mapping and return it.
   840 
   841 	The memory object can be closed again by calling #MemoryClose.
   842 
   843 	NOTE - This should not be used on mappings that are reused as the mapping's 
   844 	instance count is not checked.
   845 
   846 	@param aMapping			A memory mapping.
   847 
   848 	@return The memory object, or NULL.
   849 	*/
   850 	static DMemoryObject* MappingGetAndOpenMemory(DMemoryMapping* aMapping);
   851 
   852 	/**
   853 	Close a mapping
   854 
   855 	@param aMapping	A memory mapping.
   856 	*/
   857 	static void MappingClose(DMemoryMapping* aMapping);
   858 
   859 	/**
   860 	Find and open the mapping that maps a virtual address in the address space of the specified
   861 	thread.
   862 
   863 	The caller must close the mapping when it has finished using it.
   864 
   865 	@param aThread The thread whose address space is to be searched.
   866 	@param aAddr The virtual address for which the mapping is to be found.
   867 	@param aSize The size, in bytes, of the region at aAddr.
   868 	@param aOffsetInMapping A reference which is set to the offset, in bytes, into the
   869 							mapping of the start address.
   870 	@param aInstanceCount	The instance count of the found mapping.
   871 
   872 	@return The mapping, or NULL if no mapping was found.
   873 
   874 	@pre Calling thread must be in a critical section.
   875 	*/
   876 	static DMemoryMapping* FindMappingInThread(	DMemModelThread* aThread, TLinAddr aAddr, TUint aSize, 
   877 												TUint& aOffsetInMapping, TUint& aInstanceCount);
   878 
   879 	/**
   880 	Find and open the mapping that maps a virtual address in the address space of the specified
   881 	process.
   882 
   883 	The caller must close the mapping when it has finished using it.  The caller must ensure that
   884 	the process can't be destroyed while calling this method.
   885 
   886 	@param aOsAsid The identifier for the address space in which the mapping appears.
   887 	@param aAddr The virtual address for which the mapping is to be found.
   888 	@param aSize The size, in bytes, of the region at aAddr.
   889 	@param aOffsetInMapping A reference which is set to the offset, in bytes, into the
   890 							mapping of the start address.
   891 	@param aInstanceCount	The instance count of the found mapping.
   892 
   893 	@return The mapping, or NULL if no mapping was found.
   894 
   895 	@pre Calling thread must be in a critical section.
   896 	*/
   897 	static DMemoryMapping* FindMappingInAddressSpace(	TUint aOsAsid, TLinAddr aAddr, TUint aSize, 
   898 														TUint& aOffsetInMapping, TUint& aInstanceCount);
   899 
   900 
   901 	//
   902 	// Conversion utilities
   903 	//
   904 
   905 	/**
   906 	Round a size in bytes up to the next integer multiple of the page size.
   907 
   908 	@param aSize A size in bytes.
   909 
   910 	@return The rounded size.
   911 	*/
   912 	static TUint RoundToPageSize(TUint aSize);
   913 
   914 	/**
   915 	Round a size in bytes up to the next integer multiple of the page size
   916 	then convert it into a page count by dividing it by the page size.
   917 
   918 	@param aSize A size in bytes.
   919 
   920 	@return The rounded page count.
   921 	*/
   922 	static TUint RoundToPageCount(TUint aSize);
   923 
   924 	/**
   925 	Round a bit shift value representing the log2 of a size in bytes, up to
   926 	a shift value representing the log2 of a size in pages.
   927 
   928 	@param aShift log2 of a size in bytes.
   929 
   930 	@return aShift-KPageShift, or zero if aShift<=KPageShift.
   931 	*/
   932 	static TUint RoundToPageShift(TUint aShift);
   933 
   934 	/**
   935 	Convert a size in bytes to a size in pages.
   936 
   937 	@param aBytes A size in bytes.
   938 
   939 	@return aBytes/KPageSize.
   940 
   941 	@panic MemModel #EBadBytesToPages if aBytes is not an integer multiple of
   942 		   the page size.
   943 	*/
   944 	static TUint BytesToPages(TUint aBytes);
   945 
   946 	/**
   947 	Construct a #TMappingPermissions value base on individual permission flags.
   948 
   949 	@param aUser	True to allow unprivileged (user mode) access.
   950 	@param aWrite	True to allow memory contents to be modified.
   951 	@param aExecute	True to allow memory contents to be executed as code.
   952 
   953 	@return Permissions expressed as an #TMappingPermissions value.
   954 	*/
   955 	static TMappingPermissions MappingPermissions(TBool aUser, TBool aWrite, TBool aExecute);
   956 
   957 	/**
   958 	Extract the mapping permissions from a TMappingAttributes2
   959 	(or TMappingAttributes) value.
   960 
   961 	@param[out] aPermissions	If successful, mapping permissions extracted from aLegacyAttributes.
   962 	@param aLegacyAttributes	A legacy combined permission/attribute value.
   963 
   964 	@return KErrNone, if successful;
   965 			otherwise another of the system wide error codes.
   966 	*/
   967 	static TInt MappingPermissions(TMappingPermissions& aPermissions, TMappingAttributes2 aLegacyAttributes);
   968 
   969 	/**
   970 	Extract the memory attributes from a TMappingAttributes2
   971 	(or TMappingAttributes) value.
   972 
   973 	@param[out] aAttributes		If successful, memory attributes extracted from \a aLegacyAttributes.
   974 	@param aLegacyAttributes	A legacy combined permission/attribute value.
   975 
   976 	@return KErrNone, if successful;
   977 			otherwise another of the system wide error codes.
   978 	*/
   979 	static TInt MemoryAttributes(TMemoryAttributes& aAttributes, TMappingAttributes2 aLegacyAttributes);
   980 
   981 	/**
   982 	Construct a legacy combined permission/memory-type value based on a
   983 	#TMemoryAttributes and #TMappingPermissions value.
   984 
   985 	@param aAttributes	A memory attributes value.
   986 	@param aPermissions	A mapping permissions value.
   987 
   988 	@return A TMappingAttributes2 value combining \a aAttributes and \a aPermissions.
   989 	*/
   990 	static TMappingAttributes2 LegacyMappingAttributes(TMemoryAttributes aAttributes, TMappingPermissions aPermissions);
   991 
   992 	//
   993 	// Code paging
   994 	//
   995 
   996 	/**
   997 	Create a new memory object which will contain demand paged code.
   998 
   999 	@param[out] aMemory	Pointer reference which on success is set to the address
  1000 						of the created memory object.
  1001 	@param aPageCount	Size of the memory object, in number of pages.
  1002 	@param aInfo		Pointer reference which on success it set to a #TPagedCodeInfo
  1003 						object which should be initialised with information required
  1004 						for demand paging the code. (Call #PagedCodeLoaded when this is done.)
  1005 
  1006 	@return KErrNone, if successful;
  1007 			otherwise another of the system wide error codes.
  1008 	*/
  1009 	static TInt PagedCodeNew(DMemoryObject*& aMemory, TUint aPageCount, TPagedCodeInfo*& aInfo);
  1010 
  1011 	/**
  1012 	Call this to indicate that a memory object created with #PagedCodeNew has had its
  1013 	#TPagedCodeInfo object initialised.
  1014 
  1015 	@param aMemory		The memory object.
  1016 	@param aLoadAddress	An address at which \a aMemory is mapped with write permissions.
  1017 	*/
  1018 	static void PagedCodeLoaded(DMemoryObject* aMemory, TLinAddr aLoadAddress);
  1019 
  1020 	//
  1021 	// Misc
  1022 	//
  1023 
  1024 	// Initialisation...
  1025 	static void Init1();
  1026 	static void Init2();
  1027 	static void Init3();
  1028 	static TInt InitFixedKernelMemory(DMemoryObject*& aMemory, TLinAddr aStart, TLinAddr aEnd, TUint aInitSize, TMemoryObjectType aType, TMemoryCreateFlags aMemoryCreateFlags, TMemoryAttributes aMemoryAttributes, TMappingCreateFlags aMappingCreateFlags);
  1029 	static TInt MemoryClaimInitialPages(DMemoryObject* aMemory, TLinAddr aBase, TUint aSize, TMappingPermissions aPermissions, TBool aAllowGaps=false, TBool aAllowNonRamPages=false);
  1030 
  1031 	// IPC helpers...
  1032 	static void ValidateLocalIpcAddress(TLinAddr aAddr, TUint aSize, TBool aWrite);
  1033 #ifndef __SMP__
  1034 	static void IpcAliasPde(TPde*& aPdePtr, TUint aOsAsid);
  1035 #endif
  1036 	static void UserPermissionFault(TLinAddr aAddr, TBool aWrite);
  1037 
  1038 	// Address space...
  1039 	static TInt AddressSpaceAlloc(TPhysAddr& aPageDirectory);
  1040 	static void AddressSpaceFree(TUint aOsAsid);
  1041 	static void AsyncAddressSpaceFree(TUint aOsAsid);
  1042 	static TInt VirtualAllocCommon(TLinAddr& aLinAddr, TUint aSize, TBool aDemandPaged);
  1043 	static void VirtualFreeCommon(TLinAddr aLinAddr, TUint aSize);
  1044 	static TInt VirtualAlloc(TInt aOsAsid, TLinAddr& aLinAddr, TUint aSize, TBool aDemandPaged);
  1045 	static void VirtualFree(TInt aOsAsid, TLinAddr aLinAddr, TUint aSize);
  1046 
  1047 	/**
  1048 	Enumeration of panic values for category "MemModel".
  1049 	*/
  1050 	enum TMemModelPanic
  1051 		{
  1052 		EFsRegisterThread,
  1053 		EProcessDestructChunksRemaining,
  1054 		ECommitInvalidDllDataAddress,
  1055 		ECodeSegLoadedNotCreator,
  1056 		ETempMappingAlreadyInUse,
  1057 		EUnsupportedOperation,
  1058 		EBadBytesToPages,
  1059 		ECodeSegSetReadOnlyFailure,
  1060 		EProcessDestructOsAsidRemaining,
  1061 		};
  1062 	static void Panic(TMemModelPanic aPanic);
  1063 	};
  1064 
  1065 
  1066 
  1067 template <class T>
  1068 FORCE_INLINE void FlagSet(T& a,const T b)
  1069 	{ a = (T)(a|b); }
  1070 
  1071 template <class T>
  1072 FORCE_INLINE void FlagSet(T& a,const T b,const T c)
  1073 	{ a = (T)(a|b|c); }
  1074 
  1075 template <class T>
  1076 FORCE_INLINE void FlagSet(T& a,const T b,const T c,const T d)
  1077 	{ a = (T)(a|b|c|d); }
  1078 
  1079 template <class T>
  1080 FORCE_INLINE void FlagClear(T& a,const T b)
  1081 	{ a = (T)(a&~b); }
  1082 
  1083 template <class T>
  1084 FORCE_INLINE void FlagClear(T& a,const T b,const T c)
  1085 	{ a = (T)(a&~b&~c); }
  1086 
  1087 template <class T>
  1088 FORCE_INLINE void FlagClear(T& a,const T b,const T c,const T d)
  1089 	{ a = (T)(a&~b&~c&~d); }
  1090 
  1091 
  1092 #include <memmodel/epoc/mmubase/kblockmap.h>
  1093 
  1094 /**
  1095 Structure containing the information about a demand paged code segment
  1096 which is required to load and fixup its code section.
  1097 */
  1098 class TPagedCodeInfo
  1099 	{
  1100 public:
  1101 	~TPagedCodeInfo();
  1102 	TInt ReadBlockMap(const TCodeSegCreateInfo& aInfo);
  1103 	TInt ReadFixupTables(const TCodeSegCreateInfo& aInfo);
  1104 	void ApplyFixups(TLinAddr aBuffer, TUint iIndex);
  1105 public:
  1106 	TBool iLoaded;						///< True once initial loading has finished and paging should start applying fixups.
  1107 	TUint iCodeRelocTableSize;			///< Size, in bytes, of #iCodeRelocTable.
  1108 	TUint8* iCodeRelocTable;			///< Code relocation information.
  1109 	TUint iImportFixupTableSize;		///< Size, in bytes, of #iImportFixupTable.
  1110 	TUint8* iImportFixupTable;			///< Import fixup information.
  1111 	TUint32 iCodeDelta;					///< Delta to apply to relocate words referring to the code section.
  1112 	TUint32 iDataDelta;					///< Delta to apply to relocate words referring to the data section.
  1113 
  1114 	TUint iCodeSize;					///< Size, in bytes, of the code section.
  1115 	TUint32 iCompressionType;			///< Compression scheme in use, (KUidCompressionBytePair or KFormatNotCompressed).
  1116 	TInt32* iCodePageOffsets;			///< Array of compressed page offsets within the file.
  1117 	TInt iCodeLocalDrive;				///< Local drive number.
  1118 	TInt iCodeStartInFile;				///< Offset of (possibly compressed) code from start of file.
  1119 	TBlockMap iBlockMap;				///< Kernel-side representation of block map.
  1120 	};
  1121 
  1122 
  1123 
  1124 /**
  1125 A pool of DMutex objects that can be dynamically assigned for use.
  1126 
  1127 This is intended as a memory saving alternative to having each object in a class of objects
  1128 owning their own mutex for locking purposes and provides a concurrency improvement over using
  1129 a single global lock.
  1130 */
  1131 class DMutexPool : public DBase
  1132 	{
  1133 public:
  1134 	/**
  1135 	@param aCount	Number of mutexes to allocated in the pool.
  1136 					Must be smaller than #EMaxPoolSize.
  1137 	@param aName	Base name for mutexes. Each mutex in the pool has a number appended to this base name.
  1138 	@param aOrder	A value representing the order of the mutex with respect to deadlock prevention.
  1139 	*/
  1140 	TInt Create(TUint aCount, const TDesC* aName, TUint aOrder);
  1141 
  1142 	~DMutexPool();
  1143 
  1144 	/**
  1145 	Wait on the mutex specified by \a aMutexRef.
  1146 
  1147 	If \a aMutexRef contains the null pointer then a member of this pool is selected and waited on,
  1148 	and \a aMutexRef is set to a cookie value identifying that mutex; this cookie has its least
  1149 	significant bit set to distinguish it from a normal DMutex pointer. Subsequent concurrent
  1150 	Wait operations will use the same pool mutex; possibly modifying the value of the cookie.
  1151 	*/
  1152 	void Wait(DMutex*& aMutexRef);
  1153 
  1154 	/**
  1155 	Signal the mutex specified by \a aMutexRef.
  1156 
  1157 	If mutex is identified as one from this pool then the value of \a aMutexRef will be modified
  1158 	and if there are no pending Wait operations it will be set to the null pointer to indicate
  1159 	that no mutex is assigned.
  1160 	*/
  1161 	void Signal(DMutex*& aMutexRef);
  1162 
  1163 	/**
  1164 	Return true if the mutex specified by \a aMutexRef is held by the current thread.
  1165 	*/
  1166 	TBool IsHeld(DMutex*& aMutexRef);
  1167 
  1168 	enum
  1169 		{
  1170 		/** Maximum number of mutexes allowed in a pool. */
  1171 		EMaxPoolSize = 64
  1172 		};
  1173 
  1174 private:
  1175 	/** Structure for storing information about each member of the pool. */
  1176 	struct SMember
  1177 		{
  1178 		DMutex* iMutex;		///< The mutex
  1179 		TUint iUseCount;	///< Number of times this mutex has been used
  1180 		};
  1181 	TUint iCount;		///< Number of mutexes in pool. (Number of entries in iMembers).
  1182 	TUint iNext;		///< Index of next pool mutex to use.
  1183 	SMember* iMembers;	///< Info about each memory of pool.
  1184 	};
  1185 
  1186 
  1187 #endif