os/kernelhwsrv/kernel/eka/include/memmodel/epoc/mmubase/mmubase.h
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kernel/eka/include/memmodel/epoc/mmubase/mmubase.h	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,725 @@
     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\mmubase.h
    1.18 +// 
    1.19 +// WARNING: This file contains some APIs which are internal and are subject
    1.20 +//          to change without notice. Such APIs should therefore not be used
    1.21 +//          outside the Kernel and Hardware Services package.
    1.22 +//
    1.23 +
    1.24 +#ifndef __MMUBASE_H__
    1.25 +#define __MMUBASE_H__
    1.26 +#include <plat_priv.h>
    1.27 +#include <memmodel/epoc/mmubase/kblockmap.h>
    1.28 +
    1.29 +
    1.30 +/******************************************************************************
    1.31 + * Definitions common to all MMU memory models
    1.32 + ******************************************************************************/
    1.33 +
    1.34 +/**
    1.35 +@internalComponent
    1.36 +*/
    1.37 +struct SPageInfo
    1.38 +	{
    1.39 +	enum TType
    1.40 +		{
    1.41 +		EInvalid=0,			// No physical RAM exists for this page
    1.42 +		EFixed=1,			// RAM fixed at boot time, 
    1.43 +		EUnused=2,			// Page is unused
    1.44 +		EChunk=3,			// iOwner=DChunk*			iOffset=index into chunk
    1.45 +		ECodeSegMemory=4,	// iOwner=DCodeSegMemory*	iOffset=index into CodeSeg memory (Multiple Memory Model only)
    1.46 +//		EHwChunk=5,			// Not used
    1.47 +		EPageTable=6,		// iOwner=0					iOffset=index into KPageTableBase
    1.48 +		EPageDir=7,			// iOwner=ASID				iOffset=index into Page Directory
    1.49 +		EPtInfo=8,			// iOwner=0					iOffset=index into KPageTableInfoBase
    1.50 +		EShadow=9,			// iOwner=phys ROM page		iOffset=index into ROM
    1.51 +		EPagedROM=10,		// iOwner=0,				iOffset=index into ROM
    1.52 +		EPagedCode=11,		// iOwner=DCodeSegMemory*	iOffset=index into code chunk (not offset into CodeSeg!)
    1.53 +		EPagedData=12,		// NOT YET SUPPORTED
    1.54 +		EPagedCache=13,		// iOwner=DChunk*			iOffset=index into chunk 
    1.55 +		EPagedFree=14,		// In demand paging 'live list' but not used for any purpose
    1.56 +		};
    1.57 +
    1.58 +	enum TState
    1.59 +		{
    1.60 +		EStateNormal = 0,		// no special state
    1.61 +		EStatePagedYoung = 1,	// demand paged and is on the young list
    1.62 +		EStatePagedOld = 2,		// demand paged and is on the old list
    1.63 +		EStatePagedDead = 3,	// demand paged and is currently being modified
    1.64 +		EStatePagedLocked = 4	// demand paged but is temporarily not being demand paged
    1.65 +		};
    1.66 +
    1.67 +	inline TType Type()
    1.68 +		{
    1.69 +		return (TType)iType;
    1.70 +		}
    1.71 +	inline TState State()
    1.72 +		{
    1.73 +		return (TState)iState;
    1.74 +		}
    1.75 +	inline TAny* Owner()
    1.76 +		{
    1.77 +		return iOwner;
    1.78 +		}
    1.79 +	inline TUint32 Offset()
    1.80 +		{
    1.81 +		return iOffset;
    1.82 +		}
    1.83 +	inline TInt LockCount()
    1.84 +		{
    1.85 +		return iLockCount;
    1.86 +		}
    1.87 +
    1.88 +	/** Return the index of the zone the page is in
    1.89 +	*/
    1.90 +	inline TUint8 Zone()
    1.91 +		{
    1.92 +		return iZone;
    1.93 +		}
    1.94 +
    1.95 +#ifdef _DEBUG
    1.96 +	void Set(TType aType, TAny* aOwner, TUint32 aOffset);
    1.97 +	void Change(TType aType,TState aState);
    1.98 +	void SetState(TState aState);
    1.99 +	void SetModifier(TAny* aModifier);
   1.100 +	TInt CheckModified(TAny* aModifier);
   1.101 +	void SetZone(TUint8 aZoneIndex);
   1.102 +#else
   1.103 +	inline void Set(TType aType, TAny* aOwner, TUint32 aOffset)
   1.104 +		{
   1.105 +		(TUint16&)iType = aType; // also sets iState to EStateNormal
   1.106 +		iOwner = aOwner;
   1.107 +		iOffset = aOffset;
   1.108 +		iModifier = 0;
   1.109 +		}
   1.110 +	inline void Change(TType aType,TState aState)
   1.111 +		{
   1.112 +		iType = aType;
   1.113 +		iState = aState;
   1.114 +		iModifier = 0;
   1.115 +		}
   1.116 +	inline void SetState(TState aState)
   1.117 +		{
   1.118 +		iState = aState;
   1.119 +		iModifier = 0;
   1.120 +		}
   1.121 +	inline void SetModifier(TAny* aModifier)
   1.122 +		{
   1.123 +		iModifier = aModifier;
   1.124 +		}
   1.125 +	inline TInt CheckModified(TAny* aModifier)
   1.126 +		{
   1.127 +		return iModifier!=aModifier;
   1.128 +		}
   1.129 +	
   1.130 +	inline void SetZone(TUint8 aZoneIndex)
   1.131 +		{
   1.132 +		iZone = aZoneIndex;
   1.133 +		}
   1.134 +#endif // !_DEBUG
   1.135 +	void Lock();
   1.136 +	TInt Unlock();
   1.137 +
   1.138 +	inline void SetFixed()
   1.139 +		{
   1.140 +		Set(EFixed,0,0);
   1.141 +		iLockCount = 1;
   1.142 +		}
   1.143 +	inline void SetUnused()
   1.144 +		{
   1.145 +		__NK_ASSERT_DEBUG(0 == LockCount());
   1.146 +		(TUint16&)iType = EUnused; // also sets iState to zero
   1.147 +		iModifier = 0;
   1.148 +		// do not modify iOffset in this function because cache cleaning operations
   1.149 +		// rely on using this value
   1.150 +		}
   1.151 +	inline void SetChunk(TAny* aChunk, TUint32 aOffset)
   1.152 +		{
   1.153 +		Set(EChunk,aChunk,aOffset);
   1.154 +		}
   1.155 +	inline void SetCodeSegMemory(TAny* aCodeSegMemory,TUint32 aOffset)
   1.156 +		{
   1.157 +		Set(ECodeSegMemory,aCodeSegMemory,aOffset);
   1.158 +		}
   1.159 +//	inline void SetHwChunk(TAny* aChunk, TUint32 aOffset)
   1.160 +//		{
   1.161 +//		Set(EHwChunk,aChunk,aOffset);
   1.162 +//		}
   1.163 +	inline void SetPageTable(TUint32 aId)
   1.164 +		{
   1.165 +		Set(EPageTable,0,aId);
   1.166 +		}
   1.167 +	inline void SetPageDir(TUint32 aOsAsid, TInt aOffset)
   1.168 +		{
   1.169 +		Set(EPageDir,(TAny*)aOsAsid,aOffset);
   1.170 +		}
   1.171 +	inline void SetPtInfo(TUint32 aOffset)
   1.172 +		{
   1.173 +		Set(EPtInfo,0,aOffset);
   1.174 +		}
   1.175 +	inline void SetShadow(TPhysAddr aOrigPhys, TUint32 aOffset)
   1.176 +		{
   1.177 +		Set(EShadow,(TAny*)aOrigPhys,aOffset);
   1.178 +		}
   1.179 +	inline void SetPagedROM(TUint32 aOffset)
   1.180 +		{
   1.181 +		Set(EPagedROM,0,aOffset);
   1.182 +		}
   1.183 +	inline void SetPagedCode(TAny* aCodeSegMemory, TUint32 aOffset)
   1.184 +		{
   1.185 +		Set(EPagedCode,aCodeSegMemory,aOffset);
   1.186 +		}
   1.187 +
   1.188 +	inline static SPageInfo* FromLink(SDblQueLink* aLink)
   1.189 +		{ return (SPageInfo*)((TInt)aLink-_FOFF(SPageInfo,iLink)); }
   1.190 +
   1.191 +	inline TUint& PagedLock()
   1.192 +		{ return (TUint&)iLink.iPrev; }
   1.193 +
   1.194 +	/**
   1.195 +	Return the SPageInfo for a given page of physical RAM.
   1.196 +	*/
   1.197 +	inline static SPageInfo* FromPhysAddr(TPhysAddr aAddress);
   1.198 +
   1.199 +	/**
   1.200 +	Return physical address of the RAM page which this SPageInfo object is associated.
   1.201 +	If the address has no SPageInfo, then a null pointer is returned.
   1.202 +	*/
   1.203 +	static SPageInfo* SafeFromPhysAddr(TPhysAddr aAddress);
   1.204 +
   1.205 +	/**
   1.206 +	Return physical address of the RAM page which this SPageInfo object is associated.
   1.207 +	*/
   1.208 +	inline TPhysAddr PhysAddr();
   1.209 +
   1.210 +private:
   1.211 +	TUint8 iType;			// enum TType
   1.212 +	TUint8 iState;			// enum TState
   1.213 +	TUint8 iZone;			// The index of the zone the page is in, for use by DRamAllocator
   1.214 +	TUint8 iSpare1;
   1.215 +	TAny* iOwner;			// owning object 
   1.216 +	TUint32 iOffset;		// page offset withing owning object
   1.217 +	TAny* iModifier;		// pointer to object currently manipulating page
   1.218 +	TUint32 iLockCount;		// non-zero if page acquired by code outside of the kernel
   1.219 +	TUint32 iSpare2;
   1.220 +public:
   1.221 +	SDblQueLink iLink;		// used for placing page into linked lists
   1.222 +	};
   1.223 +
   1.224 +/******************************************************************************
   1.225 +Per-page table info
   1.226 +
   1.227 +Page count	0-256
   1.228 +Usage		unused
   1.229 +			chunk		ptr (26 bits) offset (12 bits)
   1.230 +			HW chunk	ptr (26 bits) offset (12 bits)
   1.231 +			global		offset (12 bits)
   1.232 +			shadow page	offset (12 bits)
   1.233 +
   1.234 +
   1.235 +*******************************************************************************/
   1.236 +/**
   1.237 +@internalComponent
   1.238 +*/
   1.239 +struct SPageTableInfo
   1.240 +	{
   1.241 +	enum TAttribs
   1.242 +		{
   1.243 +		EUnused=0,
   1.244 +		EChunk=1,
   1.245 +//		EHwChunk=2,
   1.246 +		EGlobal=3,
   1.247 +		EShadow=4,
   1.248 +		};
   1.249 +
   1.250 +	enum {EAttShift=6, EAttMask=0x3f};
   1.251 +
   1.252 +	inline TInt Attribs()
   1.253 +		{return iAttPtr&EAttMask;}
   1.254 +	inline TInt Count()
   1.255 +		{return iCount;}
   1.256 +	inline TUint32 Offset()
   1.257 +		{return iOffset;}
   1.258 +	inline TUint32 Ptr()
   1.259 +		{return iAttPtr>>EAttShift;}
   1.260 +
   1.261 +	inline void SetUnused()
   1.262 +		{iCount=0; iOffset=0; iAttPtr=0;}
   1.263 +	inline void SetChunk(TUint32 aChunk, TUint32 aOffset)
   1.264 +		{iOffset=aOffset; iAttPtr=(aChunk<<EAttShift)|EChunk;}
   1.265 +//	inline void SetHwChunk(TUint32 aChunk, TUint32 aOffset)
   1.266 +//		{iOffset=aOffset; iAttPtr=(aChunk<<EAttShift)|EHwChunk;}
   1.267 +	inline void SetGlobal(TUint32 aOffset)
   1.268 +		{iOffset=aOffset; iAttPtr=EGlobal;}
   1.269 +	inline void SetShadow(TUint32 aOffset)
   1.270 +		{iCount=0; iOffset=aOffset; iAttPtr=EShadow;}
   1.271 +
   1.272 +	TUint16 iCount;
   1.273 +	TUint16 iOffset;
   1.274 +	TUint32 iAttPtr;
   1.275 +	};
   1.276 +
   1.277 +/******************************************************************************
   1.278 +Bitmap Allocators
   1.279 +
   1.280 +PageTableAllocator				free page tables within allocated pages
   1.281 +PageTableLinearAllocator		free linear addresses for page tables
   1.282 +ASIDAllocator					free process slots
   1.283 +
   1.284 +Page directory linear address = PageDirBase + (ASID<<PageDirSizeShift)
   1.285 +Page table linear address = PageTableBase + (PTID<<PageTableSizeShift)
   1.286 +
   1.287 +Terminology
   1.288 +
   1.289 +  Page table cluster = no. of page tables in one page
   1.290 +  Page table block = no. of SPageTableInfo structures in one page
   1.291 +  Page table group = no. of page tables mapped with a single page table
   1.292 +
   1.293 +  Local = specific to process
   1.294 +  Shared = subset of processes but not necessarily all
   1.295 +  Global = all processes
   1.296 +*******************************************************************************/
   1.297 +
   1.298 +/********************************************
   1.299 + * Address range allocator
   1.300 + ********************************************/
   1.301 +/**
   1.302 +@internalComponent
   1.303 +*/
   1.304 +class TLinearSection
   1.305 +	{
   1.306 +public:
   1.307 +	static TLinearSection* New(TLinAddr aBase, TLinAddr aEnd);
   1.308 +public:
   1.309 +	TLinAddr iBase;
   1.310 +	TLinAddr iEnd;
   1.311 +	TBitMapAllocator iAllocator;	// bitmap of used PDE positions
   1.312 +	};
   1.313 +
   1.314 +/******************************************************************************
   1.315 + * Base class for MMU stuff
   1.316 + ******************************************************************************/
   1.317 +
   1.318 +/**
   1.319 +@internalComponent
   1.320 +*/
   1.321 +const TPhysAddr KRomPhysAddrInvalid=0xFFFFFFFFu;
   1.322 +
   1.323 +/**
   1.324 +@internalComponent
   1.325 +*/
   1.326 +const TUint16 KPageTableNotPresentId=0xFFFF;
   1.327 +
   1.328 +/**
   1.329 +@internalComponent
   1.330 +*/
   1.331 +const TInt KUnmapPagesTLBFlushDeferred=0x80000000;
   1.332 +
   1.333 +/**
   1.334 +@internalComponent
   1.335 +*/
   1.336 +const TInt KUnmapPagesCountMask=0xffff;
   1.337 +
   1.338 +/**
   1.339 +@internalComponent
   1.340 +*/
   1.341 +const TInt KMaxPages = 32;
   1.342 +
   1.343 +/**
   1.344 +@internalComponent
   1.345 +*/
   1.346 +typedef TUint32 TPde;
   1.347 +
   1.348 +/**
   1.349 +@internalComponent
   1.350 +*/
   1.351 +typedef TUint32 TPte;
   1.352 +
   1.353 +class THwChunkAddressAllocator;
   1.354 +class RamCacheBase;
   1.355 +class Defrag;
   1.356 +class DRamAllocator;
   1.357 +class DMemModelCodeSegMemory;
   1.358 +class DMemModelChunk;
   1.359 +
   1.360 +/**
   1.361 +@internalComponent
   1.362 +*/
   1.363 +class MmuBase
   1.364 +	{
   1.365 +public:
   1.366 +	enum TPanic
   1.367 +		{
   1.368 +		EAsyncFreePageStillInUse=0,
   1.369 +		EPtLinAllocCreateFailed=1,
   1.370 +		EPtAllocCreateFailed=2,
   1.371 +		EPageInfoCreateFailed=3,
   1.372 +		EAsyncFreeListCreateFailed=4,
   1.373 +		EPtBlockCountCreateFailed=5,
   1.374 +		EPtGroupCountCreateFailed=6,
   1.375 +		EInvalidPageTableAtBoot=7,
   1.376 +		ERamAllocMutexCreateFailed=8,
   1.377 +		EHwChunkMutexCreateFailed=9,
   1.378 +		ECreateKernelSectionFailed=10,
   1.379 +		ECreateHwChunkAllocFailed=11,
   1.380 +		EFreeHwChunkAddrInvalid=12,
   1.381 +		EFreeHwChunkIndexInvalid=13,
   1.382 +		EBadMappedPageAfterBoot=14,
   1.383 +		ERecoverRamDriveAllocPTIDFailed=15,
   1.384 +		EMapPageTableBadExpand=16,
   1.385 +		ERecoverRamDriveBadPageTable=17,
   1.386 +		ERecoverRamDriveBadPage=18,
   1.387 +		EBadFreePhysicalRam=19,
   1.388 +		EPageLockedTooManyTimes=20,
   1.389 +		EPageUnlockedTooManyTimes=21,
   1.390 +		EPageInfoSetWhenNotUnused=22,
   1.391 +		ERamCacheAllocFailed=23,
   1.392 +		EDefragAllocFailed=24,
   1.393 +		EDefragUnknownPageType=25,
   1.394 +		EDefragUnknownPageTableType=27,
   1.395 +		EDefragUnknownChunkType=28,
   1.396 +		EDefragStackAllocFailed=29,
   1.397 +		EDefragKernelChunkNoPageTable=30,
   1.398 +		EDefragProcessWrongPageDir=31,
   1.399 +		};
   1.400 +public:
   1.401 +	MmuBase();
   1.402 +
   1.403 +	// non virtual
   1.404 +	TInt AllocPageTable();
   1.405 +	TInt DoAllocPageTable(TPhysAddr& aPhysAddr);
   1.406 +	TInt InitPageTableInfo(TInt aId);
   1.407 +	TInt MapPageTable(TInt aId, TPhysAddr aPhysAddr, TBool aAllowExpand=ETrue);
   1.408 +	void FreePageTable(TInt aId);
   1.409 +	TBool DoFreePageTable(TInt aId);
   1.410 +	TInt AllocPhysicalRam(TInt aSize, TPhysAddr& aPhysAddr, TInt aAlign=0);
   1.411 +	TInt ZoneAllocPhysicalRam(TUint* aZoneIdList, TUint aZoneIdCount, TInt aSize, TPhysAddr& aPhysAddr, TInt aAlign=0);
   1.412 +	TInt AllocPhysicalRam(TInt aNumPages, TPhysAddr* aPageList);
   1.413 +	TInt ZoneAllocPhysicalRam(TUint* aZoneIdList, TUint aZoneIdCount, TInt aNumPages, TPhysAddr* aPageList);
   1.414 +	TInt FreePhysicalRam(TPhysAddr aPhysAddr, TInt aSize);
   1.415 +	TInt FreePhysicalRam(TInt aNumPages, TPhysAddr* aPageList);
   1.416 +	TInt ClaimPhysicalRam(TPhysAddr aPhysAddr, TInt aSize);
   1.417 +	TInt GetPageTableId(TPhysAddr aPtPhys);
   1.418 +	void MapRamPage(TLinAddr aAddr, TPhysAddr aPage, TPte aPtePerm);
   1.419 +	void UnmapAndFree(TLinAddr aAddr, TInt aNumPages);
   1.420 +	void FreePages(TPhysAddr* aPageList, TInt aCount, TZonePageType aPageType);
   1.421 +	void CreateKernelSection(TLinAddr aEnd, TInt aHwChunkAlign);
   1.422 +	TInt AllocateAllPageTables(TLinAddr aLinAddr, TInt aSize, TPde aPdePerm, TInt aMapShift, SPageTableInfo::TAttribs aAttrib);
   1.423 +	TInt AllocShadowPage(TLinAddr aRomAddr);
   1.424 +	TInt FreeShadowPage(TLinAddr aRomAddr);
   1.425 +	TInt FreezeShadowPage(TLinAddr aRomAddr);
   1.426 +	TInt FreeRamInBytes();
   1.427 +	TInt GetRamZonePageCount(TUint aId, SRamZonePageCount& aPageData);
   1.428 +	TInt ModifyRamZoneFlags(TUint aId, TUint aClearMask, TUint aSetMask);
   1.429 +
   1.430 +	// RAM allocator and defrag interfaces.
   1.431 +	void RamAllocLock();
   1.432 +	void RamAllocUnlock();
   1.433 +	TUint NumberOfFreeDpPages();
   1.434 +	TInt MovePage(TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest);
   1.435 +	TInt DiscardPage(TPhysAddr aAddr, TUint aBlockZoneId, TBool aBlockRest);
   1.436 +
   1.437 +	// virtual
   1.438 +	virtual void Init1();
   1.439 +	virtual void Init2();
   1.440 +	virtual void Init3();
   1.441 +	virtual THwChunkAddressAllocator* MappingRegion(TUint aMapAttr);
   1.442 +	virtual TInt RecoverRamDrive();
   1.443 +	virtual TInt CopyToShadowMemory(TLinAddr aDest, TLinAddr aSrc, TUint32 aLength);
   1.444 +	
   1.445 +	// cpu dependent page moving method - cutils.cia
   1.446 +	TInt MoveKernelStackPage(DChunk* aChunk, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest);
   1.447 +
   1.448 +	// pure virtual
   1.449 +	virtual void DoInit2()=0;
   1.450 +	virtual TBool PteIsPresent(TPte aPte)=0;
   1.451 +	virtual TPhysAddr PtePhysAddr(TPte aPte, TInt aPteIndex)=0;
   1.452 +	virtual TPhysAddr PdePhysAddr(TLinAddr aAddr)=0;
   1.453 +	virtual void SetupInitialPageInfo(SPageInfo* aPageInfo, TLinAddr aChunkAddr, TInt aPdeIndex)=0;
   1.454 +	virtual void SetupInitialPageTableInfo(TInt aId, TLinAddr aChunkAddr, TInt aNumPtes)=0;
   1.455 +	virtual void AssignPageTable(TInt aId, TInt aUsage, TAny* aObject, TLinAddr aAddr, TPde aPdePerm)=0;
   1.456 +	virtual TInt UnassignPageTable(TLinAddr aAddr)=0;
   1.457 +	virtual void BootstrapPageTable(TInt aXptId, TPhysAddr aXptPhys, TInt aId, TPhysAddr aPhysAddr)=0;
   1.458 +	virtual void FixupXPageTable(TInt aId, TLinAddr aTempMap, TPhysAddr aOld, TPhysAddr aNew)=0;
   1.459 +	virtual TInt PageTableId(TLinAddr aAddr)=0;
   1.460 +	virtual TInt BootPageTableId(TLinAddr aAddr, TPhysAddr& aPtPhys)=0;
   1.461 +	virtual void ClearPageTable(TInt aId, TInt aFirstIndex=0)=0;
   1.462 +	virtual TPhysAddr LinearToPhysical(TLinAddr aAddr)=0;
   1.463 +	virtual TInt LinearToPhysical(TLinAddr aAddr, TInt aSize, TPhysAddr& aPhysicalAddress, TPhysAddr* aPhysicalPageList=NULL)=0;
   1.464 +	virtual void MapRamPages(TInt aId, SPageInfo::TType aType, TAny* aPtr, TUint32 aOffset, const TPhysAddr* aPageList, TInt aNumPages, TPte aPtePerm)=0;
   1.465 +	virtual void MapPhysicalPages(TInt aId, SPageInfo::TType aType, TAny* aPtr, TUint32 aOffset, TPhysAddr aPhysAddr, TInt aNumPages, TPte aPtePerm)=0;
   1.466 +	virtual void RemapPage(TInt aId, TUint32 aAddr, TPhysAddr aOldAddr, TPhysAddr aNewAddr, TPte aPtePerm, DProcess* aProcess)=0;
   1.467 +	virtual TInt UnmapPages(TInt aId, TUint32 aAddr, TInt aNumPages, TPhysAddr* aPageList, TBool aSetPagesFree, TInt& aNumPtes, TInt& aNumFree, DProcess* aProcess)=0;
   1.468 +	virtual void ClearRamDrive(TLinAddr aStart)=0;
   1.469 +	virtual TInt PdePtePermissions(TUint& aMapAttr, TPde& aPde, TPte& aPte)=0;
   1.470 +	virtual void Map(TLinAddr aLinAddr, TPhysAddr aPhysAddr, TInt aSize, TPde aPdePerm, TPte aPtePerm, TInt aMapShift)=0;
   1.471 +	virtual void Unmap(TLinAddr aLinAddr, TInt aSize)=0;
   1.472 +	virtual void InitShadowPageTable(TInt aId, TLinAddr aRomAddr, TPhysAddr aOrigPhys)=0;
   1.473 +	virtual void InitShadowPage(TPhysAddr aShadowPhys, TLinAddr aRomAddr)=0;
   1.474 +	virtual void DoUnmapShadowPage(TInt aId, TLinAddr aRomAddr, TPhysAddr aOrigPhys)=0;
   1.475 +	virtual TInt UnassignShadowPageTable(TLinAddr aRomAddr, TPhysAddr aOrigPhys)=0;
   1.476 +	virtual void DoFreezeShadowPage(TInt aId, TLinAddr aRomAddr)=0;
   1.477 +	virtual void FlushShadow(TLinAddr aRomAddr)=0;
   1.478 +	virtual void AssignShadowPageTable(TInt aId, TLinAddr aRomAddr)=0;
   1.479 +	virtual void ClearPages(TInt aNumPages, TPhysAddr* aPageList, TUint8 aClearByte = KChunkClearByteDefault)=0;
   1.480 +	virtual void Pagify(TInt aId, TLinAddr aLinAddr)=0;
   1.481 +	virtual void CacheMaintenanceOnDecommit(const TPhysAddr* aPhysAdr, TInt aPageCount)=0;
   1.482 +	virtual void CacheMaintenanceOnDecommit(const TPhysAddr aPhysAdr)=0;
   1.483 +	virtual void CacheMaintenanceOnPreserve(const TPhysAddr* aPhysAdr, TInt aPageCount, TUint aMapAttr)=0;
   1.484 +	virtual void CacheMaintenanceOnPreserve(const TPhysAddr aPhysAdr, TUint aMapAttr)=0;
   1.485 +	virtual void CacheMaintenanceOnPreserve(TPhysAddr aPhysAddr, TInt aSize, TLinAddr aLinAddr, TUint iMapAttr)=0;
   1.486 +
   1.487 +	// memory model dependent page moving methods - mdefrag.cpp
   1.488 +	virtual TInt MoveCodeSegMemoryPage(DMemModelCodeSegMemory* aCodeSegMemory, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest)=0;
   1.489 +	virtual TInt MoveCodeChunkPage(DChunk* aChunk, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest)=0;
   1.490 +	virtual TInt MoveDataChunkPage(DChunk* aChunk, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest)=0;
   1.491 +
   1.492 +	// cpu and memory model dependent page moving methods - xmmu.cpp
   1.493 +	virtual TInt RamDefragFault(TAny* aExceptionInfo)=0;
   1.494 +	virtual void DisablePageModification(DMemModelChunk* aChunk, TInt aOffset)=0;
   1.495 +	virtual TPte PtePermissions(TChunkType aChunkType)=0;
   1.496 +
   1.497 +public:
   1.498 +	static TUint32 RoundToPageSize(TUint32 aSize);
   1.499 +	static TUint32 RoundToChunkSize(TUint32 aSize);
   1.500 +	static TInt RoundUpRangeToPageSize(TUint32& aBase, TUint32& aSize);
   1.501 +	static void Wait();
   1.502 +	static void Signal();
   1.503 +	static void WaitHwChunk();
   1.504 +	static void SignalHwChunk();
   1.505 +	static void Panic(TPanic aPanic);
   1.506 +public:
   1.507 +	inline TLinAddr PageTableLinAddr(TInt aId)
   1.508 +		{return iPageTableLinBase+(aId<<iPageTableShift);}
   1.509 +	inline SPageTableInfo& PtInfo(TInt aId)
   1.510 +		{return iPtInfo[aId];}
   1.511 +
   1.512 +	inline TLinAddr PtInfoBlockLinAddr(TInt aBlock)
   1.513 +		{return (TLinAddr)iPtInfo+(aBlock<<iPageShift);}
   1.514 +
   1.515 +	/** Get the page table info block number from a page table ID
   1.516 +	@param aId The ID of the page table.
   1.517 +	@return The page table info block
   1.518 +	*/
   1.519 +	inline TInt PtInfoBlock(TInt aId)
   1.520 +		{return aId >> iPtBlockShift;}
   1.521 +
   1.522 +	/**
   1.523 +	@return The page table entry for the page table info pages.
   1.524 +	*/
   1.525 +	inline TPte PtInfoPtePerm()
   1.526 +		{return iPtInfoPtePerm;}
   1.527 +	
   1.528 +public:
   1.529 +	TInt AllocRamPages(TPhysAddr* aPageList, TInt aNumPages, TZonePageType aPageType, TUint aBlockedZoneId=KRamZoneInvalidId, TBool aBlockRest=EFalse);
   1.530 +	TInt ZoneAllocRamPages(TUint* aZoneIdList, TUint aZoneIdCount, TPhysAddr* aPageList, TInt aNumPages, TZonePageType aPageType);
   1.531 +	TInt AllocContiguousRam(TInt aSize, TPhysAddr& aPhysAddr, TZonePageType aPageType, TInt aAlign, TUint aBlockedZoneId=KRamZoneInvalidId, TBool aBlockRest=EFalse);
   1.532 +	TInt ZoneAllocContiguousRam(TUint* aZoneIdList, TUint aZoneIdCount, TInt aSize, TPhysAddr& aPhysAddr, TZonePageType aPageType, TInt aAlign);
   1.533 +
   1.534 +public:
   1.535 +	TInt iPageSize;				// page size in bytes
   1.536 +	TInt iPageMask;				// page size - 1
   1.537 +	TInt iPageShift;			// log2(page size)
   1.538 +	TInt iChunkSize;			// PDE size in bytes
   1.539 +	TInt iChunkMask;			// PDE size - 1
   1.540 +	TInt iChunkShift;			// log2(PDE size)
   1.541 +	TInt iPageTableSize;		// 2nd level page table size in bytes
   1.542 +	TInt iPageTableMask;		// 2nd level page table size - 1
   1.543 +	TInt iPageTableShift;		// log2(2nd level page table size)
   1.544 +	TInt iPtClusterSize;		// number of page tables per page
   1.545 +	TInt iPtClusterMask;		// number of page tables per page - 1
   1.546 +	TInt iPtClusterShift;		// log2(number of page tables per page)
   1.547 +	TInt iPtBlockSize;			// number of SPageTableInfo per page
   1.548 +	TInt iPtBlockMask;			// number of SPageTableInfo per page - 1
   1.549 +	TInt iPtBlockShift;			// log2(number of SPageTableInfo per page)
   1.550 +	TInt iPtGroupSize;			// number of page tables mapped by a page table
   1.551 +	TInt iPtGroupMask;			// number of page tables mapped by a page table - 1
   1.552 +	TInt iPtGroupShift;			// log2(number of page tables mapped by a page table)
   1.553 +	TInt iMaxPageTables;		// maximum number of page tables (<65536)
   1.554 +	TInt* iPtBlockCount;		// number of page table pages in each block
   1.555 +	TInt* iPtGroupCount;		// number of page table pages in each group
   1.556 +	TInt iNumPages;				// Number of pages being managed
   1.557 +	SPageTableInfo* iPtInfo;	// per-page table information array
   1.558 +	TLinAddr iPageTableLinBase;	// base address of page tables
   1.559 +	DRamAllocator* iRamPageAllocator;
   1.560 +	TBitMapAllocator* iPageTableAllocator;	// NULL if page table size = page size
   1.561 +	TBitMapAllocator* iPageTableLinearAllocator;
   1.562 +	TInt iInitialFreeMemory;
   1.563 +	TBool iAllocFailed;
   1.564 +	TPte iPtInfoPtePerm;
   1.565 +	TPte iPtPtePerm;
   1.566 +	TPde iPtPdePerm;
   1.567 +	TPte* iTempPte;				// PTE used for temporary mappings
   1.568 +	TLinAddr iTempAddr;			// address corresponding to iTempPte
   1.569 +	TLinearSection* iKernelSection;		// bitmap used to allocate kernel section addresses
   1.570 +	THwChunkAddressAllocator* iHwChunkAllocator;	// address allocator for HW chunks in kernel section
   1.571 +	TUint32 iMapSizes;			// bit mask of supported mapping sizes
   1.572 +	TUint iDecommitThreshold;	// threshold for selective/global cache flush on decommit for VIPT caches
   1.573 +	TLinAddr iRomLinearBase;
   1.574 +	TLinAddr iRomLinearEnd;
   1.575 +	TPte iShadowPtePerm;
   1.576 +	TPde iShadowPdePerm;
   1.577 +
   1.578 +	// Page moving and defrag fault handling members.
   1.579 +	TLinAddr iAltStackBase;
   1.580 +	TLinAddr iDisabledAddr;
   1.581 +	TInt iDisabledAddrAsid;
   1.582 +	TPte* iDisabledPte;
   1.583 +	TPte iDisabledOldVal;
   1.584 +
   1.585 +	RamCacheBase* iRamCache;
   1.586 +	Defrag* iDefrag;
   1.587 +
   1.588 +	static DMutex* HwChunkMutex;	// mutex protecting HW chunk address allocators
   1.589 +	static DMutex* RamAllocatorMutex;	// the main mutex protecting alloc/dealloc and most map/unmap
   1.590 +	static MmuBase* TheMmu;		// pointer to the single instance of this class
   1.591 +	static const SRamZone* RamZoneConfig; /**<Pointer to variant specified array containing details on RAM banks and their allocation preferences*/
   1.592 +	static TRamZoneCallback RamZoneCallback; /**<Pointer to callback function to be invoked when RAM power state changes*/
   1.593 +
   1.594 +public:
   1.595 +	friend class Monitor;
   1.596 +	};
   1.597 +
   1.598 +
   1.599 +/******************************************************************************
   1.600 + * Address allocator for HW chunks
   1.601 + ******************************************************************************/
   1.602 +
   1.603 +/**
   1.604 +@internalComponent
   1.605 +*/
   1.606 +class THwChunkRegion
   1.607 +	{
   1.608 +public:
   1.609 +	inline THwChunkRegion(TInt aIndex, TInt aSize, TPde aPdePerm)
   1.610 +				: iIndex((TUint16)aIndex), iRegionSize((TUint16)aSize), iPdePerm(aPdePerm)
   1.611 +				{}
   1.612 +public:
   1.613 +	TUint16 iIndex;				// index of base of this region in linear section
   1.614 +	TUint16 iRegionSize;		// number of PDEs covered; 0 means page table
   1.615 +	union
   1.616 +		{
   1.617 +		TPde iPdePerm;			// PDE permissions for this region
   1.618 +		THwChunkRegion* iNext;	// used during deallocation
   1.619 +		};
   1.620 +	};
   1.621 +
   1.622 +/**
   1.623 +@internalComponent
   1.624 +*/
   1.625 +class THwChunkPageTable : public THwChunkRegion
   1.626 +	{
   1.627 +public:
   1.628 +	THwChunkPageTable(TInt aIndex, TInt aSize, TPde aPdePerm);
   1.629 +	static THwChunkPageTable* New(TInt aIndex, TPde aPdePerm);
   1.630 +public:
   1.631 +	TBitMapAllocator iAllocator;	// bitmap of used page positions
   1.632 +	};
   1.633 +
   1.634 +/**
   1.635 +@internalComponent
   1.636 +*/
   1.637 +class THwChunkAddressAllocator : public RPointerArray<THwChunkRegion>
   1.638 +	{
   1.639 +public:
   1.640 +	static THwChunkAddressAllocator* New(TInt aAlign, TLinearSection* aSection);
   1.641 +	TLinAddr Alloc(TInt aSize, TInt aAlign, TInt aOffset, TPde aPdePerm);
   1.642 +	THwChunkRegion* Free(TLinAddr aAddr, TInt aSize);
   1.643 +public:
   1.644 +	THwChunkAddressAllocator();
   1.645 +	TLinAddr SearchExisting(TInt aNumPages, TInt aPageAlign, TInt aPageOffset, TPde aPdePerm);
   1.646 +	void Discard(THwChunkRegion* aRegion);
   1.647 +	static TInt Order(const THwChunkRegion& a1, const THwChunkRegion& a2);
   1.648 +	THwChunkRegion* NewRegion(TInt aIndex, TInt aSize, TPde aPdePerm);
   1.649 +	THwChunkPageTable* NewPageTable(TInt aIndex, TPde aPdePerm, TInt aInitB, TInt aInitC);
   1.650 +public:
   1.651 +	TInt iAlign;				// alignment required for allocated addresses
   1.652 +	TLinearSection* iSection;	// linear section in which allocation occurs
   1.653 +	};
   1.654 +
   1.655 +
   1.656 +/** Hardware chunk
   1.657 +
   1.658 +@internalComponent
   1.659 +*/
   1.660 +class DMemModelChunkHw : public DPlatChunkHw
   1.661 +	{
   1.662 +public:
   1.663 +	virtual TInt Close(TAny* aPtr);
   1.664 +public:
   1.665 +	TInt AllocateLinearAddress(TPde aPdePerm);
   1.666 +	void DeallocateLinearAddress();
   1.667 +public:
   1.668 +	THwChunkAddressAllocator* iAllocator;
   1.669 +	};
   1.670 +
   1.671 +
   1.672 +/******************************************************************************
   1.673 + * MMU-specifc code segment data
   1.674 + ******************************************************************************/
   1.675 +
   1.676 +/**
   1.677 +@internalComponent
   1.678 +*/
   1.679 +class DMmuCodeSegMemory : public DEpocCodeSegMemory
   1.680 +	{
   1.681 +public:
   1.682 +	DMmuCodeSegMemory(DEpocCodeSeg* aCodeSeg);
   1.683 +	~DMmuCodeSegMemory();
   1.684 +	virtual TInt Create(TCodeSegCreateInfo& aInfo);
   1.685 +	virtual TInt Loaded(TCodeSegCreateInfo& aInfo);
   1.686 +
   1.687 +	/**
   1.688 +	Apply code relocations and import fixups to one page of code.
   1.689 +	@param aBuffer The buffer containg the code
   1.690 +	@param aCodeAddress The address the page will be mapped at
   1.691 +	*/
   1.692 +	void ApplyCodeFixups(TUint32* aBuffer, TLinAddr aCodeAddress);
   1.693 +
   1.694 +	/**
   1.695 +	Apply code relocations and import fixups to one page of code.
   1.696 +	Called by DMemModelCodeSegMemory::Loaded to fixup pages which are already paged-in.
   1.697 +
   1.698 +	@param aBuffer The buffer containg the code
   1.699 +	@param aCodeAddress The address the page will be mapped at
   1.700 +	*/
   1.701 +	TInt ApplyCodeFixupsOnLoad(TUint32* aBuffer, TLinAddr aCodeAddress);
   1.702 +private:
   1.703 +	TInt ReadBlockMap(const TCodeSegCreateInfo& aInfo);
   1.704 +	TInt ReadFixupTables(const TCodeSegCreateInfo& aInfo);
   1.705 +public:
   1.706 +	TBool iIsDemandPaged;
   1.707 +
   1.708 +	TInt iPageCount;					// Number of pages used for code
   1.709 +	TInt iDataPageCount;				// Number of extra pages used to store data section
   1.710 +	TUint8* iCodeRelocTable;			// Code relocation information
   1.711 +	TInt iCodeRelocTableSize;			// Size of code relocation table in bytes
   1.712 +	TUint8* iImportFixupTable;			// Import fixup information
   1.713 +	TInt iImportFixupTableSize;			// Size of import fixup table in bytes
   1.714 +	TUint32 iCodeDelta;					// Code relocation delta
   1.715 +	TUint32 iDataDelta;					// Data relocation delta
   1.716 +
   1.717 +	TInt iCompressionType;				// Compression scheme in use
   1.718 +	TInt32* iCodePageOffsets;			// Array of compressed page offsets within the file
   1.719 +	TInt iCodeLocalDrive;				// Local drive number
   1.720 +	TBlockMap iBlockMap;				// Kernel-side representation of block map
   1.721 +	TInt iCodeStartInFile;				// Offset of (possibly compressed) code from start of file
   1.722 +
   1.723 +	TAny* iDataSectionMemory;			// pointer to saved copy of data section (when demand paging)
   1.724 +
   1.725 +	TInt iCodeAllocBase;
   1.726 +	};
   1.727 +
   1.728 +#endif