0
|
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
|