1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/include/memmodel/epoc/mmubase/ramalloc.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,213 @@
1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\include\memmodel\epoc\mmubase\ramalloc.h
1.18 +//
1.19 +//
1.20 +
1.21 +/**
1.22 + @file
1.23 + @internalComponent
1.24 +*/
1.25 +
1.26 +#ifndef __RAMALLOC_H__
1.27 +#define __RAMALLOC_H__
1.28 +#include <kernel/klib.h>
1.29 +
1.30 +// RAM information block passed from bootstrap to kernel.
1.31 +// Consists of two consecutive lists of SRamBank structures, each terminated by
1.32 +// a bank with iSize=0.
1.33 +// The first list specifies all available blocks of RAM in the system.
1.34 +// The second list specifies any blocks of RAM which are reserved and not
1.35 +// available for general allocation. This should not include RAM mapped by the
1.36 +// bootstrap - this will be discovered when the initial page mappings are
1.37 +// analysed.
1.38 +struct SRamInfo
1.39 + {
1.40 + SRamBank iBanks[1]; // extend for multiple banks
1.41 +// SRamBank iReservedBlocks[1];
1.42 + };
1.43 +
1.44 +/** The number of types of pages that can't be moved or discarded
1.45 +*/
1.46 +const TInt KPageImmovable = EPageMovable;
1.47 +
1.48 +/** The lowest enum from TZonePageType that DRamAllocater will allocate
1.49 +*/
1.50 +const TUint KPageTypeAllocBase = EPageFixed;
1.51 +
1.52 +/** Element 0 of SZone::iBma is the bit map of all allocated pages
1.53 +regardless of type.
1.54 +*/
1.55 +const TUint KBmaAllPages = 0;
1.56 +
1.57 +/** The maximum number of freeable contiguous pages that can be found by
1.58 +DRamAllocator::FindFreeableContiguousPages and RamCacheBase::AllocFreeContiguousPages.
1.59 +*/
1.60 +const TUint KMaxFreeableContiguousPages = 16;
1.61 +
1.62 +
1.63 +/** Structure to store the information on a zone.
1.64 +*/
1.65 +struct SZone
1.66 + {
1.67 + TBitMapAllocator* iBma[EPageTypes]; /**< Pointers to bit map allocators for each type of page*/
1.68 + TPhysAddr iPhysBase; /**< physical base address of this zone*/
1.69 + TPhysAddr iPhysEnd; /**< physical end address of this zone*/
1.70 + TUint32 iPhysPages; /**< the total no. of pages that are in this zone*/
1.71 + TUint32 iAllocPages[EPageTypes]; /**< number of pages allocated of each type*/
1.72 + TUint32 iFreePages; /**< number of pages free*/
1.73 + SDblQueLink iPrefLink; /**< The link of this zone into the preference ordered list*/
1.74 + TUint iPrefRank; /**< The rank of this zone in the preference ordered list.*/
1.75 + TUint iId; /**< the ID of the zone*/
1.76 + TUint iFlags; /**< bit flags for this zone, all flags masked KRamZoneFlagInvalid are
1.77 + for use by the kernel only*/
1.78 + TUint8 iPref; /**< the preference of the zone, lower preference zones are used first*/
1.79 + };
1.80 +
1.81 +/** The different stages of a general defragmentation*/
1.82 +enum TGenDefragStage
1.83 + {
1.84 + EGenDefragStage0, /**< This stage should discard any pages needed to
1.85 + allow the required movable pages to fit into the
1.86 + RAM zones to be in use after the general defrag.*/
1.87 + EGenDefragStage1, /**< This stage should reduce the number of RAM
1.88 + zones in use to the minmum required.*/
1.89 + EGenDefragStage2, /**< This stage clears space in most preferable RAM
1.90 + zones for fixed page allocations by placing movable
1.91 + and discardable pages in the least preferable RAM
1.92 + zones in use.*/
1.93 + EGenDefragStageEnd,
1.94 + };
1.95 +
1.96 +// forward declare
1.97 +struct SPageInfo;
1.98 +
1.99 +class DRamAllocator : public DBase
1.100 + {
1.101 +private:
1.102 + /** Used with NextAllocZone to specify which order to run through the zones
1.103 + */
1.104 + enum TZoneSearchState
1.105 + {
1.106 + EZoneSearchPref,
1.107 + EZoneSearchAddr,
1.108 + EZoneSearchEnd,
1.109 + };
1.110 +
1.111 + enum TPanic
1.112 + {
1.113 + EDoNotUse=0,
1.114 + EDoMarkPagesAllocated1=1,
1.115 + EAllocRamPagesInconsistent=2,
1.116 + EZonesTooNumerousOrFew=3, /**<There are too many or too few RAM zones*/
1.117 + EZonesNotDistinct=4, /**<Some of the RAM zones overlap*/
1.118 + EZonesIncomplete=5, /**<The RAM zones don't cover all the RAM, either because the zones
1.119 + are too small or at least one zone is mapped to an incorrect address*/
1.120 + EZonesIDInvalid=6, /**<KRamZoneInvalidId can't be used for any zone's ID*/
1.121 + EZonesIDNotUnique=7, /**<At least two zones share the same ID*/
1.122 + EZonesAlignment=8, /**<Zones are not aligned to page boundaries*/
1.123 + EZonesCountErr=9, /**<The count of free and alloc'd zone pages is corrupted*/
1.124 + EZonesCallbackErr=10, /**<Unexpected error when zone call back invoked*/
1.125 + EZonesFlagsInvalid=11, /**<Attempt to create a zone with flags set to invalid values*/
1.126 + ECreateNoMemory=12, /**<Not enough free RAM to create a DRamAllocator object*/
1.127 + ECreateInvalidReserveBank=13,/**<A specified reserve bank could not be reserved*/
1.128 + ECreateInvalidRamBanks=14, /**<The specified RAM banks are invalid*/
1.129 + EFreeingLockedPage=15, /**< A locked page was requested for freeing*/
1.130 + };
1.131 +
1.132 +public:
1.133 +
1.134 + static DRamAllocator* New(const SRamInfo& aInfo, const SRamZone* aZoneInfo, TRamZoneCallback aZoneCallback);
1.135 + static void Panic(TPanic aPanic);
1.136 + TUint TotalPhysicalRamPages();
1.137 + TInt FreeRamInBytes();
1.138 + TUint FreeRamInPages();
1.139 + TInt ClaimPhysicalRam(TPhysAddr aBase, TInt aSize);
1.140 + TInt FreePhysicalRam(TPhysAddr aBase, TInt aSize);
1.141 + void Create(const SRamInfo& aInfo, const SRamZone* aZones, TRamZoneCallback aZoneCallback);
1.142 + TInt MarkPageAllocated(TPhysAddr aAddr, TZonePageType aType);
1.143 + void MarkPagesAllocated(TPhysAddr aAddr, TInt aCount, TZonePageType aType);
1.144 + TInt FreeRamPage(TPhysAddr aAddr, TZonePageType aType);
1.145 + void FreeRamPages(TPhysAddr* aPageList, TInt aNumPages, TZonePageType aType);
1.146 + TInt AllocRamPages(TPhysAddr* aPageList, TInt aNumPages, TZonePageType aType, TUint aBlockedZoneId=KRamZoneInvalidId, TBool aBlockRest=EFalse);
1.147 + TInt ZoneAllocRamPages(TUint* aZoneIdList, TUint aZoneIdCount, TPhysAddr* aPageList, TInt aNumPages, TZonePageType aType);
1.148 + TInt AllocContiguousRam(TUint aNumPages, TPhysAddr& aPhysAddr, TZonePageType aType, TInt aAlign=0, TUint aBlockZoneId=KRamZoneInvalidId, TBool aBlockRest=EFalse);
1.149 + TInt ZoneAllocContiguousRam(TUint* aZoneIdList, TUint aZoneIdCount, TInt aSize, TPhysAddr& aPhysAddr, TZonePageType aType, TInt aAlign);
1.150 +#ifdef _DEBUG
1.151 + void DebugDump();
1.152 +#endif
1.153 +#ifdef __VERIFY_LEASTMOVDIS
1.154 + void VerifyLeastPrefMovDis();
1.155 +#endif
1.156 + TInt GetZonePageCount(TUint aId, SRamZonePageCount& aPageData);
1.157 + void ChangePageType(SPageInfo* aPageInfo, TZonePageType aOldType, TZonePageType aNewType);
1.158 +#ifdef BTRACE_RAM_ALLOCATOR
1.159 + void SendInitialBtraceLogs(void);
1.160 +#endif
1.161 + TInt GetZoneAddress(TUint aZoneId, TPhysAddr& aPhysBase, TUint& aNumPages);
1.162 + TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2);
1.163 + TInt NextAllocatedPage(SZone* aZone, TUint& aOffset, TZonePageType aType) const;
1.164 + TUint GenDefragFreePages(TZonePageType aType) const;
1.165 + SZone* GeneralDefragStart0(TGenDefragStage& aStage, TUint& aRequiredToBeDiscarded);
1.166 + SZone* GeneralDefragNextZone0();
1.167 + SZone* GeneralDefragStart1();
1.168 + SZone* GeneralDefragNextZone1();
1.169 + SZone* GeneralDefragStart2();
1.170 + SZone* GeneralDefragNextZone2();
1.171 + void GeneralDefragEnd();
1.172 + SZone* ZoneFromId(TUint aId) const;
1.173 + void ZoneClaimStart(SZone& aZone);
1.174 + void ZoneClaimEnd(SZone& aZone);
1.175 + TInt ModifyZoneFlags(TUint aId, TUint aClearFlags, TUint aSetFlags);
1.176 + void ZoneMark(SZone& aZone);
1.177 + TBool ZoneUnmark(SZone& aZone);
1.178 + void InitialCallback();
1.179 +private:
1.180 + static DRamAllocator* New();
1.181 + SZone* GetZoneAndOffset(TPhysAddr aAddr, TInt& aOffset);
1.182 + inline void CountZones(const SRamZone* aZones);
1.183 + inline void SortRamZones(const SRamZone* aZones, TUint8* aZoneAddrOrder);
1.184 + void ZoneAllocPages(SZone* aZone, TUint32 aCount, TZonePageType aType);
1.185 + void ZoneFreePages(SZone* aZone, TUint32 aCount, TZonePageType aType);
1.186 + void ZoneClearPages(SZone& aZone, TUint aRequiredPages);
1.187 + TUint32 ZoneFindPages(TPhysAddr*& aPageList, SZone& aZone, TUint32 aNumPages, TZonePageType aType);
1.188 + TInt SetPhysicalRamState(TPhysAddr aBase, TInt aSize, TBool aState, TZonePageType aType);
1.189 + inline TUint InitSPageInfos(const SZone* aZone);
1.190 + TBool NextAllocZone(SZone*& aZone, TZoneSearchState& aState, TZonePageType aType, TUint aBlockedZoneId, TBool aBlockRest);
1.191 + TBool NoAllocOfPageType(SZone& aZone, TZonePageType aType) const;
1.192 +private:
1.193 + TPhysAddr iPhysAddrBase; // lowest valid physical address
1.194 + TPhysAddr iPhysAddrTop; // highest valid physical address
1.195 + TUint iTotalFreeRamPages;
1.196 + TUint iTotalRamPages;
1.197 +
1.198 + SZone* iZones; /**< per-zone info stored in ascending address order*/
1.199 + TUint32 iNumZones; /**< The number of zones*/
1.200 + SDblQue iZonePrefList; /**< Doubly linked list of zones in preference order*/
1.201 + SDblQueLink* iZoneLeastMovDis; /**< Link to the least preferable RAM zone that has discardable or movable pages*/
1.202 + TUint iZoneLeastMovDisRank; /**< Rank of the least preferable RAM zone that has discardable or movable pages*/
1.203 + TUint64 iZonePwrState; /**< mask of currently used power blocks*/
1.204 + TBool iZoneCallbackInitSent; /**< Set to ETrue once an ERamZoneOp_Init has been issued*/
1.205 + TRamZoneCallback iZonePowerFunc; /**< Callback function to invoke when RAM zone power state changes*/
1.206 + TInt iZoneTmpAddrIndex; /**< Used by NextAllocZone*/
1.207 + SDblQueLink* iZoneTmpPrefLink; /**< Used by NextAllocZone*/
1.208 + SDblQueLink* iZoneGeneralPrefLink; /**< Link to the current RAM zone being defragged*/
1.209 + SDblQueLink* iZoneGeneralTmpLink; /**< Link to the current RAM zone being defragged*/
1.210 + TUint iZoneGeneralStage; /**< The current stage of any general defrag operation*/
1.211 +#ifdef _DEBUG
1.212 + TBool iAllowBmaVerify;
1.213 +#endif
1.214 + };
1.215 +
1.216 +#endif