Update contrib.
1 // Copyright (c) 1998-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.
14 // e32\include\memmodel\epoc\mmubase\ramalloc.h
23 #ifndef __RAMALLOC_H__
24 #define __RAMALLOC_H__
25 #include <kernel/klib.h>
27 // RAM information block passed from bootstrap to kernel.
28 // Consists of two consecutive lists of SRamBank structures, each terminated by
29 // a bank with iSize=0.
30 // The first list specifies all available blocks of RAM in the system.
31 // The second list specifies any blocks of RAM which are reserved and not
32 // available for general allocation. This should not include RAM mapped by the
33 // bootstrap - this will be discovered when the initial page mappings are
37 SRamBank iBanks[1]; // extend for multiple banks
38 // SRamBank iReservedBlocks[1];
41 /** The number of types of pages that can't be moved or discarded
43 const TInt KPageImmovable = EPageMovable;
45 /** The lowest enum from TZonePageType that DRamAllocater will allocate
47 const TUint KPageTypeAllocBase = EPageFixed;
49 /** Element 0 of SZone::iBma is the bit map of all allocated pages
52 const TUint KBmaAllPages = 0;
54 /** The maximum number of freeable contiguous pages that can be found by
55 DRamAllocator::FindFreeableContiguousPages and RamCacheBase::AllocFreeContiguousPages.
57 const TUint KMaxFreeableContiguousPages = 16;
60 /** Structure to store the information on a zone.
64 TBitMapAllocator* iBma[EPageTypes]; /**< Pointers to bit map allocators for each type of page*/
65 TPhysAddr iPhysBase; /**< physical base address of this zone*/
66 TPhysAddr iPhysEnd; /**< physical end address of this zone*/
67 TUint32 iPhysPages; /**< the total no. of pages that are in this zone*/
68 TUint32 iAllocPages[EPageTypes]; /**< number of pages allocated of each type*/
69 TUint32 iFreePages; /**< number of pages free*/
70 SDblQueLink iPrefLink; /**< The link of this zone into the preference ordered list*/
71 TUint iPrefRank; /**< The rank of this zone in the preference ordered list.*/
72 TUint iId; /**< the ID of the zone*/
73 TUint iFlags; /**< bit flags for this zone, all flags masked KRamZoneFlagInvalid are
74 for use by the kernel only*/
75 TUint8 iPref; /**< the preference of the zone, lower preference zones are used first*/
78 /** The different stages of a general defragmentation*/
81 EGenDefragStage0, /**< This stage should discard any pages needed to
82 allow the required movable pages to fit into the
83 RAM zones to be in use after the general defrag.*/
84 EGenDefragStage1, /**< This stage should reduce the number of RAM
85 zones in use to the minmum required.*/
86 EGenDefragStage2, /**< This stage clears space in most preferable RAM
87 zones for fixed page allocations by placing movable
88 and discardable pages in the least preferable RAM
96 class DRamAllocator : public DBase
99 /** Used with NextAllocZone to specify which order to run through the zones
101 enum TZoneSearchState
111 EDoMarkPagesAllocated1=1,
112 EAllocRamPagesInconsistent=2,
113 EZonesTooNumerousOrFew=3, /**<There are too many or too few RAM zones*/
114 EZonesNotDistinct=4, /**<Some of the RAM zones overlap*/
115 EZonesIncomplete=5, /**<The RAM zones don't cover all the RAM, either because the zones
116 are too small or at least one zone is mapped to an incorrect address*/
117 EZonesIDInvalid=6, /**<KRamZoneInvalidId can't be used for any zone's ID*/
118 EZonesIDNotUnique=7, /**<At least two zones share the same ID*/
119 EZonesAlignment=8, /**<Zones are not aligned to page boundaries*/
120 EZonesCountErr=9, /**<The count of free and alloc'd zone pages is corrupted*/
121 EZonesCallbackErr=10, /**<Unexpected error when zone call back invoked*/
122 EZonesFlagsInvalid=11, /**<Attempt to create a zone with flags set to invalid values*/
123 ECreateNoMemory=12, /**<Not enough free RAM to create a DRamAllocator object*/
124 ECreateInvalidReserveBank=13,/**<A specified reserve bank could not be reserved*/
125 ECreateInvalidRamBanks=14, /**<The specified RAM banks are invalid*/
126 EFreeingLockedPage=15, /**< A locked page was requested for freeing*/
131 static DRamAllocator* New(const SRamInfo& aInfo, const SRamZone* aZoneInfo, TRamZoneCallback aZoneCallback);
132 static void Panic(TPanic aPanic);
133 TUint TotalPhysicalRamPages();
134 TInt FreeRamInBytes();
135 TUint FreeRamInPages();
136 TInt ClaimPhysicalRam(TPhysAddr aBase, TInt aSize);
137 TInt FreePhysicalRam(TPhysAddr aBase, TInt aSize);
138 void Create(const SRamInfo& aInfo, const SRamZone* aZones, TRamZoneCallback aZoneCallback);
139 TInt MarkPageAllocated(TPhysAddr aAddr, TZonePageType aType);
140 void MarkPagesAllocated(TPhysAddr aAddr, TInt aCount, TZonePageType aType);
141 TInt FreeRamPage(TPhysAddr aAddr, TZonePageType aType);
142 void FreeRamPages(TPhysAddr* aPageList, TInt aNumPages, TZonePageType aType);
143 TInt AllocRamPages(TPhysAddr* aPageList, TInt aNumPages, TZonePageType aType, TUint aBlockedZoneId=KRamZoneInvalidId, TBool aBlockRest=EFalse);
144 TInt ZoneAllocRamPages(TUint* aZoneIdList, TUint aZoneIdCount, TPhysAddr* aPageList, TInt aNumPages, TZonePageType aType);
145 TInt AllocContiguousRam(TUint aNumPages, TPhysAddr& aPhysAddr, TZonePageType aType, TInt aAlign=0, TUint aBlockZoneId=KRamZoneInvalidId, TBool aBlockRest=EFalse);
146 TInt ZoneAllocContiguousRam(TUint* aZoneIdList, TUint aZoneIdCount, TInt aSize, TPhysAddr& aPhysAddr, TZonePageType aType, TInt aAlign);
150 #ifdef __VERIFY_LEASTMOVDIS
151 void VerifyLeastPrefMovDis();
153 TInt GetZonePageCount(TUint aId, SRamZonePageCount& aPageData);
154 void ChangePageType(SPageInfo* aPageInfo, TZonePageType aOldType, TZonePageType aNewType);
155 #ifdef BTRACE_RAM_ALLOCATOR
156 void SendInitialBtraceLogs(void);
158 TInt GetZoneAddress(TUint aZoneId, TPhysAddr& aPhysBase, TUint& aNumPages);
159 TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2);
160 TInt NextAllocatedPage(SZone* aZone, TUint& aOffset, TZonePageType aType) const;
161 TUint GenDefragFreePages(TZonePageType aType) const;
162 SZone* GeneralDefragStart0(TGenDefragStage& aStage, TUint& aRequiredToBeDiscarded);
163 SZone* GeneralDefragNextZone0();
164 SZone* GeneralDefragStart1();
165 SZone* GeneralDefragNextZone1();
166 SZone* GeneralDefragStart2();
167 SZone* GeneralDefragNextZone2();
168 void GeneralDefragEnd();
169 SZone* ZoneFromId(TUint aId) const;
170 void ZoneClaimStart(SZone& aZone);
171 void ZoneClaimEnd(SZone& aZone);
172 TInt ModifyZoneFlags(TUint aId, TUint aClearFlags, TUint aSetFlags);
173 void ZoneMark(SZone& aZone);
174 TBool ZoneUnmark(SZone& aZone);
175 void InitialCallback();
177 static DRamAllocator* New();
178 SZone* GetZoneAndOffset(TPhysAddr aAddr, TInt& aOffset);
179 inline void CountZones(const SRamZone* aZones);
180 inline void SortRamZones(const SRamZone* aZones, TUint8* aZoneAddrOrder);
181 void ZoneAllocPages(SZone* aZone, TUint32 aCount, TZonePageType aType);
182 void ZoneFreePages(SZone* aZone, TUint32 aCount, TZonePageType aType);
183 void ZoneClearPages(SZone& aZone, TUint aRequiredPages);
184 TUint32 ZoneFindPages(TPhysAddr*& aPageList, SZone& aZone, TUint32 aNumPages, TZonePageType aType);
185 TInt SetPhysicalRamState(TPhysAddr aBase, TInt aSize, TBool aState, TZonePageType aType);
186 inline TUint InitSPageInfos(const SZone* aZone);
187 TBool NextAllocZone(SZone*& aZone, TZoneSearchState& aState, TZonePageType aType, TUint aBlockedZoneId, TBool aBlockRest);
188 TBool NoAllocOfPageType(SZone& aZone, TZonePageType aType) const;
190 TPhysAddr iPhysAddrBase; // lowest valid physical address
191 TPhysAddr iPhysAddrTop; // highest valid physical address
192 TUint iTotalFreeRamPages;
193 TUint iTotalRamPages;
195 SZone* iZones; /**< per-zone info stored in ascending address order*/
196 TUint32 iNumZones; /**< The number of zones*/
197 SDblQue iZonePrefList; /**< Doubly linked list of zones in preference order*/
198 SDblQueLink* iZoneLeastMovDis; /**< Link to the least preferable RAM zone that has discardable or movable pages*/
199 TUint iZoneLeastMovDisRank; /**< Rank of the least preferable RAM zone that has discardable or movable pages*/
200 TUint64 iZonePwrState; /**< mask of currently used power blocks*/
201 TBool iZoneCallbackInitSent; /**< Set to ETrue once an ERamZoneOp_Init has been issued*/
202 TRamZoneCallback iZonePowerFunc; /**< Callback function to invoke when RAM zone power state changes*/
203 TInt iZoneTmpAddrIndex; /**< Used by NextAllocZone*/
204 SDblQueLink* iZoneTmpPrefLink; /**< Used by NextAllocZone*/
205 SDblQueLink* iZoneGeneralPrefLink; /**< Link to the current RAM zone being defragged*/
206 SDblQueLink* iZoneGeneralTmpLink; /**< Link to the current RAM zone being defragged*/
207 TUint iZoneGeneralStage; /**< The current stage of any general defrag operation*/
209 TBool iAllowBmaVerify;