First public contribution.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
24 #include "mrefcntobj.h"
25 #include "mmappinglist.h"
26 #include "mpagearray.h"
33 Base class for memory objects.
35 A memory object is a sparse array of memory pages (#iPages) to which memory
36 mappings may be attached (#iMappings). All pages in the array are managed
37 in the same way (#iManager).
39 class DMemoryObject : public DReferenceCountedObject
42 virtual ~DMemoryObject();
45 Claim ownership of memory originally allocated by the bootstrap.
47 This is used during system boot to initialise this object's memory to contain
48 the pages which are already mapped at a given region of virtual addresses.
50 For coarse memory objects, this function also takes ownership of the page tables
51 being used to map the memory.
53 @param aBase Starting virtual address of memory to claim.
55 @param aSize Size, in bytes, of memory region to claim.
57 @param aPermissions The access permissions which the memory region
58 is mapped. As well as being required for correct object
59 initialisation this also enables the function to check
60 that the bootstrap code mapped the memory in manner
61 consistent with the flexible memory model implementation.
63 @param aAllowGaps True if the memory region may have gaps (unmapped pages) in it.
64 If false, the function faults if the region is not fully
65 populated with mapped pages.
67 @param aAllowNonRamPages True if the memory region contains memory pages which are
68 not RAM pages known to the kernel. I.e. are not
69 contained in the list of RAM banks supplied by the bootstrap.
70 Any such memory cannot be never be subsequently freed from the
71 memory object because the kernel can't handle this memory.
73 @return KErrNone if successful, otherwise one of the system wide error codes.
75 virtual TInt ClaimInitialPages(TLinAddr aBase, TUint aSize, TMappingPermissions aPermissions, TBool aAllowGaps=false, TBool aAllowNonRamPages=false) = 0;
78 Update the page table entries for all attached mappings to add entries for
79 a specified set of memory pages.
81 This method is called by this object's manager whenever new pages of memory are added.
83 @param aPages An RPageArray::TIter which refers to a range of pages
84 in this memory object.
85 Only array entries which have state RPageArray::ECommitted
86 should be mapped into a mapping's page tables.
88 @return KErrNone if successful, otherwise one of the system wide error codes.
90 virtual TInt MapPages(RPageArray::TIter aPages);
93 Update the page table entries for all attached mappings to add new entry for
94 a specified memory page.
96 This method is called by this object's manager whenever the page is moved.
98 @param aPageArray The page array entry of the page in this memory object.
99 Only array entries which have state RPageArray::ECommitted
100 should be mapped into a mapping's page tables.
102 @param aIndex The index of the page in this memory object.
104 @param aInvalidateTLB Set to ETrue when the TLB entries associated with this page
105 should be invalidated. This must be done when there is
106 already a valid pte for this page, i.e. if the page is still
109 @return KErrNone if successful, otherwise one of the system wide error codes.
111 virtual void RemapPage(TPhysAddr& aPageArray, TUint aIndex, TBool aInvalidateTLB);
114 Update the page table entries for all attached mappings to remove entries for
115 a specified set of memory pages.
117 This method is called this object's manager whenever pages of memory are removed.
119 @param aPages An RPageArray::TIter which refers to a range of pages
120 in this memory object.
121 Only array entries which return true for
122 RPageArray::TargetStateIsDecommitted should be unmapped
123 from a mapping's page tables.
125 @param aDecommitting True if memory is being permanently decommitted from
126 the memory object. False if the memory pages are only
127 temporarily being unmapped due to a demand paging 'page out'
130 virtual void UnmapPages(RPageArray::TIter aPages, TBool aDecommitting);
133 Update the page table entries for all attached mappings to apply access restrictions
134 to a specified set of memory pages.
136 This method is called by this object's manager whenever pages of memory are restricted.
138 @param aPages An RPageArray::TIter which refers to a range of pages
139 in this memory object.
140 Only array entries which return true for
141 RPageArray::TargetStateIsDecommitted should be unmapped
142 from a mapping's page tables.
144 @param aRestriction A value from enum #TRestrictPagesType indicating the
145 kind of restriction to apply.
147 virtual void RestrictPages(RPageArray::TIter aPages, TRestrictPagesType aRestriction);
150 Add a memory mapping to this memory object.
152 This is only intended for use by #DMemoryMappingBase::Attach.
154 After verifying that the mapping is permitted (using #CheckNewMapping)
155 the mapping is linked into this objects list of mappings #iMappings.
157 @param aMapping The mapping to add.
159 @return KErrNone if successful,
160 otherwise KErrAccessDenied to indicate that the mapping is not allowed.
162 virtual TInt AddMapping(DMemoryMappingBase* aMapping);
165 Remove a memory mapping from this memory object.
167 This is only intended for use by #DMemoryMappingBase::Detach.
169 This unlinks the mapping from the list of mappings #iMappings.
171 @param aMapping The mapping to remove.
173 virtual void RemoveMapping(DMemoryMappingBase* aMapping);
176 Attempt to set the memory object read only. This will only succeed if
177 there are no writable mappings to the memory object.
179 NOTE - This can't be undone, page moving will break if a memory object
180 is made writable again.
182 @return KErrNone on success, KErrInUse if writable mappings are found.
184 virtual TInt SetReadOnly();
187 Create a mapping object to map this memory.
189 This is only intended for use by #MM::MappingNew.
191 The base class creates a #DFineMapping object. It is overridden by #DCoarseMemory to create a
192 #DCoarseMapping in appropriate circumstances.
194 @param aIndex The index of the start of the mapping into this memory object.
195 @oaram aCount The size in pages of the mapping.
197 virtual DMemoryMapping* CreateMapping(TUint aIndex, TUint aCount);
200 Get the physical address(es) for a region of pages in this memory object.
202 Depending on how the memory is being managed the physical addresses returned
203 may become invalid due to various reasons, e.g.
205 - memory being decommitted from the memory object
206 - ram defragmentation moving the memory contents to a different physical page
207 - paging out of demand paged memory
209 This function should therefore only be used where it is know that these
210 possibilities can't occur, e.g. this is used safely by DPhysicalPinMapping::PhysAddr.
212 @param aIndex Page index, within the memory, for the start of the region.
213 @param aCount Number of pages in the region.
214 @param aPhysicalAddress On success, this value is set to one of two values.
215 If the specified region is physically contiguous,
216 the value is the physical address of the first page
217 in the region. If the region is discontiguous, the
218 value is set to KPhysAddrInvalid.
219 @param aPhysicalPageList If not zero, this points to an array of TPhysAddr
220 objects. On success, this array will be filled
221 with the addresses of the physical pages which
222 contain the specified region. If aPageList is
223 zero, then the function will fail with
224 KErrNotFound if the specified region is not
225 physically contiguous.
227 @return 0 if successful and the whole region is physically contiguous.
228 1 if successful but the region isn't physically contiguous.
229 KErrNotFound, if any page in the region is not present,
230 otherwise one of the system wide error codes.
232 TInt PhysAddr(TUint aIndex, TUint aCount, TPhysAddr& aPhysicalAddress, TPhysAddr* aPhysicalPageList);
235 Check specified region lies entirely within this memory object, and that it
238 TBool CheckRegion(TUint aIndex, TUint aCount);
241 Clip the specified region to lie within the memory object,
243 void ClipRegion(TUint& aIndex, TUint& aCount);
246 Set the mutex used to lock operations on this memory object
248 void SetLock(DMutex* aLock);
251 Prevents any further mappings being added to this memory object.
256 Return the memory attributes for this object's memory.
258 FORCE_INLINE TMemoryAttributes Attributes()
260 return (TMemoryAttributes)iAttributes;
264 Value for initialising SPageInfo::iFlags when allocating pages.
266 FORCE_INLINE TUint8 PageInfoFlags()
272 Value for #Mmu::TRamAllocFlags to use when allocating pages.
274 FORCE_INLINE Mmu::TRamAllocFlags RamAllocFlags()
276 return (Mmu::TRamAllocFlags)iRamAllocFlags;
280 Return true if this object is an instance of #DCoarseMemory.
282 FORCE_INLINE TBool IsCoarse()
284 return iFlags&ECoarseObject;
288 Return true if this object contains memory which is being demand paged.
290 FORCE_INLINE TBool IsDemandPaged()
292 return iFlags&EDemandPaged;
296 Return true if writeable mappings of the memory are not allowed.
298 FORCE_INLINE TBool IsReadOnly()
300 return iFlags&EDenyWriteMappings;
304 Return true if executable mappings allowed on this memory object.
306 FORCE_INLINE TBool IsExecutable()
308 return !(iFlags&EDenyExecuteMappings);
312 Clear the flag that indicates that a mapping has been added.
314 FORCE_INLINE void ClearMappingAddedFlag()
316 __NK_ASSERT_DEBUG(iMappings.LockIsHeld());
317 __e32_atomic_and_ord8(&iFlags, (TUint8)~EMappingAdded);
321 Set the flag to indicate that a mapping has been added.
323 FORCE_INLINE void SetMappingAddedFlag()
325 __NK_ASSERT_DEBUG(iMappings.LockIsHeld());
326 __NK_ASSERT_DEBUG(MmuLock::IsHeld());
327 __e32_atomic_ior_ord8(&iFlags, (TUint8)EMappingAdded);
331 Get the value of the mappings added flags
333 @return ETrue if a mapping has been added, EFalse otherwise.
335 FORCE_INLINE TBool MappingAddedFlag()
337 __NK_ASSERT_DEBUG(MmuLock::IsHeld());
338 return iFlags & (TUint8)EMappingAdded;
344 Maximum number of bits which can be stored in an array entry by SetPagingManagerData.
346 KPagingManagerDataBits = RPageArray::KPagingManagerDataBits
352 Maximum value which can be stored in an array entry by SetPagingManagerData.
354 KMaxPagingManagerData = RPageArray::KMaxPagingManagerData
358 Write \a aValue to the paging manager data for page index \a aIndex.
359 The value must not exceed KMaxPagingManagerData.
360 This must only be used for demand paged memory objects.
362 void SetPagingManagerData(TUint aIndex, TUint aValue);
365 Return the paging manager data for page index \a aIndex.
366 This must only be used for demand paged memory objects.
367 @see SetPagingManagerData
369 TUint PagingManagerData(TUint aIndex);
372 Check that a given memory mapping is allowed to be attached to this memory object.
374 @param aMapping The mapping to check.
376 @return KErrNone if successful,
377 otherwise KErrAccessDenied to indicate that the mapping is not allowed.
379 TInt CheckNewMapping(DMemoryMappingBase* aMapping);
382 Emit BTrace traces identifying the initial attributes of this object.
388 @param aManager The manager object for this memory.
389 @param aFlags Initial value for #iFlags.
390 @param aSizeInPages Size of the memory object, in number of pages.
391 @param aAttributes Bitmask of values from enum #TMemoryAttributes.
392 @param aCreateFlags Bitmask of option flags from enum #TMemoryCreateFlags.
394 DMemoryObject(DMemoryManager* aManager, TUint aFlags, TUint aSizeInPages, TMemoryAttributes aAttributes, TMemoryCreateFlags aCreateFlags);
397 Second phase constructor.
399 @return KErrNone if successful, otherwise one of the system wide error codes.
405 The manager of this memory object.
407 DMemoryManager* iManager;
410 For use by this object's manager (iManager) to store any memory objects specific state
411 it requires to keep track of.
416 For use by DMemoryManager::QueueCleanup to link objects which require a cleanup operation.
417 Access to this is protected by #DMemoryManager::iCleanupLock.
419 DMemoryObject* iCleanupNext;
422 For use by DMemoryManager::QueueCleanup to store flags representing each pending cleanup operation.
423 Access to this is protected by #DMemoryManager::iCleanupLock.
425 TUint32 iCleanupFlags;
428 Bit flags stored in #iFlags giving various state and attributes of the object.
433 Flag set during object construction to indicate that this mapping is of
434 class #DCoarseMemory.
436 ECoarseObject = 1<<0,
439 Flag set during object construction to indicate that the memory for this object
440 is being demand paged in some manner.
445 Flag set during object construction to indicate that all resources for this
446 object are to be reserved during construction; excluding memory pages owned by
447 object. Objects constructed in this way will not require additional memory
448 allocation when committing memory to them (other than allocating the memory
449 pages being committed.)
451 EReserveResources = 1<<2,
454 Flag set during object construction to indicate that pinned memory mappings
455 are not allowed to be attached to this object.
460 Flag set by DenyMappings to indicate that no additional memory mappings
461 are allowed to be attached to this object.
463 EDenyMappings = 1<<4,
466 Flag set during object construction, or by SetReadOnly, to indicate that
467 the memory object is read-only and no writable mappings are allowed
468 to be attached to this object.
470 EDenyWriteMappings = 1<<5,
473 Flag set during object construction to indicate that executable memory mappings
474 are not allowed to be attached to this object.
475 This is mainly an optimisation to allow demand paging to avoid instruction cache
476 maintenance operations during page fault handling.
478 EDenyExecuteMappings = 1<<6,
481 Flag set whenever a new mapping is added to a memory object.
482 The object's mappings lock and MmuLock protects this flag when it is set
483 and the mappings lock protects when it is cleared.
485 EMappingAdded = 1<<7,
494 Value from TMemoryAttributes indicating type of memory in object.
499 #Mmu::TRamAllocFlags value to use when allocating RAM for this memory object.
501 TUint16 iRamAllocFlags;
504 List of mappings currently attached to this object.
506 TMappingList iMappings;
509 Size, in page units, of this memory object.
514 Lock currently being used to serialise explicit memory operations.
515 This is assigned using #MemoryObjectLock.
520 The array of memory pages assigned to this memory object.
528 A memory object which has a size that is an exact multiple
529 multiple of the region covered by a whole MMU page table;
530 that is a 'chunk' size (#KChunkSize) bytes.
532 When used in conjunction with DCoarseMapping this object
533 allows RAM to be saved by sharing MMU page tables between multiple
534 different mappings of the memory.
536 Fine memory mappings (DFineMapping) may also be attached
537 to this memory object but these won't benefit from page table
540 class DCoarseMemory : public DMemoryObject
543 // from DMemoryObject...
544 virtual ~DCoarseMemory();
545 virtual TInt ClaimInitialPages(TLinAddr aBase, TUint aSize, TMappingPermissions aPermissions, TBool aAllowGaps=false, TBool aAllowNonRamPages=false);
546 virtual TInt MapPages(RPageArray::TIter aPages);
547 virtual void RemapPage(TPhysAddr& aPageArray, TUint aIndex, TBool aInvalidateTLB);
548 virtual void UnmapPages(RPageArray::TIter aPages, TBool aDecommitting);
549 virtual void RestrictPages(RPageArray::TIter aPages, TRestrictPagesType aRestriction);
550 virtual TInt AddMapping(DMemoryMappingBase* aMapping);
551 virtual void RemoveMapping(DMemoryMappingBase* aMapping);
552 virtual TInt SetReadOnly();
553 virtual DMemoryMapping* CreateMapping(TUint aIndex, TUint aCount);
556 Create a new DCoarseMemory object.
558 @param aManager The manager object for this memory.
559 @param aSizeInPages Size of the memory object, in number of pages.
560 (Must represent an exact 'chunk' size.)
561 @param aAttributes Bitmask of values from enum #TMemoryAttributes.
562 @param aCreateFlags Bitmask of option flags from enum #TMemoryCreateFlags.
564 @return The newly created DCoarseMemory or the null pointer if there was
567 static DCoarseMemory* New(DMemoryManager* aManager, TUint aSizeInPages, TMemoryAttributes aAttributes, TMemoryCreateFlags aCreateFlags);
570 Remove an mmu page table from this memory object's ownership.
571 This is called when a RAM page containing the page table is paged out.
572 This function delegates its action to DPageTables::StealPageTable.
574 @param aChunkIndex The index of the page table, i.e. the offset, in 'chunks',
575 into the object's memory that the page table is being used to map.
576 (The index into DPageTables::iTables.)
577 @param aPteType The #TPteType the page table is being used for.
578 (The index into #iPageTables.)
580 @pre #MmuLock is held.
581 @pre #PageTablesLockIsHeld
583 void StealPageTable(TUint aChunkIndex, TUint aPteType);
586 // Interface for DCoarseMapping
589 Get the page table to use for mapping a specified chunk if it exists.
591 @param aPteType The #TPteType the page tables will be used for.
592 @param aChunkIndex The index of the chunk.
594 @return The virtual address of the page table, or NULL.
596 @pre #MmuLock is held.
598 TPte* GetPageTable(TUint aPteType , TUint aChunkIndex);
601 Update the page tables to add entries for a specified set of demand paged memory
602 pages following a 'page in' or memory pinning operation.
604 @param aMapping The mapping the pages are being paged into.
606 @param aPages An RPageArray::TIter which refers to a range of pages
607 in the memory object #iMemory.
608 Only array entries which have state RPageArray::ECommitted
609 should be mapped into the page tables.
611 @param aPinArgs The resources required to pin any page tables.
612 Page table must be pinned if \a aPinArgs.iPinnedPageTables is
613 not the null pointer, in which case this the virtual address
614 of the pinned must be stored in the array this points to.
615 \a aPinArgs.iReadOnly is true if write access permissions
618 @return KErrNone if successful, otherwise one of the system wide error codes.
620 @pre #MmuLock is held.
621 @post #MmuLock has been released.
623 TInt PageIn(DCoarseMapping* aMapping, RPageArray::TIter aPages, TPinArgs& aPinArgs, TUint aMapInstanceCount);
626 Update the page table entries to renable access to a specified memory page.
628 This method is called by #DCoarseMapping::MovingPageIn
630 @param aMapping The mapping which maps the page.
631 @param aPageArrayPtr The page array entry of the page to map.
632 Only array entries which have state RPageArray::ECommitted
633 should be mapped into a mapping's page tables.
635 @param aIndex The index of the memory page.
637 TBool MovingPageIn(DCoarseMapping* aMapping, TPhysAddr& aPageArrayPtr, TUint aIndex);
640 Function to return a page table pointer for the specified linear address and
641 index to this mapping.
643 This method is called by #DCoarseMapping::FindPageTable.
645 @param aLinAddr The linear address to find the page table entry for.
646 @param aMemoryIndex The memory object index of the page to find the page
649 @return A pointer to the page table entry, if the page table entry couldn't
650 be found this will be NULL
652 TPte* FindPageTable(DCoarseMapping* aMapping, TLinAddr aLinAddr, TUint aMemoryIndex);
656 For arguments, see #New.
658 DCoarseMemory(DMemoryManager* aManager, TUint aSizeInPages, TMemoryAttributes aAttributes, TMemoryCreateFlags aCreateFlags);
662 The object which manages the page tables owned by a #DCoarseMemory object
663 and used by #DCoarseMapping objects. Each DPageTables is used for mappings
664 with a specific #TPteType e.g. set of memory access permissions, and all these
665 #DCoarseMapping objects are linked into this object whenever they are
666 attached to a DCoarseMemory.
668 class DPageTables : public DReferenceCountedObject
672 Create a new DPageTables.
674 This object is added to DCoarseMemory::iPageTables and all of
675 the mmu page tables will be initialised to map the memory currently
676 owned by the memory object (unless memory is demand paged).
679 @param aMemory The DCoarseMemory the new object is associated with.
680 @param aNumPages Size of the memory object, in number of pages.
681 (Must represent an exact 'chunk' size.)
682 @param aPteType The #TPteType the page tables will be used for.
684 @return The newly created DPageTables or the null pointer if there was
687 @pre The #MemoryObjectLock for the memory must be held by the current thread.
689 static DPageTables* New(DCoarseMemory* aMemory, TUint aNumPages, TUint aPteType);
691 virtual ~DPageTables();
694 Update the page tables to add entries for a specified set of memory pages.
696 This method is called by #DCoarseMemory::MapPages.
698 @param aPages An RPageArray::TIter which refers to a range of pages
699 in the memory object #iMemory.
700 Only array entries which have state RPageArray::ECommitted
701 should be mapped into the page tables.
703 @return KErrNone if successful, otherwise one of the system wide error codes.
705 virtual TInt MapPages(RPageArray::TIter aPages);
708 Update the page table entries for a specified memory page.
710 This method is called by #DCoarseMemory::RemapPage
712 @param aPageArray The page array entry of the page in this memory object.
713 Only array entries which have state RPageArray::ECommitted
714 should be mapped into a mapping's page tables.
716 @param aIndex The index of the page in this memory object.
718 @param aInvalidateTLB Set to ETrue when the TLB entries associated with this page
719 should be invalidated. This must be done when there is
720 already a valid pte for this page, i.e. if the page is still
723 virtual void RemapPage(TPhysAddr& aPageArray, TUint aIndex, TBool aInvalidateTLB);
726 Update the page table entries to renable access to a specified memory page.
728 This method is called by #DCoarseMemory::MovingPageIn
730 @param aPageArrayPtr The page array entry of the page to map.
731 Only array entries which have state RPageArray::ECommitted
732 should be mapped into a mapping's page tables.
734 @param aIndex The index of the memory page.
736 virtual TBool MovingPageIn(TPhysAddr& aPageArrayPtr, TUint aIndex);
740 Update the page tables to remove entries for a specified set of memory pages.
742 This method is called by #DCoarseMemory::UnmapPages.
744 @param aPages An RPageArray::TIter which refers to a range of pages
745 in the memory object #iMemory.
746 Only array entries which return true for
747 RPageArray::TargetStateIsDecommitted should be unmapped
748 from the page tables.
750 @param aDecommitting True if memory is being permanently decommitted from
751 the memory object. False if the memory pages are only
752 temporarily being unmapped due to a demand paging 'page out'
755 virtual void UnmapPages(RPageArray::TIter aPages, TBool aDecommitting);
758 Update the page tables to apply access restrictions to a specified set of memory pages.
760 This method is called by #DCoarseMemory::RestrictPagesNA.
762 @param aPages An RPageArray::TIter which refers to a range of pages
763 in the memory object #iMemory.
764 Only array entries which return true for
765 RPageArray::TargetStateIsDecommitted should be unmapped
766 from the page tables.
768 virtual void RestrictPagesNA(RPageArray::TIter aPages);
771 Update the page tables to add entries for a specified set of demand paged memory
772 pages following a 'page in' or memory pinning operation.
774 @param aPages An RPageArray::TIter which refers to a range of pages
775 in the memory object #iMemory.
776 Only array entries which have state RPageArray::ECommitted
777 should be mapped into the page tables.
779 @param aPinArgs The resources required to pin any page tables.
780 Page table must be pinned if \a aPinArgs.iPinnedPageTables is
781 not the null pointer, in which case this the virtual address
782 of the pinned must be stored in the array this points to.
783 \a aPinArgs.iReadOnly is true if write access permissions
786 @param aMapping The mapping that took the page fault or is being pinned.
788 @param aMapInstanceCount The instance count of the mapping.
790 @return KErrNone if successful, otherwise one of the system wide error codes.
792 virtual TInt PageIn(RPageArray::TIter aPages, TPinArgs& aPinArgs,
793 DMemoryMappingBase* aMapping, TUint aMapInstanceCount);
796 Flush the MMUs TLB entries associated with all attached memory mappings
797 for a specified region of memory pages.
799 This is used by UnmapPages and RestrictPages.
801 @param aStartIndex Page index, within the memory, for start of the region.
802 @param aEndIndex Page index, within the memory, for the first page after
803 the end of the region.
805 void FlushTLB(TUint aStartIndex, TUint aEndIndex);
809 Get the page table being used for a specified chunk index if it exists.
811 @param aChunkIndex The index into #iTables of the page table.
813 @return The virtual address of the page table,
814 or the null pointer if one wasn't found.
816 inline TPte* GetPageTable(TUint aChunkIndex)
818 __NK_ASSERT_DEBUG(MmuLock::IsHeld());
819 return iTables[aChunkIndex];
823 Get the page table being used for a specified chunk index; allocating
824 a new one if it didn't previously exist.
826 @param aChunkIndex The index into #iTables of the page table.
828 @return The virtual address of the page table,
829 or the null pointer if one wasn't found and couldn't be allocated.
831 TPte* GetOrAllocatePageTable(TUint aChunkIndex);
834 Get and pin the page table being for a specified chunk index; allocating
835 a new one if it didn't previously exist.
837 @param aChunkIndex The index into #iTables of the page table.
838 @param aPinArgs The resources required to pin the page table.
839 On success, the page table will have been appended to
840 \a aPinArgs.iPinnedPageTables.
842 @return The virtual address of the page table,
843 or the null pointer if one wasn't found and couldn't be allocated.
845 TPte* GetOrAllocatePageTable(TUint aChunkIndex, TPinArgs& aPinArgs);
848 Allocate a single page table.
850 @param aChunkIndex The index into #iTables of the page table.
851 @param aDemandPaged True if the page table is for mapping demand paged memory. Most of the
852 time this will be determined by the #EDemandPaged bit in #iFlags.
853 @param aPermanent True, if the page table's permanence count is to be incremented.
855 @return The virtual address of the page table,
856 or the null pointer if one wasn't found and couldn't be allocated.
858 TPte* AllocatePageTable(TUint aChunkIndex, TBool aDemandPaged, TBool aPermanent=false);
861 Free a single page table if it is unused.
863 @param aChunkIndex The index into #iTables of the page table.
865 void FreePageTable(TUint aChunkIndex);
868 Allocate all the mmu page tables for this object (iTables) and ensure that
869 they are not freed even when they no longer map any pages.
871 This method increments iPermanenceCount.
873 This is called by DCoarseMemory::AddMapping when a memory mapping is
874 added with the #DMemoryMappingBase::EPermanentPageTables attribute is set.
875 This will also be true if the memory object has the #EReserveResources
878 @pre The #MemoryObjectLock for the memory must be held by the current thread.
880 @return KErrNone if successful, otherwise one of the system wide error codes.
882 TInt AllocatePermanentPageTables();
885 Reverses the action of #AllocatePermanentPageTables.
887 This method decrements iPermanenceCount and if this reaches zero,
888 the mmu page tables for this object are freed if the are no longer in use.
890 void FreePermanentPageTables();
893 This is called by DCoarseMemory::AddMapping when a coarse memory mapping is
896 @param aMapping The coarse memory mapping to add.
898 @return KErrNone if successful, otherwise one of the system wide error codes.
900 TInt AddMapping(DCoarseMapping* aMapping);
903 This is called by DCoarseMemory::RemoveMapping when a coarse memory mapping is
906 @param aMapping The coarse memory mapping to remove.
908 void RemoveMapping(DCoarseMapping* aMapping);
911 Overriding DReferenceCountedObject::Close.
912 This removes the linkage with #iMemory if this object is deleted.
917 Overriding DReferenceCountedObject::AsyncClose.
918 This removes the linkage with #iMemory if this object is deleted.
923 Remove an mmu page table from this object's ownership.
924 This is called from DCoarseMemory::StealPageTable when a RAM page containing
925 the page table is paged out.
927 @param aChunkIndex The index into #iTables of the page table.
929 @pre #MmuLock is held.
930 @pre #PageTablesLockIsHeld
932 void StealPageTable(TUint aChunkIndex);
936 For arguments, see #New.
938 DPageTables(DCoarseMemory* aMemory, TInt aNumPts, TUint aPteType);
941 Second phase constructor.
943 This initialises all of the mmu page tables to map the memory currently owned
944 by the memory object (#iMemory).
946 @return KErrNone if successful, otherwise one of the system wide error codes.
952 Reverses the action of #AllocatePermanentPageTables for a range of page tables.
954 This is an implementation factor for #FreePermanentPageTables().
956 @param aChunkIndex The index into #iTables of the first page table.
957 @param aChunkCount The number of page tables.
959 void FreePermanentPageTables(TUint aChunkIndex, TUint aChunkCount);
962 Assign a newly allocated page table to this object.
964 This adds the page table to the page directory entries associated with
965 all mappings attached to this object.
967 @param aChunkIndex The index into #iTables of the page table.
968 @param aPageTable The page table.
970 @pre #PageTablesLockIsHeld.
972 void AssignPageTable(TUint aChunkIndex, TPte* aPageTable);
975 Unassign a page table to this object.
977 This removes the page table from the page directory entries associated with
978 all mappings attached to this object.
980 This is called by FreePageTable and StealPageTable.
982 @param aChunkIndex The index into #iTables of the page table.
984 @pre #PageTablesLockIsHeld.
986 void UnassignPageTable(TUint aChunkIndex);
990 The coarse memory object which owns us.
992 DCoarseMemory* iMemory;
995 The #TPteType the page tables are being used for.
996 (This object's index in #iMemory->iPageTables.)
1001 The list of coarse mappings attached to this object.
1002 These mappings use the mmu page tables owned by us.
1004 TMappingList iMappings;
1007 The page table entry (PTE) value for use when mapping pages into the page tables.
1008 This value has the physical address component being zero, so a page's physical
1009 address can be simply ORed in.
1014 Reference count for the number of times #AllocatePermanentPageTables
1015 has been called without #FreePermanentPageTables.
1017 TUint iPermanenceCount;
1020 Number of entries in #iTables.
1022 TUint iNumPageTables;
1025 Array of page tables owned by this object. This may extend into memory
1026 beyond the end of this object and contains #iNumPageTables entries.
1028 Each entry in the array corresponds to a #KChunkSize sized region of #iMemory.
1029 The null pointer indicating that no page table exists for the corresponding
1032 The contents of the array are protected by the PageTableAllocator lock AND #MmuLock
1039 Get or allocate the page tables container for a given PTE type
1041 @pre #MemoryObjectLock for this object must be held.
1043 DPageTables* GetOrAllocatePageTables(TUint aPteType);
1047 Array of #DPageTables objects owned by this memory object.
1048 Updates to this array require the #MmuLock.
1050 DPageTables* iPageTables[ENumPteTypes];
1052 friend class DCoarseMemory::DPageTables; // for DPageTables::Close() / AsyncClose()
1058 A memory object without the special case optimisations of DCoarseMemory.
1060 class DFineMemory : public DMemoryObject
1063 // from DMemoryObject...
1064 virtual ~DFineMemory();
1065 virtual TInt ClaimInitialPages(TLinAddr aBase, TUint aSize, TMappingPermissions aPermissions, TBool aAllowGaps=false, TBool aAllowNonRamPages=false);
1069 Create a new DFineMemory object.
1071 @param aManager The manager object for this memory.
1072 @param aSizeInPages Size of the memory object, in number of pages.
1073 @param aAttributes Bitmask of values from enum #TMemoryAttributes.
1074 @param aCreateFlags Bitmask of option flags from enum #TMemoryCreateFlags.
1076 @return The newly created DFineMemory or the null pointer if there was
1077 insufficient memory.
1079 static DFineMemory* New(DMemoryManager* aManager, TUint aSizeInPages, TMemoryAttributes aAttributes, TMemoryCreateFlags aCreateFlags);
1083 For arguments, see #New.
1085 DFineMemory(DMemoryManager* aManager, TUint aSizeInPages, TMemoryAttributes aAttributes, TMemoryCreateFlags aCreateFlags);