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