|
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". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32\include\memmodel\epoc\mmubase\ramalloc.h |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 @internalComponent |
|
21 */ |
|
22 |
|
23 #ifndef __RAMALLOC_H__ |
|
24 #define __RAMALLOC_H__ |
|
25 #include <kernel/klib.h> |
|
26 |
|
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 |
|
34 // analysed. |
|
35 struct SRamInfo |
|
36 { |
|
37 SRamBank iBanks[1]; // extend for multiple banks |
|
38 // SRamBank iReservedBlocks[1]; |
|
39 }; |
|
40 |
|
41 /** The number of types of pages that can't be moved or discarded |
|
42 */ |
|
43 const TInt KPageImmovable = EPageMovable; |
|
44 |
|
45 /** The lowest enum from TZonePageType that DRamAllocater will allocate |
|
46 */ |
|
47 const TUint KPageTypeAllocBase = EPageFixed; |
|
48 |
|
49 /** Element 0 of SZone::iBma is the bit map of all allocated pages |
|
50 regardless of type. |
|
51 */ |
|
52 const TUint KBmaAllPages = 0; |
|
53 |
|
54 /** The maximum number of freeable contiguous pages that can be found by |
|
55 DRamAllocator::FindFreeableContiguousPages and RamCacheBase::AllocFreeContiguousPages. |
|
56 */ |
|
57 const TUint KMaxFreeableContiguousPages = 16; |
|
58 |
|
59 |
|
60 /** Structure to store the information on a zone. |
|
61 */ |
|
62 struct SZone |
|
63 { |
|
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*/ |
|
76 }; |
|
77 |
|
78 /** The different stages of a general defragmentation*/ |
|
79 enum TGenDefragStage |
|
80 { |
|
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 |
|
89 zones in use.*/ |
|
90 EGenDefragStageEnd, |
|
91 }; |
|
92 |
|
93 // forward declare |
|
94 struct SPageInfo; |
|
95 |
|
96 class DRamAllocator : public DBase |
|
97 { |
|
98 private: |
|
99 /** Used with NextAllocZone to specify which order to run through the zones |
|
100 */ |
|
101 enum TZoneSearchState |
|
102 { |
|
103 EZoneSearchPref, |
|
104 EZoneSearchAddr, |
|
105 EZoneSearchEnd, |
|
106 }; |
|
107 |
|
108 enum TPanic |
|
109 { |
|
110 EDoNotUse=0, |
|
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*/ |
|
127 }; |
|
128 |
|
129 public: |
|
130 |
|
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); |
|
147 #ifdef _DEBUG |
|
148 void DebugDump(); |
|
149 #endif |
|
150 #ifdef __VERIFY_LEASTMOVDIS |
|
151 void VerifyLeastPrefMovDis(); |
|
152 #endif |
|
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); |
|
157 #endif |
|
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(); |
|
176 private: |
|
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; |
|
189 private: |
|
190 TPhysAddr iPhysAddrBase; // lowest valid physical address |
|
191 TPhysAddr iPhysAddrTop; // highest valid physical address |
|
192 TUint iTotalFreeRamPages; |
|
193 TUint iTotalRamPages; |
|
194 |
|
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*/ |
|
208 #ifdef _DEBUG |
|
209 TBool iAllowBmaVerify; |
|
210 #endif |
|
211 }; |
|
212 |
|
213 #endif |