Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// 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\mmubase.h
//
// WARNING: This file contains some APIs which are internal and are subject
// to change without notice. Such APIs should therefore not be used
// outside the Kernel and Hardware Services package.
//
#ifndef __MMUBASE_H__
#define __MMUBASE_H__
#include <plat_priv.h>
#include <memmodel/epoc/mmubase/kblockmap.h>
/******************************************************************************
* Definitions common to all MMU memory models
******************************************************************************/
/**
@internalComponent
*/
struct SPageInfo
{
enum TType
{
EInvalid=0, // No physical RAM exists for this page
EFixed=1, // RAM fixed at boot time,
EUnused=2, // Page is unused
EChunk=3, // iOwner=DChunk* iOffset=index into chunk
ECodeSegMemory=4, // iOwner=DCodeSegMemory* iOffset=index into CodeSeg memory (Multiple Memory Model only)
// EHwChunk=5, // Not used
EPageTable=6, // iOwner=0 iOffset=index into KPageTableBase
EPageDir=7, // iOwner=ASID iOffset=index into Page Directory
EPtInfo=8, // iOwner=0 iOffset=index into KPageTableInfoBase
EShadow=9, // iOwner=phys ROM page iOffset=index into ROM
EPagedROM=10, // iOwner=0, iOffset=index into ROM
EPagedCode=11, // iOwner=DCodeSegMemory* iOffset=index into code chunk (not offset into CodeSeg!)
EPagedData=12, // NOT YET SUPPORTED
EPagedCache=13, // iOwner=DChunk* iOffset=index into chunk
EPagedFree=14, // In demand paging 'live list' but not used for any purpose
};
enum TState
{
EStateNormal = 0, // no special state
EStatePagedYoung = 1, // demand paged and is on the young list
EStatePagedOld = 2, // demand paged and is on the old list
EStatePagedDead = 3, // demand paged and is currently being modified
EStatePagedLocked = 4 // demand paged but is temporarily not being demand paged
};
inline TType Type()
{
return (TType)iType;
}
inline TState State()
{
return (TState)iState;
}
inline TAny* Owner()
{
return iOwner;
}
inline TUint32 Offset()
{
return iOffset;
}
inline TInt LockCount()
{
return iLockCount;
}
/** Return the index of the zone the page is in
*/
inline TUint8 Zone()
{
return iZone;
}
#ifdef _DEBUG
void Set(TType aType, TAny* aOwner, TUint32 aOffset);
void Change(TType aType,TState aState);
void SetState(TState aState);
void SetModifier(TAny* aModifier);
TInt CheckModified(TAny* aModifier);
void SetZone(TUint8 aZoneIndex);
#else
inline void Set(TType aType, TAny* aOwner, TUint32 aOffset)
{
(TUint16&)iType = aType; // also sets iState to EStateNormal
iOwner = aOwner;
iOffset = aOffset;
iModifier = 0;
}
inline void Change(TType aType,TState aState)
{
iType = aType;
iState = aState;
iModifier = 0;
}
inline void SetState(TState aState)
{
iState = aState;
iModifier = 0;
}
inline void SetModifier(TAny* aModifier)
{
iModifier = aModifier;
}
inline TInt CheckModified(TAny* aModifier)
{
return iModifier!=aModifier;
}
inline void SetZone(TUint8 aZoneIndex)
{
iZone = aZoneIndex;
}
#endif // !_DEBUG
void Lock();
TInt Unlock();
inline void SetFixed()
{
Set(EFixed,0,0);
iLockCount = 1;
}
inline void SetUnused()
{
__NK_ASSERT_DEBUG(0 == LockCount());
(TUint16&)iType = EUnused; // also sets iState to zero
iModifier = 0;
// do not modify iOffset in this function because cache cleaning operations
// rely on using this value
}
inline void SetChunk(TAny* aChunk, TUint32 aOffset)
{
Set(EChunk,aChunk,aOffset);
}
inline void SetCodeSegMemory(TAny* aCodeSegMemory,TUint32 aOffset)
{
Set(ECodeSegMemory,aCodeSegMemory,aOffset);
}
// inline void SetHwChunk(TAny* aChunk, TUint32 aOffset)
// {
// Set(EHwChunk,aChunk,aOffset);
// }
inline void SetPageTable(TUint32 aId)
{
Set(EPageTable,0,aId);
}
inline void SetPageDir(TUint32 aOsAsid, TInt aOffset)
{
Set(EPageDir,(TAny*)aOsAsid,aOffset);
}
inline void SetPtInfo(TUint32 aOffset)
{
Set(EPtInfo,0,aOffset);
}
inline void SetShadow(TPhysAddr aOrigPhys, TUint32 aOffset)
{
Set(EShadow,(TAny*)aOrigPhys,aOffset);
}
inline void SetPagedROM(TUint32 aOffset)
{
Set(EPagedROM,0,aOffset);
}
inline void SetPagedCode(TAny* aCodeSegMemory, TUint32 aOffset)
{
Set(EPagedCode,aCodeSegMemory,aOffset);
}
inline static SPageInfo* FromLink(SDblQueLink* aLink)
{ return (SPageInfo*)((TInt)aLink-_FOFF(SPageInfo,iLink)); }
inline TUint& PagedLock()
{ return (TUint&)iLink.iPrev; }
/**
Return the SPageInfo for a given page of physical RAM.
*/
inline static SPageInfo* FromPhysAddr(TPhysAddr aAddress);
/**
Return physical address of the RAM page which this SPageInfo object is associated.
If the address has no SPageInfo, then a null pointer is returned.
*/
static SPageInfo* SafeFromPhysAddr(TPhysAddr aAddress);
/**
Return physical address of the RAM page which this SPageInfo object is associated.
*/
inline TPhysAddr PhysAddr();
private:
TUint8 iType; // enum TType
TUint8 iState; // enum TState
TUint8 iZone; // The index of the zone the page is in, for use by DRamAllocator
TUint8 iSpare1;
TAny* iOwner; // owning object
TUint32 iOffset; // page offset withing owning object
TAny* iModifier; // pointer to object currently manipulating page
TUint32 iLockCount; // non-zero if page acquired by code outside of the kernel
TUint32 iSpare2;
public:
SDblQueLink iLink; // used for placing page into linked lists
};
/******************************************************************************
Per-page table info
Page count 0-256
Usage unused
chunk ptr (26 bits) offset (12 bits)
HW chunk ptr (26 bits) offset (12 bits)
global offset (12 bits)
shadow page offset (12 bits)
*******************************************************************************/
/**
@internalComponent
*/
struct SPageTableInfo
{
enum TAttribs
{
EUnused=0,
EChunk=1,
// EHwChunk=2,
EGlobal=3,
EShadow=4,
};
enum {EAttShift=6, EAttMask=0x3f};
inline TInt Attribs()
{return iAttPtr&EAttMask;}
inline TInt Count()
{return iCount;}
inline TUint32 Offset()
{return iOffset;}
inline TUint32 Ptr()
{return iAttPtr>>EAttShift;}
inline void SetUnused()
{iCount=0; iOffset=0; iAttPtr=0;}
inline void SetChunk(TUint32 aChunk, TUint32 aOffset)
{iOffset=aOffset; iAttPtr=(aChunk<<EAttShift)|EChunk;}
// inline void SetHwChunk(TUint32 aChunk, TUint32 aOffset)
// {iOffset=aOffset; iAttPtr=(aChunk<<EAttShift)|EHwChunk;}
inline void SetGlobal(TUint32 aOffset)
{iOffset=aOffset; iAttPtr=EGlobal;}
inline void SetShadow(TUint32 aOffset)
{iCount=0; iOffset=aOffset; iAttPtr=EShadow;}
TUint16 iCount;
TUint16 iOffset;
TUint32 iAttPtr;
};
/******************************************************************************
Bitmap Allocators
PageTableAllocator free page tables within allocated pages
PageTableLinearAllocator free linear addresses for page tables
ASIDAllocator free process slots
Page directory linear address = PageDirBase + (ASID<<PageDirSizeShift)
Page table linear address = PageTableBase + (PTID<<PageTableSizeShift)
Terminology
Page table cluster = no. of page tables in one page
Page table block = no. of SPageTableInfo structures in one page
Page table group = no. of page tables mapped with a single page table
Local = specific to process
Shared = subset of processes but not necessarily all
Global = all processes
*******************************************************************************/
/********************************************
* Address range allocator
********************************************/
/**
@internalComponent
*/
class TLinearSection
{
public:
static TLinearSection* New(TLinAddr aBase, TLinAddr aEnd);
public:
TLinAddr iBase;
TLinAddr iEnd;
TBitMapAllocator iAllocator; // bitmap of used PDE positions
};
/******************************************************************************
* Base class for MMU stuff
******************************************************************************/
/**
@internalComponent
*/
const TPhysAddr KRomPhysAddrInvalid=0xFFFFFFFFu;
/**
@internalComponent
*/
const TUint16 KPageTableNotPresentId=0xFFFF;
/**
@internalComponent
*/
const TInt KUnmapPagesTLBFlushDeferred=0x80000000;
/**
@internalComponent
*/
const TInt KUnmapPagesCountMask=0xffff;
/**
@internalComponent
*/
const TInt KMaxPages = 32;
/**
@internalComponent
*/
typedef TUint32 TPde;
/**
@internalComponent
*/
typedef TUint32 TPte;
class THwChunkAddressAllocator;
class RamCacheBase;
class Defrag;
class DRamAllocator;
class DMemModelCodeSegMemory;
class DMemModelChunk;
/**
@internalComponent
*/
class MmuBase
{
public:
enum TPanic
{
EAsyncFreePageStillInUse=0,
EPtLinAllocCreateFailed=1,
EPtAllocCreateFailed=2,
EPageInfoCreateFailed=3,
EAsyncFreeListCreateFailed=4,
EPtBlockCountCreateFailed=5,
EPtGroupCountCreateFailed=6,
EInvalidPageTableAtBoot=7,
ERamAllocMutexCreateFailed=8,
EHwChunkMutexCreateFailed=9,
ECreateKernelSectionFailed=10,
ECreateHwChunkAllocFailed=11,
EFreeHwChunkAddrInvalid=12,
EFreeHwChunkIndexInvalid=13,
EBadMappedPageAfterBoot=14,
ERecoverRamDriveAllocPTIDFailed=15,
EMapPageTableBadExpand=16,
ERecoverRamDriveBadPageTable=17,
ERecoverRamDriveBadPage=18,
EBadFreePhysicalRam=19,
EPageLockedTooManyTimes=20,
EPageUnlockedTooManyTimes=21,
EPageInfoSetWhenNotUnused=22,
ERamCacheAllocFailed=23,
EDefragAllocFailed=24,
EDefragUnknownPageType=25,
EDefragUnknownPageTableType=27,
EDefragUnknownChunkType=28,
EDefragStackAllocFailed=29,
EDefragKernelChunkNoPageTable=30,
EDefragProcessWrongPageDir=31,
};
public:
MmuBase();
// non virtual
TInt AllocPageTable();
TInt DoAllocPageTable(TPhysAddr& aPhysAddr);
TInt InitPageTableInfo(TInt aId);
TInt MapPageTable(TInt aId, TPhysAddr aPhysAddr, TBool aAllowExpand=ETrue);
void FreePageTable(TInt aId);
TBool DoFreePageTable(TInt aId);
TInt AllocPhysicalRam(TInt aSize, TPhysAddr& aPhysAddr, TInt aAlign=0);
TInt ZoneAllocPhysicalRam(TUint* aZoneIdList, TUint aZoneIdCount, TInt aSize, TPhysAddr& aPhysAddr, TInt aAlign=0);
TInt AllocPhysicalRam(TInt aNumPages, TPhysAddr* aPageList);
TInt ZoneAllocPhysicalRam(TUint* aZoneIdList, TUint aZoneIdCount, TInt aNumPages, TPhysAddr* aPageList);
TInt FreePhysicalRam(TPhysAddr aPhysAddr, TInt aSize);
TInt FreePhysicalRam(TInt aNumPages, TPhysAddr* aPageList);
TInt ClaimPhysicalRam(TPhysAddr aPhysAddr, TInt aSize);
TInt GetPageTableId(TPhysAddr aPtPhys);
void MapRamPage(TLinAddr aAddr, TPhysAddr aPage, TPte aPtePerm);
void UnmapAndFree(TLinAddr aAddr, TInt aNumPages);
void FreePages(TPhysAddr* aPageList, TInt aCount, TZonePageType aPageType);
void CreateKernelSection(TLinAddr aEnd, TInt aHwChunkAlign);
TInt AllocateAllPageTables(TLinAddr aLinAddr, TInt aSize, TPde aPdePerm, TInt aMapShift, SPageTableInfo::TAttribs aAttrib);
TInt AllocShadowPage(TLinAddr aRomAddr);
TInt FreeShadowPage(TLinAddr aRomAddr);
TInt FreezeShadowPage(TLinAddr aRomAddr);
TInt FreeRamInBytes();
TInt GetRamZonePageCount(TUint aId, SRamZonePageCount& aPageData);
TInt ModifyRamZoneFlags(TUint aId, TUint aClearMask, TUint aSetMask);
// RAM allocator and defrag interfaces.
void RamAllocLock();
void RamAllocUnlock();
TUint NumberOfFreeDpPages();
TInt MovePage(TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest);
TInt DiscardPage(TPhysAddr aAddr, TUint aBlockZoneId, TBool aBlockRest);
// virtual
virtual void Init1();
virtual void Init2();
virtual void Init3();
virtual THwChunkAddressAllocator* MappingRegion(TUint aMapAttr);
virtual TInt RecoverRamDrive();
virtual TInt CopyToShadowMemory(TLinAddr aDest, TLinAddr aSrc, TUint32 aLength);
// cpu dependent page moving method - cutils.cia
TInt MoveKernelStackPage(DChunk* aChunk, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest);
// pure virtual
virtual void DoInit2()=0;
virtual TBool PteIsPresent(TPte aPte)=0;
virtual TPhysAddr PtePhysAddr(TPte aPte, TInt aPteIndex)=0;
virtual TPhysAddr PdePhysAddr(TLinAddr aAddr)=0;
virtual void SetupInitialPageInfo(SPageInfo* aPageInfo, TLinAddr aChunkAddr, TInt aPdeIndex)=0;
virtual void SetupInitialPageTableInfo(TInt aId, TLinAddr aChunkAddr, TInt aNumPtes)=0;
virtual void AssignPageTable(TInt aId, TInt aUsage, TAny* aObject, TLinAddr aAddr, TPde aPdePerm)=0;
virtual TInt UnassignPageTable(TLinAddr aAddr)=0;
virtual void BootstrapPageTable(TInt aXptId, TPhysAddr aXptPhys, TInt aId, TPhysAddr aPhysAddr)=0;
virtual void FixupXPageTable(TInt aId, TLinAddr aTempMap, TPhysAddr aOld, TPhysAddr aNew)=0;
virtual TInt PageTableId(TLinAddr aAddr)=0;
virtual TInt BootPageTableId(TLinAddr aAddr, TPhysAddr& aPtPhys)=0;
virtual void ClearPageTable(TInt aId, TInt aFirstIndex=0)=0;
virtual TPhysAddr LinearToPhysical(TLinAddr aAddr)=0;
virtual TInt LinearToPhysical(TLinAddr aAddr, TInt aSize, TPhysAddr& aPhysicalAddress, TPhysAddr* aPhysicalPageList=NULL)=0;
virtual void MapRamPages(TInt aId, SPageInfo::TType aType, TAny* aPtr, TUint32 aOffset, const TPhysAddr* aPageList, TInt aNumPages, TPte aPtePerm)=0;
virtual void MapPhysicalPages(TInt aId, SPageInfo::TType aType, TAny* aPtr, TUint32 aOffset, TPhysAddr aPhysAddr, TInt aNumPages, TPte aPtePerm)=0;
virtual void RemapPage(TInt aId, TUint32 aAddr, TPhysAddr aOldAddr, TPhysAddr aNewAddr, TPte aPtePerm, DProcess* aProcess)=0;
virtual TInt UnmapPages(TInt aId, TUint32 aAddr, TInt aNumPages, TPhysAddr* aPageList, TBool aSetPagesFree, TInt& aNumPtes, TInt& aNumFree, DProcess* aProcess)=0;
virtual void ClearRamDrive(TLinAddr aStart)=0;
virtual TInt PdePtePermissions(TUint& aMapAttr, TPde& aPde, TPte& aPte)=0;
virtual void Map(TLinAddr aLinAddr, TPhysAddr aPhysAddr, TInt aSize, TPde aPdePerm, TPte aPtePerm, TInt aMapShift)=0;
virtual void Unmap(TLinAddr aLinAddr, TInt aSize)=0;
virtual void InitShadowPageTable(TInt aId, TLinAddr aRomAddr, TPhysAddr aOrigPhys)=0;
virtual void InitShadowPage(TPhysAddr aShadowPhys, TLinAddr aRomAddr)=0;
virtual void DoUnmapShadowPage(TInt aId, TLinAddr aRomAddr, TPhysAddr aOrigPhys)=0;
virtual TInt UnassignShadowPageTable(TLinAddr aRomAddr, TPhysAddr aOrigPhys)=0;
virtual void DoFreezeShadowPage(TInt aId, TLinAddr aRomAddr)=0;
virtual void FlushShadow(TLinAddr aRomAddr)=0;
virtual void AssignShadowPageTable(TInt aId, TLinAddr aRomAddr)=0;
virtual void ClearPages(TInt aNumPages, TPhysAddr* aPageList, TUint8 aClearByte = KChunkClearByteDefault)=0;
virtual void Pagify(TInt aId, TLinAddr aLinAddr)=0;
virtual void CacheMaintenanceOnDecommit(const TPhysAddr* aPhysAdr, TInt aPageCount)=0;
virtual void CacheMaintenanceOnDecommit(const TPhysAddr aPhysAdr)=0;
virtual void CacheMaintenanceOnPreserve(const TPhysAddr* aPhysAdr, TInt aPageCount, TUint aMapAttr)=0;
virtual void CacheMaintenanceOnPreserve(const TPhysAddr aPhysAdr, TUint aMapAttr)=0;
virtual void CacheMaintenanceOnPreserve(TPhysAddr aPhysAddr, TInt aSize, TLinAddr aLinAddr, TUint iMapAttr)=0;
// memory model dependent page moving methods - mdefrag.cpp
virtual TInt MoveCodeSegMemoryPage(DMemModelCodeSegMemory* aCodeSegMemory, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest)=0;
virtual TInt MoveCodeChunkPage(DChunk* aChunk, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest)=0;
virtual TInt MoveDataChunkPage(DChunk* aChunk, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest)=0;
// cpu and memory model dependent page moving methods - xmmu.cpp
virtual TInt RamDefragFault(TAny* aExceptionInfo)=0;
virtual void DisablePageModification(DMemModelChunk* aChunk, TInt aOffset)=0;
virtual TPte PtePermissions(TChunkType aChunkType)=0;
public:
static TUint32 RoundToPageSize(TUint32 aSize);
static TUint32 RoundToChunkSize(TUint32 aSize);
static TInt RoundUpRangeToPageSize(TUint32& aBase, TUint32& aSize);
static void Wait();
static void Signal();
static void WaitHwChunk();
static void SignalHwChunk();
static void Panic(TPanic aPanic);
public:
inline TLinAddr PageTableLinAddr(TInt aId)
{return iPageTableLinBase+(aId<<iPageTableShift);}
inline SPageTableInfo& PtInfo(TInt aId)
{return iPtInfo[aId];}
inline TLinAddr PtInfoBlockLinAddr(TInt aBlock)
{return (TLinAddr)iPtInfo+(aBlock<<iPageShift);}
/** Get the page table info block number from a page table ID
@param aId The ID of the page table.
@return The page table info block
*/
inline TInt PtInfoBlock(TInt aId)
{return aId >> iPtBlockShift;}
/**
@return The page table entry for the page table info pages.
*/
inline TPte PtInfoPtePerm()
{return iPtInfoPtePerm;}
public:
TInt AllocRamPages(TPhysAddr* aPageList, TInt aNumPages, TZonePageType aPageType, TUint aBlockedZoneId=KRamZoneInvalidId, TBool aBlockRest=EFalse);
TInt ZoneAllocRamPages(TUint* aZoneIdList, TUint aZoneIdCount, TPhysAddr* aPageList, TInt aNumPages, TZonePageType aPageType);
TInt AllocContiguousRam(TInt aSize, TPhysAddr& aPhysAddr, TZonePageType aPageType, TInt aAlign, TUint aBlockedZoneId=KRamZoneInvalidId, TBool aBlockRest=EFalse);
TInt ZoneAllocContiguousRam(TUint* aZoneIdList, TUint aZoneIdCount, TInt aSize, TPhysAddr& aPhysAddr, TZonePageType aPageType, TInt aAlign);
public:
TInt iPageSize; // page size in bytes
TInt iPageMask; // page size - 1
TInt iPageShift; // log2(page size)
TInt iChunkSize; // PDE size in bytes
TInt iChunkMask; // PDE size - 1
TInt iChunkShift; // log2(PDE size)
TInt iPageTableSize; // 2nd level page table size in bytes
TInt iPageTableMask; // 2nd level page table size - 1
TInt iPageTableShift; // log2(2nd level page table size)
TInt iPtClusterSize; // number of page tables per page
TInt iPtClusterMask; // number of page tables per page - 1
TInt iPtClusterShift; // log2(number of page tables per page)
TInt iPtBlockSize; // number of SPageTableInfo per page
TInt iPtBlockMask; // number of SPageTableInfo per page - 1
TInt iPtBlockShift; // log2(number of SPageTableInfo per page)
TInt iPtGroupSize; // number of page tables mapped by a page table
TInt iPtGroupMask; // number of page tables mapped by a page table - 1
TInt iPtGroupShift; // log2(number of page tables mapped by a page table)
TInt iMaxPageTables; // maximum number of page tables (<65536)
TInt* iPtBlockCount; // number of page table pages in each block
TInt* iPtGroupCount; // number of page table pages in each group
TInt iNumPages; // Number of pages being managed
SPageTableInfo* iPtInfo; // per-page table information array
TLinAddr iPageTableLinBase; // base address of page tables
DRamAllocator* iRamPageAllocator;
TBitMapAllocator* iPageTableAllocator; // NULL if page table size = page size
TBitMapAllocator* iPageTableLinearAllocator;
TInt iInitialFreeMemory;
TBool iAllocFailed;
TPte iPtInfoPtePerm;
TPte iPtPtePerm;
TPde iPtPdePerm;
TPte* iTempPte; // PTE used for temporary mappings
TLinAddr iTempAddr; // address corresponding to iTempPte
TLinearSection* iKernelSection; // bitmap used to allocate kernel section addresses
THwChunkAddressAllocator* iHwChunkAllocator; // address allocator for HW chunks in kernel section
TUint32 iMapSizes; // bit mask of supported mapping sizes
TUint iDecommitThreshold; // threshold for selective/global cache flush on decommit for VIPT caches
TLinAddr iRomLinearBase;
TLinAddr iRomLinearEnd;
TPte iShadowPtePerm;
TPde iShadowPdePerm;
// Page moving and defrag fault handling members.
TLinAddr iAltStackBase;
TLinAddr iDisabledAddr;
TInt iDisabledAddrAsid;
TPte* iDisabledPte;
TPte iDisabledOldVal;
RamCacheBase* iRamCache;
Defrag* iDefrag;
static DMutex* HwChunkMutex; // mutex protecting HW chunk address allocators
static DMutex* RamAllocatorMutex; // the main mutex protecting alloc/dealloc and most map/unmap
static MmuBase* TheMmu; // pointer to the single instance of this class
static const SRamZone* RamZoneConfig; /**<Pointer to variant specified array containing details on RAM banks and their allocation preferences*/
static TRamZoneCallback RamZoneCallback; /**<Pointer to callback function to be invoked when RAM power state changes*/
public:
friend class Monitor;
};
/******************************************************************************
* Address allocator for HW chunks
******************************************************************************/
/**
@internalComponent
*/
class THwChunkRegion
{
public:
inline THwChunkRegion(TInt aIndex, TInt aSize, TPde aPdePerm)
: iIndex((TUint16)aIndex), iRegionSize((TUint16)aSize), iPdePerm(aPdePerm)
{}
public:
TUint16 iIndex; // index of base of this region in linear section
TUint16 iRegionSize; // number of PDEs covered; 0 means page table
union
{
TPde iPdePerm; // PDE permissions for this region
THwChunkRegion* iNext; // used during deallocation
};
};
/**
@internalComponent
*/
class THwChunkPageTable : public THwChunkRegion
{
public:
THwChunkPageTable(TInt aIndex, TInt aSize, TPde aPdePerm);
static THwChunkPageTable* New(TInt aIndex, TPde aPdePerm);
public:
TBitMapAllocator iAllocator; // bitmap of used page positions
};
/**
@internalComponent
*/
class THwChunkAddressAllocator : public RPointerArray<THwChunkRegion>
{
public:
static THwChunkAddressAllocator* New(TInt aAlign, TLinearSection* aSection);
TLinAddr Alloc(TInt aSize, TInt aAlign, TInt aOffset, TPde aPdePerm);
THwChunkRegion* Free(TLinAddr aAddr, TInt aSize);
public:
THwChunkAddressAllocator();
TLinAddr SearchExisting(TInt aNumPages, TInt aPageAlign, TInt aPageOffset, TPde aPdePerm);
void Discard(THwChunkRegion* aRegion);
static TInt Order(const THwChunkRegion& a1, const THwChunkRegion& a2);
THwChunkRegion* NewRegion(TInt aIndex, TInt aSize, TPde aPdePerm);
THwChunkPageTable* NewPageTable(TInt aIndex, TPde aPdePerm, TInt aInitB, TInt aInitC);
public:
TInt iAlign; // alignment required for allocated addresses
TLinearSection* iSection; // linear section in which allocation occurs
};
/** Hardware chunk
@internalComponent
*/
class DMemModelChunkHw : public DPlatChunkHw
{
public:
virtual TInt Close(TAny* aPtr);
public:
TInt AllocateLinearAddress(TPde aPdePerm);
void DeallocateLinearAddress();
public:
THwChunkAddressAllocator* iAllocator;
};
/******************************************************************************
* MMU-specifc code segment data
******************************************************************************/
/**
@internalComponent
*/
class DMmuCodeSegMemory : public DEpocCodeSegMemory
{
public:
DMmuCodeSegMemory(DEpocCodeSeg* aCodeSeg);
~DMmuCodeSegMemory();
virtual TInt Create(TCodeSegCreateInfo& aInfo);
virtual TInt Loaded(TCodeSegCreateInfo& aInfo);
/**
Apply code relocations and import fixups to one page of code.
@param aBuffer The buffer containg the code
@param aCodeAddress The address the page will be mapped at
*/
void ApplyCodeFixups(TUint32* aBuffer, TLinAddr aCodeAddress);
/**
Apply code relocations and import fixups to one page of code.
Called by DMemModelCodeSegMemory::Loaded to fixup pages which are already paged-in.
@param aBuffer The buffer containg the code
@param aCodeAddress The address the page will be mapped at
*/
TInt ApplyCodeFixupsOnLoad(TUint32* aBuffer, TLinAddr aCodeAddress);
private:
TInt ReadBlockMap(const TCodeSegCreateInfo& aInfo);
TInt ReadFixupTables(const TCodeSegCreateInfo& aInfo);
public:
TBool iIsDemandPaged;
TInt iPageCount; // Number of pages used for code
TInt iDataPageCount; // Number of extra pages used to store data section
TUint8* iCodeRelocTable; // Code relocation information
TInt iCodeRelocTableSize; // Size of code relocation table in bytes
TUint8* iImportFixupTable; // Import fixup information
TInt iImportFixupTableSize; // Size of import fixup table in bytes
TUint32 iCodeDelta; // Code relocation delta
TUint32 iDataDelta; // Data relocation delta
TInt iCompressionType; // Compression scheme in use
TInt32* iCodePageOffsets; // Array of compressed page offsets within the file
TInt iCodeLocalDrive; // Local drive number
TBlockMap iBlockMap; // Kernel-side representation of block map
TInt iCodeStartInFile; // Offset of (possibly compressed) code from start of file
TAny* iDataSectionMemory; // pointer to saved copy of data section (when demand paging)
TInt iCodeAllocBase;
};
#endif