os/kernelhwsrv/kernel/eka/memmodel/epoc/flexible/mmu/mmanager.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 MMANAGER_H
    22 #define MMANAGER_H
    23 
    24 #include "mpagearray.h"
    25 
    26 
    27 class DMemoryObject;
    28 class DMemoryMappingBase;
    29 class DPageReadRequest;
    30 class DPageWriteRequest;
    31 
    32 /**
    33 An abstract interface for performing operations on a memory object, such as allocating
    34 or freeing memory.
    35 
    36 There are different concrete implementations of this class for memory being managed in
    37 different ways, e.g. demand paged versus unpaged memory.
    38 
    39 Any particular instance of a manager will only support a subset of the methods provided.
    40 The default implementations of these in this base class return KErrErrNotSupported.
    41 */
    42 class DMemoryManager : public DBase
    43 	{
    44 public:
    45 	/**
    46 	Create a new memory object for use with this manager.
    47 
    48 	@param[out]	aMemory	On success this is set to the address of the created memory object.
    49 	@param aSizeInPages	Size of the memory object, in number of pages.
    50 	@param aAttributes	Bitmask of values from enum #TMemoryAttributes.
    51 	@param aCreateFlags	Bitmask of option flags from enum #TMemoryCreateFlags.
    52 
    53 	@return KErrNone if successful, otherwise one of the system wide error codes.
    54 	*/
    55 	virtual TInt New(DMemoryObject*& aMemory, TUint aSizeInPages, TMemoryAttributes aAttributes, TMemoryCreateFlags aCreateFlags);
    56 
    57 	/**
    58 	Remove all memory from a memory object and close a reference on it.
    59 
    60 	If there are no longer any mappings to the memory, or other references,
    61 	this will result in the memory object being destroyed. However whilst
    62 	other references exist, cleanup of memory and other resources may be
    63 	delayed indefinitely.
    64 
    65 	@param aMemory		A memory object associated with this manager.
    66 	*/
    67 	virtual void Destruct(DMemoryObject* aMemory) =0;
    68 
    69 	/**
    70 	Allocate memory resources for a specified region of a memory object.
    71 
    72 	Depending on the manager, this may involve allocating physical RAM pages or
    73 	reserving space in a backing store.
    74 
    75 	@param aMemory		A memory object associated with this manager.
    76 	@param aIndex		Page index for the start of the region.
    77 	@param aCount		Number of pages in the region.
    78 
    79 	@return KErrNone if successful,
    80 			KErrAlreadyExists if any part of the region was already allocated,
    81 			KErrNotSupported if the manager doesn't support this function,
    82 			otherwise one of the system wide error codes.
    83 	*/
    84 	virtual TInt Alloc(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
    85 
    86 	/**
    87 	Allocate physically contiguous RAM for a specified region of a memory object.
    88 
    89 	Important note, this function can unexpectedly fail with KErrAlreadyExists
    90 	if any part of the the region previously contained allocated memory which
    91 	had been freed but which was pinned. It is therefore not suitable for general
    92 	use.
    93 
    94 	@param aMemory			A memory object associated with this manager.
    95 	@param aIndex			Page index for the start of the region.
    96 	@param aCount			Number of pages in the region.
    97 	@param aAlign			Log2 of the alignment (in bytes) that the address of the
    98 							allocated physical RAM must have.
    99 	@param[out] aPhysAddr	On success, this is set to the start address of the
   100 							allocated physical RAM.
   101 
   102 	@return KErrNone if successful,
   103 			KErrAlreadyExists if any part of the region was already allocated,
   104 			KErrNotSupported if the manager doesn't support this function,
   105 			otherwise one of the system wide error codes.
   106 	*/
   107 	virtual TInt AllocContiguous(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TUint aAlign, TPhysAddr& aPhysAddr);
   108 
   109 	/**
   110 	Free any memory resources used for a specified region of a memory object.
   111 	This is the inverse operation to #Alloc and #AllocContiguous.
   112 
   113 	Depending on the manager, this may involve freeing space in a backing store
   114 	as well as freeing any currently committed RAM.
   115 
   116 	If part of the memory is currently pinned then resource freeing may be delayed
   117 	indefinitely.
   118 
   119 	@param aMemory		A memory object associated with this manager.
   120 	@param aIndex		Page index for the start of the region.
   121 	@param aCount		Number of pages in the region.
   122 	*/
   123 	virtual void Free(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
   124 
   125 	/**
   126 	Wipe the entire memory contents of the memory object so they are in the
   127 	same state as if the memory had been newly allocated with #Alloc.
   128 
   129 	This doesn't allocate any new memory, just fills the existing contents
   130 	with the appropriate wipe byte which is used with the memory object.
   131 
   132 	@param aMemory	A memory object associated with this manager.
   133 
   134 	@see EMemoryCreateUseCustomWipeByte
   135 	@see EMemoryCreateNoWipe
   136 
   137 	@return KErrNone, if successful;
   138 			otherwise KErrNotSupported, to indicate the memory object doesn't support this operation.
   139 	*/
   140 	virtual TInt Wipe(DMemoryObject* aMemory);
   141 
   142 	/**
   143 	Add a specified set of physical memory pages to a region of a memory object.
   144 
   145 	@param aMemory		A memory object associated with this manager.
   146 	@param aIndex		Page index for the start of the region.
   147 	@param aCount		Number of pages in the region.
   148 	@param aPages		Pointer to array of pages to add. This must contain \a aCount
   149 						number of physical page addresses which are each page aligned.
   150 
   151 	@return KErrNone if successful,
   152 			KErrAlreadyExists if any part of the region was already allocated,
   153 			KErrNotSupported if the manager doesn't support this function,
   154 			otherwise one of the system wide error codes.
   155 	*/
   156 	virtual TInt AddPages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages);
   157 
   158 	/**
   159 	Add a contiguous range of physical memory pages to a region of a memory object.
   160 
   161 	@param aMemory		A memory object associated with this manager.
   162 	@param aIndex		Page index for the start of the region.
   163 	@param aCount		Number of pages in the region.
   164 	@param aPhysAddr	The page aligned start address of the pages to be added.
   165 
   166 	@return KErrNone if successful,
   167 			KErrAlreadyExists if any part of the region was already allocated,
   168 			KErrNotSupported if the manager doesn't support this function,
   169 			otherwise one of the system wide error codes.
   170 	*/
   171 	virtual TInt AddContiguous(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr aPhysAddr);
   172 
   173 	/**
   174 	Remove the memory pages from a specified region of a memory object.
   175 	This is the inverse operation to #AddPages and #AddContiguous.
   176 
   177 	@param aMemory		A memory object associated with this manager.
   178 	@param aIndex		Page index for the start of the region.
   179 	@param aCount		Number of pages in the region.
   180 	@param[out] aPages	Pointer to an array of physical addresses which has a
   181 						length of \a aCount. The contents of this will be set to
   182 						the addresses of the pages which were removed by this
   183 						function. The number of valid entries in this array is
   184 						given by the return value of this function.
   185 						aPages may be the null-pointer, to indicate that these
   186 						page addresses aren't required by the caller.
   187 
   188 	@return The number of pages successfully removed from the memory object.
   189 			This gives the number of valid entries in the array \a aPages and is
   190 			less-than or equal to \a aCount.
   191 	*/
   192 	virtual TInt RemovePages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages);
   193 
   194 	/**
   195 	Mark the specified region of a memory object as discardable.
   196 	The system may remove discardable pages from the memory object at any time,
   197 	to be reused for other purposes.
   198 
   199 	@param aMemory		A memory object associated with this manager.
   200 	@param aIndex		Page index for the start of the region.
   201 	@param aCount		Number of pages in the region.
   202 
   203 	@return KErrNone if successful,
   204 			KErrNotSupported if the manager doesn't support this function,
   205 			otherwise one of the system wide error codes.
   206 	*/
   207 	virtual TInt AllowDiscard(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
   208 
   209 	/**
   210 	Mark the specified region of a memory object as no longer discardable.
   211 	This undoes the operation of #AllowDiscard.
   212 
   213 	If any pages in the region are no longer present, then the operation will
   214 	fail with KErrNotFound. In this case, the state of the pages in the region
   215 	is indeterminate; they may be either still discardable, not discardable, or
   216 	not present.
   217 
   218 	@param aMemory		A memory object associated with this manager.
   219 	@param aIndex		Page index for the start of the region.
   220 	@param aCount		Number of pages in the region.
   221 
   222 	@return KErrNone if successful,
   223 			KErrNotFound if any page in the region was no longer present,
   224 			KErrNotSupported if the manager doesn't support this function,
   225 			otherwise one of the system wide error codes.
   226 	*/
   227 	virtual TInt DisallowDiscard(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
   228 
   229 	/**
   230 	Remove a page of RAM from a memory object.
   231 
   232 	This is only intended for use by #DPager::StealPage when it removes a page
   233 	from the demand paging live list.
   234 
   235 	@param aMemory		A memory object associated with this manager.
   236 	@param aPageInfo	The page information structure of the page to be stolen.
   237 						This must be owned by \a aMemory.
   238 
   239 	@return KErrNone if successful,
   240 			KErrInUse if the page became pinned or was subject to a page fault,
   241 			KErrNotSupported if the manager doesn't support this function,
   242 			otherwise one of the system wide error codes.
   243 
   244  	@pre RamAllocLock held.
   245 	@pre MmuLock held.
   246 	*/
   247 	virtual TInt StealPage(DMemoryObject* aMemory, SPageInfo* aPageInfo);
   248 
   249 	/**
   250 	Restrict the access permissions for a page of RAM.
   251 
   252 	This is only intended for use by #DPager::RestrictPage when it restricts
   253 	access to a page in the demand paging live list.
   254 
   255 	@param aMemory		A memory object associated with this manager.
   256 	@param aPageInfo	The page information structure of the page to be restricted.
   257 						This must be owned by \a aMemory.
   258 	@param aRestriction	The restriction type to apply.
   259 
   260 	@return KErrNone if successful,
   261 			KErrInUse if the page state changed, e.g. became pinned or was subject to a page fault,
   262 			KErrNotSupported if the manager doesn't support this function,
   263 			otherwise one of the system wide error codes.
   264 	*/
   265 	virtual TInt RestrictPage(DMemoryObject* aMemory, SPageInfo* aPageInfo, TRestrictPagesType aRestriction);
   266 
   267 	/**
   268 	Clean a page of RAM by saving any modifications to it out to backing store.
   269 
   270 	This function must only be called when there are no writable MMU mappings of the page.
   271 
   272 	The function must only return a success after determining no writable MMU mappings
   273 	were created for the page, in which case it should also mark the page as clean using
   274 	SPageInfo::SetClean.
   275 
   276 	This is only intended for use by #StealPage.
   277 
   278 	@param aMemory			A memory object associated with this manager.
   279 	@param aPageInfo		The page information structure of the page to be cleaned.
   280 							This must be owned by \a aMemory.
   281 	@param aPageArrayEntry	Reference to the page's page array entry in \a aMemory->iPages.
   282 
   283 	@return KErrNone if successful,
   284 			KErrInUse if the page state changed, e.g. became pinned or was subject to a page fault making it writable,
   285 			KErrNotSupported if the manager doesn't support this function,
   286 			otherwise one of the system wide error codes.
   287 
   288 	@pre MmuLock held
   289 	@pre The memory page must not have any writeable MMU mappings.
   290 	@post MmuLock held (but may have been released by this function)
   291 	*/
   292 	virtual TInt CleanPage(DMemoryObject* aMemory, SPageInfo* aPageInfo, TPhysAddr*& aPageArrayEntry);
   293 
   294 	/**
   295 	Process a page fault in memory associated with this manager.
   296 
   297 	This is only intended for use by #DPager::HandlePageFault.
   298 
   299 	@param aMemory				A memory object associated with this manager whose memory was
   300 								accessed by the page fault.
   301 	@param aIndex				Page index, within the memory, at which the page fault occurred.
   302 	@param aMapping				The memory mapping in which the page fault occurred.
   303 	@param aMapInstanceCount	The instance count of the mapping that took the page fault.
   304 	@param aAccessPermissions	Flags from enum #TMappingPermissions indicating the memory
   305 								access permissions used by the page fault. E.g. the #EReadWrite
   306 								flag will be set for a write access.
   307 
   308 	@return KErrNone if the fault was handled successfully and the running program should
   309 			restart at the faulting instruction.
   310 			Otherwise, one of the system wide error codes indicating that the program generating
   311 			the page fault attempted an invalid memory access.
   312 	*/
   313 	virtual TInt HandleFault(	DMemoryObject* aMemory, TUint aIndex, DMemoryMapping* aMapping, 
   314 								TUint aMapInstanceCount, TUint aAccessPermissions);
   315 
   316 	/**
   317 	Pin the region of a memory object covered by a specified memory mapping.
   318 
   319 	This function should ensure that the memory pages covered by the mapping are
   320 	present in the memory object and will not be removed again until an #Unpin
   321 	operation is issued. Additionally, for demand paged memory, the pages
   322 	must be mapped into \a aMapping using DMemoryMappingBase::PageIn.
   323 
   324 	This function is only intended to be called via DMemoryMappingBase::DoPin
   325 	which is itself called from DMemoryMappingBase::Attach.
   326 
   327 	@param aMemory	A memory object associated with this manager.
   328 	@param aMapping	A mapping with the DMemoryMappingBase::EPinned attribute which
   329 					has been attached to \a aMemory.
   330 	@param aPinArgs	The resources to use for pinning. This must have sufficient replacement
   331 					pages allocated to pin every page the mapping covers. Also, the
   332 					value of \a aPinArgs.iReadOnly must be set to correspond to the
   333 					mappings access permissions.
   334 
   335 	@return KErrNone if successful,
   336 			KErrNotFound if any part of the memory to be pinned was not present,
   337 			otherwise one of the system wide error codes.
   338 	*/
   339 	virtual TInt Pin(DMemoryObject* aMemory, DMemoryMappingBase* aMapping, TPinArgs& aPinArgs) =0;
   340 
   341 	/**
   342 	Unpin the region of a memory object covered by a specified memory mapping.
   343 
   344 	This reverses the action of #Pin and is only intended to be called from
   345 	DMemoryMappingBase::Detach.
   346 
   347 	Note, pinning is a reference counting operation, therefore pages must stay
   348 	resident in memory (pinned) until the number of unpinning operations affecting
   349 	them equals the number of pinning operations.
   350 
   351 	@param aMemory	A memory object associated with this manager.
   352 	@param aMapping	A mapping with the DMemoryMappingBase::EPinned attribute which
   353 					has been attached to \a aMemory.
   354 	@param aPinArgs	The resources used for pinning. The replacement pages allocated
   355 					to this will be increased for each page which was became completely
   356 					unpinned.
   357 	*/
   358 	virtual void Unpin(DMemoryObject* aMemory, DMemoryMappingBase* aMapping, TPinArgs& aPinArgs) =0;
   359 
   360 	/**
   361 	@todo
   362 	*/
   363 	virtual TInt MovePage(DMemoryObject* aMemory, SPageInfo* aOldPageInfo, TPhysAddr& aNewPage, TUint aBlockZoneId, TBool aBlockRest);
   364 
   365 	/**
   366 	Return the TZonePageType of the pages that the memory manager can allocate and free.
   367 	*/
   368 	virtual TZonePageType PageType();
   369 
   370 	/**
   371 	Bitmask representing the different cleanup operations which can be performed
   372 	on a memory object. The operations are queued with #QueueCleanup and
   373 	pending operations are stored in each memory object's DMemoryObject::iCleanupFlags.
   374 	*/
   375 	enum TCleanupOperationFlag
   376 		{
   377 		/**
   378 		Execute #DoCleanupDecommitted.
   379 		*/
   380 		ECleanupDecommitted	= 1<<0,
   381 
   382 		/**
   383 		Internal flag which indicates that cleanup has been queued.
   384 		*/
   385 		ECleanupIsQueued	= 1u<<31
   386 		};
   387 
   388 	/**
   389 	Queue a cleanup operation to run for a specified memory object.
   390 
   391 	The operations are run from #CleanupFunction which is called
   392 	from a #TMemoryCleanup callback.
   393 
   394 	@param aMemory		The memory object.
   395 	@param aCleanupOp	The operation to perform.
   396 	*/
   397 	static void QueueCleanup(DMemoryObject* aMemory, TCleanupOperationFlag aCleanupOp);
   398 
   399 protected:
   400 
   401 	/**
   402 	Unmap and free the RAM pages used for a specified region of a memory object.
   403 
   404 	Successfully freed pages are returned to the system's free RAM pool.
   405 	However, pinned pages are placed in the decommitted state
   406 	(RPageArray::EDecommitted) and remain allocated to the memory object.
   407 	These decommitted pages may ultimately get freed by #FreeDecommitted
   408 	or they may become re-allocated with #ReAllocDecommitted.
   409 
   410 	@param aMemory		A memory object associated with this manager.
   411 	@param aIndex		Page index for the start of the region.
   412 	@param aCount		Number of pages in the region.
   413 	*/
   414 	static void DoFree(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
   415 
   416 	/**
   417 	Re-allocate all decommitted but still present RAM pages in a region of a memory object.
   418 
   419 	When pinned memory is freed from a memory object it is placed in the
   420 	RPageArray::EDecommitted state. This function is called by #Alloc to place
   421 	all such memory back into the committed state as if it had been newly allocated.
   422 
   423 	@param aMemory		A memory object associated with this manager.
   424 	@param aIndex		Page index for the start of the region.
   425 	@param aCount		Number of pages in the region.
   426 	*/
   427 	static void ReAllocDecommitted(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
   428 
   429 	/**
   430 	Attempt to free all decommitted but still present RAM pages in a region of a memory object.
   431 
   432 	When pinned memory is freed from a memory object it is placed in the
   433 	RPageArray::EDecommitted state. This function is called by #DoCleanupDecommitted
   434 	to attempt to fully free this memory if it is no longer pinned.
   435 
   436 	@param aMemory		A memory object associated with this manager.
   437 	@param aIndex		Page index for the start of the region.
   438 	@param aCount		Number of pages in the region.
   439 	*/
   440 	static void FreeDecommitted(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
   441 
   442 	/**
   443 	Implementation factor for #FreeDecommitted and #DoFree.
   444 	*/
   445 	static TInt FreePages(DMemoryObject* aMemory, RPageArray::TIter aPageList);
   446 
   447 	/**
   448 	Cleanup any decommitted memory associated with a memory object.
   449 
   450 	This is called for memory objects which were queued for cleanup (#QueueCleanup)
   451 	with the #ECleanupDecommitted operation. A manager class must override this method
   452 	if it triggers this cleanup type - the default implementation faults in debug builds.
   453 
   454 	@param aMemory The memory object requiring cleanup.
   455 	*/
   456 	virtual void DoCleanupDecommitted(DMemoryObject* aMemory);
   457 
   458 private:
   459 	/**
   460 	Callback function which executes all pending operations queued with #QueueCleanup.
   461 	*/
   462 	static void CleanupFunction(TAny*);
   463 
   464 	/**
   465 	Head of a singly linked list of memory objects which require a cleanup operation.
   466 	Each object in the list is linked using its DMemoryObject::iCleanupNext member.
   467 	@see #QueueCleanup
   468 	*/
   469 	static DMemoryObject* iCleanupHead;
   470 
   471 	/**
   472 	Spinlock used during memory cleanup operations to protect object list (#iCleanupHead
   473 	and DMemoryObject::iCleanupNext) and operation flags (DMemoryObject::iCleanupFlags).
   474 	*/
   475 	static TSpinLock iCleanupLock;
   476 	};
   477 
   478 
   479 
   480 /**
   481 The bass class for memory managers implementing the different forms of demand paging.
   482 The provides the common functions required to 'page in' and 'page out' memory.
   483 */
   484 class DPagedMemoryManager : public DMemoryManager
   485 	{
   486 public:
   487 	// from DMemoryManager...
   488 	virtual TInt New(DMemoryObject*& aMemory, TUint aSizeInPages, TMemoryAttributes aAttributes, TMemoryCreateFlags aCreateFlags);
   489 	virtual void Destruct(DMemoryObject* aMemory);
   490 	virtual TInt MovePage(DMemoryObject* aMemory, SPageInfo* aOldPageInfo, TPhysAddr& aNewPage, TUint aBlockZoneId, TBool aBlockRest);
   491 	virtual TInt StealPage(DMemoryObject* aMemory, SPageInfo* aPageInfo);
   492 	virtual TInt RestrictPage(DMemoryObject* aMemory, SPageInfo* aPageInfo, TRestrictPagesType aRestriction);
   493 	virtual TInt HandleFault(	DMemoryObject* aMemory, TUint aIndex, DMemoryMapping* aMapping, 
   494 								TUint aMapInstanceCount, TUint aAccessPermissions);
   495 	virtual TInt Pin(DMemoryObject* aMemory, DMemoryMappingBase* aMapping, TPinArgs& aPinArgs);
   496 	virtual void Unpin(DMemoryObject* aMemory, DMemoryMappingBase* aMapping, TPinArgs& aPinArgs);
   497 
   498 	/**
   499 	Called by DPager::Init3 during third stage initialisation.
   500 	*/
   501 	virtual void Init3() = 0;
   502 
   503 	/**
   504 	Called by Kern::InstallPagingDevice to notify memory managers when a paging device
   505 	is installed. A manager requires use of these paging devices to access storage media
   506 	where demand paged content is stored.
   507 	*/
   508 	virtual TInt InstallPagingDevice(DPagingDevice* aDevice) = 0;
   509 
   510 protected:
   511 
   512 	/**
   513 	Acquire a request object suitable for issuing to #ReadPages to
   514 	obtain the data content of a specified region of a memory object.
   515 
   516 	Once the request object is finished with it must be released (DPagingRequest::Release).
   517 
   518 	Typically this function is implemented by calling DPagingRequestPool::AcquirePageReadRequest
   519 	on the request pool of the paging device appropriate to the memory object.
   520 
   521 	@param[out] aRequest	On success this is set to the address of the request object.
   522 	@param aMemory			A memory object associated with this manager.
   523 	@param aIndex			Page index for the start of the region.
   524 	@param aCount			Number of pages in the region.
   525 
   526 	@return KErrNone if successful,
   527 			otherwise one of the system wide error codes.
   528 	*/
   529 	virtual TInt AcquirePageReadRequest(DPageReadRequest*& aRequest, DMemoryObject* aMemory, TUint aIndex, TUint aCount) = 0;
   530 
   531 	/**
   532 	Acquire a request object suitable for issuing to #WritePages to
   533 	save the data content of a specified region of a memory object.
   534 
   535 	Once the request object is finished with it must be released (DPagingRequest::Release).
   536 
   537 	Typically this function is implemented by calling DPagingRequestPool::AcquirePageWriteRequest
   538 	on the request pool of the paging device appropriate to the memory object.
   539 
   540 	@param[out] aRequest	On success this is set to the address of the request object.
   541 	@param aMemory			A memory object associated with this manager.
   542 	@param aIndex			Page index for the start of the region.
   543 	@param aCount			Number of pages in the region.
   544 
   545 	@return KErrNone if successful,
   546 			otherwise one of the system wide error codes.
   547 	*/
   548 	virtual TInt AcquirePageWriteRequest(DPageWriteRequest*& aRequest, DMemoryObject* aMemory, TUint aIndex, TUint aCount);
   549 
   550 	/**
   551 	Obtain the data content of a specified region of a memory object by reading it from
   552 	storage media.
   553 
   554 	The memory region must be the same as, or a subset of, the region used when obtaining
   555 	the request object \a aRequest.
   556 
   557 	@param aMemory	A memory object associated with this manager.
   558 	@param aIndex	Page index for the start of the region.
   559 	@param aCount	Number of pages in the region.
   560 	@param aPages	Pointer to array of pages to read into. This must contain \a aCount
   561 					number of physical page addresses which are each page aligned.
   562 	@param aRequest	A request object previously obtained with #AcquirePageReadRequest.
   563 
   564 	@return KErrNone if successful,
   565 			otherwise one of the system wide error codes.
   566 	*/
   567 	virtual TInt ReadPages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages, DPageReadRequest* aRequest) =0;
   568 
   569 	/**
   570 	Save the data content of a specified region of a memory object by writing it to
   571 	storage media. This is intended for use by an implementation of #CleanPage.
   572 
   573 	The memory region must be the same as, or a subset of, the region used when obtaining
   574 	the request object \a aRequest.
   575 
   576 	@param aMemory	A memory object associated with this manager.
   577 	@param aIndex	Page index for the start of the region.
   578 	@param aCount	Number of pages in the region.
   579 	@param aPages	Pointer to array of pages to read into. This must contain \a aCount
   580 					number of physical page addresses which are each page aligned.
   581 	@param aRequest	A request object previously obtained with #AcquirePageWriteRequest.
   582 
   583 	@return KErrNone if successful,
   584 			otherwise one of the system wide error codes.
   585 	*/
   586 	virtual TInt WritePages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages, DPageWriteRequest* aRequest);
   587 
   588 	/**
   589 	Check if a region of a memory object has been allocated. E.g. that #Alloc
   590 	has reserved backing store for the memory and this has has not yet been freed
   591 	by #Free or #Destruct.
   592 
   593 	@param aMemory	A memory object associated with this manager.
   594 	@param aIndex	Page index for the start of the region.
   595 	@param aCount	Number of pages in the region.
   596 
   597 	@return True if the whole region has allocated storage, false otherwise.
   598 
   599 	@pre #MmuLock held.
   600 	@post #MmuLock held and must not have been released by this function.
   601 	*/
   602 	virtual TBool IsAllocated(DMemoryObject* aMemory, TUint aIndex, TUint aCount) =0;
   603 
   604 protected:
   605 	/**
   606 	Do the action of #Pin for a subregion of a memory mapping.
   607 	This is an implementation factor used to implement #Pin.
   608 
   609 	@param aMemory	A memory object associated with this manager.
   610 	@param aIndex	Page index for the start of the region.
   611 	@param aCount	Number of pages in the region.
   612 	@param aMapping	A mapping with the DMemoryMappingBase::EPinned attribute which
   613 					has been attached to \a aMemory.
   614 	@param aPinArgs	The resources to use for pinning. This must have sufficient replacement
   615 					pages allocated to pin every page the mapping covers, and the
   616 					value of \a aPinArgs.iReadOnly must be set to correspond to the
   617 					mappings access permissions.
   618 
   619 	@return KErrNone if successful,
   620 			KErrNotFound if any part of the memory to be pinned was not present,
   621 			otherwise one of the system wide error codes.
   622 	*/
   623 	TInt DoPin(DMemoryObject* aMemory, TUint aIndex, TUint aCount, DMemoryMappingBase* aMapping, TPinArgs& aPinArgs);
   624 
   625 	/**
   626 	Update a single page in a memory object during memory pinning handling.
   627 
   628 	This includes assigning a new physical page of RAM to the memory object (optional)
   629 	then updating the pages state to ensure that it is pinned i.e. doesn't take
   630 	part in demand paging until unpinned again.
   631 
   632 	This is called from #DoPin.
   633 
   634 	@param aMemory			A memory object associated with this manager.
   635 	@param aIndex			Page index, within the memory, for the page.
   636 	@param aPageInfo		The page information structure of the new physical page
   637 							to assign to the \a aMemory. If there was an existing
   638 							assigned page this new page is freed back to the paging
   639 							system. Specifying a new page is optional, use the null-pointer
   640 							to indicate its absence.
   641 	@param aPageArrayEntry	Reference to the page's page array entry in \a aMemory->iPages.
   642 	@param aPinArgs			The resources to use for pinning. This must a replacement
   643 							pages allocated.
   644 
   645 	@return 1 (one) if the new page was assigned to the memory object.
   646 	@return 0 (zero) if a page already existed at the specified index.
   647 	@return KErrNotFound if there no page could be assigned, either because
   648 			none was given, or because memory is in the process of being
   649 			decommitted from the memory object.
   650 
   651 	@pre #MmuLock held.
   652 	*/
   653 	virtual TInt PageInPinnedDone(DMemoryObject* aMemory, TUint aIndex, SPageInfo* aPageInfo, TPhysAddr* aPageArrayEntry, TPinArgs& aPinArgs);
   654 
   655 	/**
   656 	Implementation factor for #PageInDone and #PageInPinnedDone.
   657 
   658 	@pre #MmuLock held.
   659 	@post #MmuLock held and must not have been released by this function.
   660 	*/
   661 	TInt DoPageInDone(DMemoryObject* aMemory, TUint aIndex, SPageInfo*& aPageInfo, TPhysAddr* aPageArrayEntry, TBool aPinning);
   662 
   663 	/**
   664 	Do the action of #Unpin for a subregion of a memory mapping.
   665 	This is an implementation factor used to implement #Unpin.
   666 
   667 	Must only be used for memory pages already successfully pinned.
   668 
   669 	@param aMemory	A memory object associated with this manager.
   670 	@param aIndex	Page index for the start of the region.
   671 	@param aCount	Number of pages in the region.
   672 	@param aMapping	A mapping with the DMemoryMappingBase::EPinned attribute which
   673 					has been attached to \a aMemory.
   674 	@param aPinArgs	The resources used for pinning. The replacement pages allocated
   675 					to this will be increased for each page which was became completely
   676 					unpinned.
   677 	*/
   678 	virtual void DoUnpin(DMemoryObject* aMemory, TUint aIndex, TUint aCount, DMemoryMappingBase* aMapping, TPinArgs& aPinArgs);
   679 
   680 	// from DMemoryManager...
   681 	virtual void DoCleanupDecommitted(DMemoryObject* aMemory);
   682 	virtual TZonePageType PageType();
   683 
   684 	/**
   685 	Decompress demand paged data.
   686 
   687 	The compression types supported are:
   688 	- Byte-Pair, specified with a compression type of
   689 	  SRomPageInfo::EBytePair or KUidCompressionBytePair.
   690 	- No Compression, specified with a compression type of zero.
   691 
   692 	@param aCompressionType 	The type of decompression to use.
   693 	@param aDst					The destination address of the decompressed data.
   694 	@param aDstBytes			The expected size of the data once it is decompressed.
   695 	@param aSrc					The address for the data to decompress.
   696 	@param aSrcBytes			The size of the data to decompress.
   697 
   698 	@return The size of decompressed data in bytes or one of the system wide error codes.
   699 	*/
   700 	TInt Decompress(TUint32 aCompressionType, TLinAddr aDst, TUint aDstBytes, TLinAddr aSrc, TUint aSrcBytes);
   701 
   702 private:
   703 	/**
   704 	Update a single page in a memory object during page fault handling.
   705 
   706 	This includes assigning a new physical page of RAM to the memory object (optional)
   707 	then updating the demand paging live list to reflect the fact that the memory page
   708 	was newly accessed.
   709 
   710 	This is called from #HandleFault.
   711 
   712 	@param aMemory			A memory object associated with this manager.
   713 	@param aIndex			Page index, within the memory, for the page.
   714 	@param aPageInfo		The page information structure of the new physical page
   715 							to assign to the \a aMemory. If there was an existing
   716 							assigned page this new page is freed back to the paging
   717 							system. Specifying a new page is optional, use the null-pointer
   718 							to indicate its absence.
   719 	@param aPageArrayEntry	Reference to the page's page array entry in \a aMemory->iPages.
   720 
   721 	@return 1 (one) if the new page was assigned to the memory object.
   722 	@return 0 (zero) if a page already existed at the specified index.
   723 	@return	KErrNotFound if there no page could be assigned, either because
   724 			none was given, or because memory is in the process of being
   725 			decommitted from the memory object.
   726 
   727 	@pre #MmuLock held.
   728 	*/
   729 	TInt PageInDone(DMemoryObject* aMemory, TUint aIndex, SPageInfo* aPageInfo, TPhysAddr* aPageArrayEntry);
   730 	};
   731 
   732 
   733 
   734 extern DMemoryManager* TheUnpagedMemoryManager;			///< The #DUnpagedMemoryManager
   735 extern DMemoryManager* TheMovableMemoryManager;			///< The #DMovableMemoryManager
   736 extern DMemoryManager* TheDiscardableMemoryManager;		///< The #DDiscardableMemoryManager
   737 extern DMemoryManager* TheHardwareMemoryManager;		///< The #DHardwareMemoryManager
   738 extern DPagedMemoryManager* TheRomMemoryManager;		///< The #DRomMemoryManager
   739 extern DPagedMemoryManager* TheDataPagedMemoryManager;	///< The #DDataPagedMemoryManager
   740 extern DPagedMemoryManager* TheCodePagedMemoryManager;	///< The #DCodePagedMemoryManager
   741 
   742 #endif