--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/include/memmodel/epoc/mmubase/ramalloc.h Thu Dec 17 09:24:54 2009 +0200
@@ -0,0 +1,213 @@
+// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32\include\memmodel\epoc\mmubase\ramalloc.h
+//
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#ifndef __RAMALLOC_H__
+#define __RAMALLOC_H__
+#include <kernel/klib.h>
+
+// RAM information block passed from bootstrap to kernel.
+// Consists of two consecutive lists of SRamBank structures, each terminated by
+// a bank with iSize=0.
+// The first list specifies all available blocks of RAM in the system.
+// The second list specifies any blocks of RAM which are reserved and not
+// available for general allocation. This should not include RAM mapped by the
+// bootstrap - this will be discovered when the initial page mappings are
+// analysed.
+struct SRamInfo
+ {
+ SRamBank iBanks[1]; // extend for multiple banks
+// SRamBank iReservedBlocks[1];
+ };
+
+/** The number of types of pages that can't be moved or discarded
+*/
+const TInt KPageImmovable = EPageMovable;
+
+/** The lowest enum from TZonePageType that DRamAllocater will allocate
+*/
+const TUint KPageTypeAllocBase = EPageFixed;
+
+/** Element 0 of SZone::iBma is the bit map of all allocated pages
+regardless of type.
+*/
+const TUint KBmaAllPages = 0;
+
+/** The maximum number of freeable contiguous pages that can be found by
+DRamAllocator::FindFreeableContiguousPages and RamCacheBase::AllocFreeContiguousPages.
+*/
+const TUint KMaxFreeableContiguousPages = 16;
+
+
+/** Structure to store the information on a zone.
+*/
+struct SZone
+ {
+ TBitMapAllocator* iBma[EPageTypes]; /**< Pointers to bit map allocators for each type of page*/
+ TPhysAddr iPhysBase; /**< physical base address of this zone*/
+ TPhysAddr iPhysEnd; /**< physical end address of this zone*/
+ TUint32 iPhysPages; /**< the total no. of pages that are in this zone*/
+ TUint32 iAllocPages[EPageTypes]; /**< number of pages allocated of each type*/
+ TUint32 iFreePages; /**< number of pages free*/
+ SDblQueLink iPrefLink; /**< The link of this zone into the preference ordered list*/
+ TUint iPrefRank; /**< The rank of this zone in the preference ordered list.*/
+ TUint iId; /**< the ID of the zone*/
+ TUint iFlags; /**< bit flags for this zone, all flags masked KRamZoneFlagInvalid are
+ for use by the kernel only*/
+ TUint8 iPref; /**< the preference of the zone, lower preference zones are used first*/
+ };
+
+/** The different stages of a general defragmentation*/
+enum TGenDefragStage
+ {
+ EGenDefragStage0, /**< This stage should discard any pages needed to
+ allow the required movable pages to fit into the
+ RAM zones to be in use after the general defrag.*/
+ EGenDefragStage1, /**< This stage should reduce the number of RAM
+ zones in use to the minmum required.*/
+ EGenDefragStage2, /**< This stage clears space in most preferable RAM
+ zones for fixed page allocations by placing movable
+ and discardable pages in the least preferable RAM
+ zones in use.*/
+ EGenDefragStageEnd,
+ };
+
+// forward declare
+struct SPageInfo;
+
+class DRamAllocator : public DBase
+ {
+private:
+ /** Used with NextAllocZone to specify which order to run through the zones
+ */
+ enum TZoneSearchState
+ {
+ EZoneSearchPref,
+ EZoneSearchAddr,
+ EZoneSearchEnd,
+ };
+
+ enum TPanic
+ {
+ EDoNotUse=0,
+ EDoMarkPagesAllocated1=1,
+ EAllocRamPagesInconsistent=2,
+ EZonesTooNumerousOrFew=3, /**<There are too many or too few RAM zones*/
+ EZonesNotDistinct=4, /**<Some of the RAM zones overlap*/
+ EZonesIncomplete=5, /**<The RAM zones don't cover all the RAM, either because the zones
+ are too small or at least one zone is mapped to an incorrect address*/
+ EZonesIDInvalid=6, /**<KRamZoneInvalidId can't be used for any zone's ID*/
+ EZonesIDNotUnique=7, /**<At least two zones share the same ID*/
+ EZonesAlignment=8, /**<Zones are not aligned to page boundaries*/
+ EZonesCountErr=9, /**<The count of free and alloc'd zone pages is corrupted*/
+ EZonesCallbackErr=10, /**<Unexpected error when zone call back invoked*/
+ EZonesFlagsInvalid=11, /**<Attempt to create a zone with flags set to invalid values*/
+ ECreateNoMemory=12, /**<Not enough free RAM to create a DRamAllocator object*/
+ ECreateInvalidReserveBank=13,/**<A specified reserve bank could not be reserved*/
+ ECreateInvalidRamBanks=14, /**<The specified RAM banks are invalid*/
+ EFreeingLockedPage=15, /**< A locked page was requested for freeing*/
+ };
+
+public:
+
+ static DRamAllocator* New(const SRamInfo& aInfo, const SRamZone* aZoneInfo, TRamZoneCallback aZoneCallback);
+ static void Panic(TPanic aPanic);
+ TUint TotalPhysicalRamPages();
+ TInt FreeRamInBytes();
+ TUint FreeRamInPages();
+ TInt ClaimPhysicalRam(TPhysAddr aBase, TInt aSize);
+ TInt FreePhysicalRam(TPhysAddr aBase, TInt aSize);
+ void Create(const SRamInfo& aInfo, const SRamZone* aZones, TRamZoneCallback aZoneCallback);
+ TInt MarkPageAllocated(TPhysAddr aAddr, TZonePageType aType);
+ void MarkPagesAllocated(TPhysAddr aAddr, TInt aCount, TZonePageType aType);
+ TInt FreeRamPage(TPhysAddr aAddr, TZonePageType aType);
+ void FreeRamPages(TPhysAddr* aPageList, TInt aNumPages, TZonePageType aType);
+ TInt AllocRamPages(TPhysAddr* aPageList, TInt aNumPages, TZonePageType aType, TUint aBlockedZoneId=KRamZoneInvalidId, TBool aBlockRest=EFalse);
+ TInt ZoneAllocRamPages(TUint* aZoneIdList, TUint aZoneIdCount, TPhysAddr* aPageList, TInt aNumPages, TZonePageType aType);
+ TInt AllocContiguousRam(TUint aNumPages, TPhysAddr& aPhysAddr, TZonePageType aType, TInt aAlign=0, TUint aBlockZoneId=KRamZoneInvalidId, TBool aBlockRest=EFalse);
+ TInt ZoneAllocContiguousRam(TUint* aZoneIdList, TUint aZoneIdCount, TInt aSize, TPhysAddr& aPhysAddr, TZonePageType aType, TInt aAlign);
+#ifdef _DEBUG
+ void DebugDump();
+#endif
+#ifdef __VERIFY_LEASTMOVDIS
+ void VerifyLeastPrefMovDis();
+#endif
+ TInt GetZonePageCount(TUint aId, SRamZonePageCount& aPageData);
+ void ChangePageType(SPageInfo* aPageInfo, TZonePageType aOldType, TZonePageType aNewType);
+#ifdef BTRACE_RAM_ALLOCATOR
+ void SendInitialBtraceLogs(void);
+#endif
+ TInt GetZoneAddress(TUint aZoneId, TPhysAddr& aPhysBase, TUint& aNumPages);
+ TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2);
+ TInt NextAllocatedPage(SZone* aZone, TUint& aOffset, TZonePageType aType) const;
+ TUint GenDefragFreePages(TZonePageType aType) const;
+ SZone* GeneralDefragStart0(TGenDefragStage& aStage, TUint& aRequiredToBeDiscarded);
+ SZone* GeneralDefragNextZone0();
+ SZone* GeneralDefragStart1();
+ SZone* GeneralDefragNextZone1();
+ SZone* GeneralDefragStart2();
+ SZone* GeneralDefragNextZone2();
+ void GeneralDefragEnd();
+ SZone* ZoneFromId(TUint aId) const;
+ void ZoneClaimStart(SZone& aZone);
+ void ZoneClaimEnd(SZone& aZone);
+ TInt ModifyZoneFlags(TUint aId, TUint aClearFlags, TUint aSetFlags);
+ void ZoneMark(SZone& aZone);
+ TBool ZoneUnmark(SZone& aZone);
+ void InitialCallback();
+private:
+ static DRamAllocator* New();
+ SZone* GetZoneAndOffset(TPhysAddr aAddr, TInt& aOffset);
+ inline void CountZones(const SRamZone* aZones);
+ inline void SortRamZones(const SRamZone* aZones, TUint8* aZoneAddrOrder);
+ void ZoneAllocPages(SZone* aZone, TUint32 aCount, TZonePageType aType);
+ void ZoneFreePages(SZone* aZone, TUint32 aCount, TZonePageType aType);
+ void ZoneClearPages(SZone& aZone, TUint aRequiredPages);
+ TUint32 ZoneFindPages(TPhysAddr*& aPageList, SZone& aZone, TUint32 aNumPages, TZonePageType aType);
+ TInt SetPhysicalRamState(TPhysAddr aBase, TInt aSize, TBool aState, TZonePageType aType);
+ inline TUint InitSPageInfos(const SZone* aZone);
+ TBool NextAllocZone(SZone*& aZone, TZoneSearchState& aState, TZonePageType aType, TUint aBlockedZoneId, TBool aBlockRest);
+ TBool NoAllocOfPageType(SZone& aZone, TZonePageType aType) const;
+private:
+ TPhysAddr iPhysAddrBase; // lowest valid physical address
+ TPhysAddr iPhysAddrTop; // highest valid physical address
+ TUint iTotalFreeRamPages;
+ TUint iTotalRamPages;
+
+ SZone* iZones; /**< per-zone info stored in ascending address order*/
+ TUint32 iNumZones; /**< The number of zones*/
+ SDblQue iZonePrefList; /**< Doubly linked list of zones in preference order*/
+ SDblQueLink* iZoneLeastMovDis; /**< Link to the least preferable RAM zone that has discardable or movable pages*/
+ TUint iZoneLeastMovDisRank; /**< Rank of the least preferable RAM zone that has discardable or movable pages*/
+ TUint64 iZonePwrState; /**< mask of currently used power blocks*/
+ TBool iZoneCallbackInitSent; /**< Set to ETrue once an ERamZoneOp_Init has been issued*/
+ TRamZoneCallback iZonePowerFunc; /**< Callback function to invoke when RAM zone power state changes*/
+ TInt iZoneTmpAddrIndex; /**< Used by NextAllocZone*/
+ SDblQueLink* iZoneTmpPrefLink; /**< Used by NextAllocZone*/
+ SDblQueLink* iZoneGeneralPrefLink; /**< Link to the current RAM zone being defragged*/
+ SDblQueLink* iZoneGeneralTmpLink; /**< Link to the current RAM zone being defragged*/
+ TUint iZoneGeneralStage; /**< The current stage of any general defrag operation*/
+#ifdef _DEBUG
+ TBool iAllowBmaVerify;
+#endif
+ };
+
+#endif