os/kernelhwsrv/kernel/eka/include/memmodel/epoc/moving/memmodel.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32\include\memmodel\epoc\moving\memmodel.h
    15 // 
    16 // WARNING: This file contains some APIs which are internal and are subject
    17 //          to change without notice. Such APIs should therefore not be used
    18 //          outside the Kernel and Hardware Services package.
    19 //
    20 
    21 #ifndef __MEMMODEL_H__
    22 #define __MEMMODEL_H__
    23 #include <memmodel/epoc/mmubase/mmubase.h>
    24 
    25 /********************************************
    26  * Deterministic Scheduler Implementation
    27  ********************************************/
    28 
    29 /**
    30 @internalComponent
    31 */
    32 #define TheCurrentAddressSpace			((DMemModelProcess*&)TheScheduler.iAddressSpace)
    33 
    34 /**
    35 @internalComponent
    36 */
    37 #define TheCurrentVMProcess				((DMemModelProcess*&)TheScheduler.iExtras[0])
    38 
    39 /**
    40 @internalComponent
    41 */
    42 #define TheCurrentDataSectionProcess	((DMemModelProcess*&)TheScheduler.iExtras[1])
    43 
    44 /**
    45 @internalComponent
    46 */
    47 #define TheCompleteDataSectionProcess	((DMemModelProcess*&)TheScheduler.iExtras[2])
    48 
    49 /**
    50 @internalComponent
    51 */
    52 #define FlushProgress					((TInt&)TheScheduler.iExtras[3])
    53 
    54 
    55 /********************************************
    56  * Process Control Block
    57  ********************************************/
    58 /**
    59 @internalComponent
    60 */
    61 const TInt KMaxChunksInProcess=16;
    62 
    63 class DMemModelChunk;
    64 /**
    65 @internalComponent
    66 */
    67 class DMemModelProcess : public DEpocProcess
    68 	{
    69 public:
    70 	void Destruct();
    71 public:
    72 	virtual TInt DoCreate(TBool aKernelProcess, TProcessCreateInfo& aInfo);
    73 	virtual TInt NewChunk(DChunk*& aChunk, SChunkCreateInfo& anInfo, TLinAddr& aRunAddr);
    74 	virtual TInt AddChunk(DChunk* aChunk,TBool isReadOnly);
    75 	virtual TInt NewShPool(DShPool*& aPool, TShPoolCreateInfo& aInfo);
    76 	virtual TInt CreateDataBssStackArea(TProcessCreateInfo& aInfo);
    77 	virtual TInt MapCodeSeg(DCodeSeg* aCodeSeg);
    78 	virtual void UnmapCodeSeg(DCodeSeg* aCodeSeg);
    79 	virtual void RemoveDllData();
    80 	virtual void FinalRelease();
    81 public:
    82 	virtual TInt GetNewChunk(DMemModelChunk*& aChunk, SChunkCreateInfo& anInfo)=0;
    83 	virtual TInt AddFixedAccessChunk(DMemModelChunk *aChunk)=0;
    84 	virtual TInt RemoveFixedAccessChunk(DMemModelChunk *aChunk)=0;
    85 	virtual void CheckForFixedAccess()=0;
    86 	virtual void DoAttributeChange()=0;
    87 public:
    88 	TInt AddChunk(DMemModelChunk* aChunk, TLinAddr& aDataSectionBase, TBool isReadOnly);
    89 	TInt AllocateDataSectionBase(DMemModelChunk& aChunk, TUint& aBase);
    90 	TUint8* DataSectionBase(DMemModelChunk* aChunk);
    91 	void RemoveChunk(DMemModelChunk *aChunk);
    92 	void DoRemoveChunk(TInt aIndex);
    93 	TInt ChunkIndex(DMemModelChunk* aChunk,TInt& aPos);
    94 	TInt CreateDllDataChunk();
    95 	void FreeDllDataChunk();
    96 	TInt CommitDllData(TLinAddr aBase, TInt aSize);
    97 	void DecommitDllData(TLinAddr aBase, TInt aSize);
    98 public:
    99 	enum TMemModelProcessAttributes
   100 		{
   101 		EFixedAddress=1,
   102 		EMoving=0x40000000,
   103 		EVariableAccess=0x20000000,
   104 //		EMovingCode=0x10000000,		NEVER USED
   105 		EVariableCode=0x04000000,
   106 		EMMProcessAttributesMask = EFixedAddress|EMoving|EVariableAccess|EVariableCode,
   107 		};
   108 
   109 	struct SChunkInfo
   110 		{
   111 		TLinAddr iDataSectionBase;
   112 		DMemModelChunk *iChunk;
   113 		TInt16 iAccessCount;
   114 		TInt16 isReadOnly;
   115 		};
   116 
   117 	TInt iNumChunks;
   118 	SChunkInfo iChunks[KMaxChunksInProcess];
   119 	TInt iNumMovingChunks;
   120 	TInt iNumNonFixedAccessChunks;
   121 	TInt iNumNonFixedAccessCodeChunks;
   122 	DMemModelChunk* iDllDataChunk;
   123 public:
   124 	friend class Monitor;
   125 	};
   126 
   127 
   128 /********************************************
   129  * Chunk Control Block
   130  ********************************************/
   131 /**
   132 @internalComponent
   133 */
   134 class DMemModelChunk : public DChunk
   135 	{
   136 public:
   137 	/**
   138 	@see DChunk::TChunkAttributes for generic attribute flags
   139 	*/
   140 	enum TMemModelChunkAttributes
   141 		{
   142 		EFixedAccess	=0x80000000,
   143 		EFixedAddress	=0x40000000,
   144 		EPrivate		=0x10000000,
   145 		ECode			=0x08000000,
   146 
   147 		EMMChunkAttributesMask = EFixedAccess | EFixedAddress | EPrivate | ECode,
   148 		};
   149 
   150 	enum TChunkState {ENotRunning=0, ERunningRO=1, ERunningRW=2};
   151 public:
   152 	DMemModelChunk();
   153 	void Destruct();
   154 public:
   155 	virtual TInt Close(TAny* aPtr);
   156 	virtual TInt DoCreate(SChunkCreateInfo& anInfo);
   157 	virtual TInt Adjust(TInt aNewSize);
   158 	virtual TInt AdjustDoubleEnded(TInt aBottom, TInt aTop);
   159 	virtual TInt CheckAccess();
   160 	virtual TInt Commit(TInt anOffset, TInt aSize, TCommitType aCommitType=DChunk::ECommitDiscontiguous, TUint32* aExtraArg=0);
   161 	virtual TInt Allocate(TInt aSize, TInt aGuard=0, TInt aAlign=0);
   162 	TInt Decommit(TInt anOffset, TInt aSize);
   163 	virtual TInt Lock(TInt anOffset, TInt aSize);
   164 	virtual TInt Unlock(TInt anOffset, TInt aSize);
   165 	virtual TInt Address(TInt aOffset, TInt aSize, TLinAddr& aKernelAddress);
   166 	virtual TInt PhysicalAddress(TInt aOffset, TInt aSize, TLinAddr& aKernelAddress, TUint32& aPhysicalAddress, TUint32* aPhysicalPageList=NULL);
   167 	virtual void BTracePrime(TInt aCategory);
   168 	virtual void Substitute(TInt aOffset, TPhysAddr aOldAddr, TPhysAddr aNewAddr);
   169 	virtual TUint8* Base(DProcess* aProcess);
   170 	inline TUint8* Base() const { return DChunk::Base(); }
   171 public:
   172 	TInt Decommit(TInt aOffset, TInt aSize, TDecommitType aDecommitType);
   173 	TInt FindFree(TInt aSize, TInt aGuard, TInt aAlign);
   174 	void SetFixedAddress(TLinAddr anAddr, TInt anInitialSize);
   175 	TInt Reserve(TInt anInitialSize);
   176 	TUint32 ApplyTopLevelPermissions(TChunkState aChunkState);
   177 	TUint32 MoveToRunAddress(TLinAddr aLinearAddr,TChunkState aChunkState);
   178 	TUint32 MoveToHomeSection();
   179 	TZonePageType GetPageType();
   180 protected:
   181 	TInt DoCommit(TInt aOffset, TInt aSize, TCommitType aCommitType=DChunk::ECommitDiscontiguous, TUint32* aExtraArg=0);
   182 	void DoDecommit(TInt aOffset, TInt aSize, TDecommitType aDecommitType=EDecommitNormal);
   183 private:
   184 	void ClaimInitialPages();
   185 	TInt ExpandHomeRegion(TInt anOffset, TInt aSize);
   186 	TLinAddr AllocateHomeAddress(TInt aSize);
   187 	void DeallocateHomeAddress();
   188 	TLinAddr ReallocateHomeAddress(TInt aNewSize);
   189 	TInt DoAllocate(TInt aSize, TInt aGuard, TInt aAlign, TBool aCommit);
   190 private:
   191 	virtual TInt SetupPermissions()=0;
   192 	virtual void AddPde(TInt anOffset)=0;
   193 	virtual void RemovePde(TInt anOffset)=0;
   194 	virtual void MoveHomePdes(TLinAddr anOldAddr, TLinAddr aNewAddr)=0;
   195 	virtual void MoveCurrentPdes(TLinAddr anOldAddr, TLinAddr aNewAddr)=0;
   196 public:
   197 	TChunkState iChunkState;
   198 	TPte iPtePermissions;
   199 	TPde iPdePermissions[3];	// indexed by iChunkState
   200 	TInt iHomeRegionOffset;
   201 	TInt iHomeRegionSize;
   202 	TLinAddr iHomeRegionBase;
   203 	TLinAddr iHomeBase;
   204 	TInt iNumPdes;
   205 	TPde* iPdes;
   206 	TPde* iHomePdes;
   207 	TUint32* iPdeBitMap;
   208 	TBitMapAllocator* iPageBitMap;
   209 	TBitMapAllocator* iPermanentPageBitMap;
   210 public:
   211 	friend class Monitor;
   212 	};
   213 
   214 
   215 /********************************************
   216  * Code segment
   217  ********************************************/
   218 
   219 class DMemModelCodeSegMemory : public DMmuCodeSegMemory
   220 	{
   221 public:
   222 	DMemModelCodeSegMemory(DEpocCodeSeg* aCodeSeg);
   223 	~DMemModelCodeSegMemory();
   224 	TInt Create(TCodeSegCreateInfo& aInfo);
   225 	TInt Loaded(TCodeSegCreateInfo& aInfo);
   226 	void Destroy();
   227 	};
   228 
   229 /**
   230 @internalComponent
   231 */
   232 class DMemModelCodeSeg: public DEpocCodeSeg
   233 	{
   234 public:
   235 	DMemModelCodeSeg();
   236 	virtual ~DMemModelCodeSeg();
   237 	virtual TInt DoCreateRam(TCodeSegCreateInfo& aInfo, DProcess* aProcess);
   238 	virtual TInt DoCreateXIP(DProcess* aProcess);
   239 	virtual TInt Loaded(TCodeSegCreateInfo& aInfo);
   240 	virtual void ReadExportDir(TUint32* aDest);
   241 	virtual TBool FindCheck(DProcess* aProcess);
   242 	virtual TBool OpenCheck(DProcess* aProcess);
   243 	inline DMemModelCodeSegMemory* Memory()
   244 		{ return (DMemModelCodeSegMemory*)iMemory; }
   245 public:
   246 	TInt iCodeAllocBase;
   247 	TInt iDataAllocBase;
   248 	TAny* iKernelData;			// only for kernel modules
   249 	};
   250 
   251 
   252 /********************************************
   253  * MMU stuff
   254  ********************************************/
   255 
   256 typedef void (*TCopyPageFn)(TLinAddr aDest, TLinAddr aSrc);
   257 
   258 /**
   259 @internalComponent
   260 */
   261 class Mmu : public MmuBase
   262 	{
   263 public:
   264 	enum TFlushFlags	{
   265 						EFlushDTLB=0x01,
   266 						EFlushDCache=0x02,
   267 						EFlushITLB=0x04,
   268 						EFlushICache=0x08,
   269 						EFlushDDecommit=0x80000000,
   270 						EFlushDPermChg=0x20000000,		// =DProcess::EVariableAccess
   271 						EFlushDMove=0x40000000,			// =DProcess::EMoving
   272 						EFlushIPermChg=0x04000000,		// =DProcess::EVariableCode
   273 						EFlushIMove=0x10000000,			// =DProcess::EMovingCode
   274 						EFlushInheritMask=EFlushDPermChg|EFlushDMove|EFlushIPermChg|EFlushIMove,
   275 						};
   276 
   277 	enum TPanic
   278 		{
   279 		EBadInitialPageAddr,
   280 		EAssignPageTableInvalidUsage,
   281 		EUserCodeAllocatorCreateFailed,
   282 		EDllDataAllocatorCreateFailed,
   283 		ERomUserDataAddressInvalid,
   284 		ERomUserDataSizeInvalid,
   285 		ERomLinearAddressInvalid,
   286 		ERemapPageFailed,
   287 		ERemapPageTableFailed,
   288 		ENoCopyPageFunction,
   289 		EFixupXPTFailed,
   290 		ECacheMaintenance,
   291 		EDefragDisablePageFailed,
   292 		EDefragFaultWhilstFMHeld,
   293 		EDefragKernelChunkNoPageTable,
   294 		};
   295 
   296 public:
   297 	inline TPde& PDE(TLinAddr aAddr)
   298 		{return *(((TPde*)iPdeBase)+(aAddr>>iChunkShift));}
   299 
   300 	// virtual - inherited/overridden from MmuBase
   301 	virtual void Init1();
   302 //	virtual void Init2();
   303 	virtual void DoInit2();
   304 //	virtual TBool PteIsPresent(TPte aPte)=0;
   305 //	virtual TPhysAddr PtePhysAddr(TPte aPte, TInt aPteIndex)=0;
   306 //	virtual TPhysAddr PdePhysAddr(TLinAddr aAddr)=0;
   307 	virtual void SetupInitialPageInfo(SPageInfo* aPageInfo, TLinAddr aChunkAddr, TInt aPdeIndex);
   308 	virtual void SetupInitialPageTableInfo(TInt aId, TLinAddr aChunkAddr, TInt aNumPtes);
   309 	virtual void AssignPageTable(TInt aId, TInt aUsage, TAny* aObject, TLinAddr aAddr, TPde aPdePerm);
   310 	virtual TInt UnassignPageTable(TLinAddr aAddr);
   311 //	virtual void BootstrapPageTable(TInt aXptId, TPhysAddr aXptPhys, TInt aId, TPhysAddr aPhysAddr)=0;
   312 	virtual TInt PageTableId(TLinAddr aAddr);
   313 //	virtual TInt BootPageTableId(TLinAddr aAddr, TPhysAddr& aPtPhys)=0;
   314 //	virtual void ClearPageTable(TInt aId, TInt aFirstIndex=0)=0;
   315 //	virtual TPhysAddr LinearToPhysical(TLinAddr aAddr)=0;
   316 //	virtual TInt LinearToPhysical(TLinAddr aAddr, TInt aSize, TPhysAddr& aPhysicalAddress, TPhysAddr* aPhysicalPageList=NULL)=0;
   317 //	virtual void MapRamPages(TInt aId, SPageInfo::TType aType, TAny* aPtr, TUint32 aOffset, const TPhysAddr* aPageList, TInt aNumPages, TPte aPtePerm)=0;
   318 //	virtual void MapPhysicalPages(TInt aId, SPageInfo::TType aType, TAny* aPtr, TUint32 aOffset, TPhysAddr aPhysAddr, TInt aNumPages, TPte aPtePerm)=0;
   319 //	virtual TInt UnmapPages(TInt aId, TUint32 aAddr, TInt aNumPages, TPhysAddr* aPageList, TBool aSetPagesFree, TInt& aNumPtes, TInt& aNumFree, DProcess* aProcess)=0;
   320 //	virtual void ClearRamDrive(TLinAddr aStart)=0;
   321 //	virtual TInt PdePtePermissions(TUint& aMapAttr, TPde& aPde, TPte& aPte)=0;
   322 //	virtual void Map(TLinAddr aLinAddr, TPhysAddr aPhysAddr, TInt aSize, TPde aPdePerm, TPte aPtePerm, TInt aMapShift)=0;
   323 //	virtual void Unmap(TLinAddr aLinAddr, TInt aSize)=0;
   324 //	virtual void InitShadowPageTable(TInt aId, TLinAddr aRomAddr, TPhysAddr aOrigPhys)=0;
   325 //	virtual void InitShadowPage(TPhysAddr aShadowPhys, TLinAddr aRomAddr)=0;
   326 //	virtual void DoUnmapShadowPage(TInt aId, TLinAddr aRomAddr, TPhysAddr aOrigPhys)=0;
   327 //	virtual TInt UnassignShadowPageTable(TLinAddr aRomAddr, TPhysAddr aOrigPhys)=0;
   328 //	virtual void DoFreezeShadowPage(TInt aId, TLinAddr aRomAddr)=0;
   329 //	virtual void FlushShadow(TLinAddr aRomAddr)=0;
   330 //	virtual void AssignShadowPageTable(TInt aId, TLinAddr aRomAddr)=0;
   331 //	virtual void ClearPages(TInt aNumPages, TPhysAddr* aPageList)=0;
   332 	virtual TPte PtePermissions(TChunkType aChunkType)=0;
   333 	virtual TInt MoveKernelPage(DChunk* aChunk, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest);
   334 	virtual TInt MoveCodeSegMemoryPage(DMemModelCodeSegMemory* aCodeSegMemory, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest);
   335 	virtual TInt MoveCodeChunkPage(DChunk* aChunk, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest);
   336 	virtual TInt MoveDataChunkPage(DChunk* aChunk, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest);
   337 
   338 	// pure virtual - new in Mmu
   339 	virtual void DoAssignPageTable(TInt aId, TLinAddr aAddr, TPde aPdePerm)=0;
   340 	virtual void RemapPageTable(TPhysAddr aOld, TPhysAddr aNewId, TLinAddr aAddr)=0;
   341 	virtual void DoUnassignPageTable(TLinAddr aAddr)=0;
   342 	virtual void MoveChunk(TLinAddr anInitAddr, TUint aSize, TLinAddr aFinalAddr, TPde aPermissions)=0;
   343 	virtual void MoveChunk(TLinAddr anInitAddr, TLinAddr aFinalAddr, TInt aNumPdes)=0;
   344 	virtual void ApplyTopLevelPermissions(TLinAddr anAddr, TUint aChunkSize, TPde aPermissions)=0;
   345 	virtual void ApplyPagePermissions(TInt aId, TInt aPageOffset, TInt aNumPages, TPte aPtePerm)=0;
   346 	virtual void SyncCodeMappings()=0;
   347 	virtual void GenericFlush(TUint32 aMask)=0;
   348 	virtual TPde PdePermissions(TChunkType aChunkType, TInt aChunkState)=0;
   349 	virtual TInt UnlockRamCachePages(TUint8* volatile & aBase, TInt aFirstPage, TInt aNumPages)=0;
   350 	virtual TInt LockRamCachePages(TUint8* volatile & aBase, TInt aFirstPage, TInt aNumPages)=0;
   351 	virtual void MapVirtual(TInt aId, TInt aNumPages)=0;
   352 	virtual TInt UnmapVirtual(TInt aId, TUint32 aAddr, TInt aNumPages, TPhysAddr* aPageList, TBool aSetPagesFree, TInt& aNumPtes, TInt& aNumFree, DProcess* aProcess)=0;
   353 	virtual TLinAddr MapTemp(TPhysAddr aPage, TBool aCached)=0;
   354 	virtual TLinAddr MapSecondTemp(TPhysAddr aPage, TBool aCached)=0;
   355 	virtual void UnmapTemp()=0;
   356 	virtual void UnmapSecondTemp()=0;
   357 	virtual void RemapKernelPage(TInt aId, TLinAddr aSrc, TLinAddr aDest, TPhysAddr aNewPhys, TPte aPtePerm)=0;
   358 	virtual TInt PreparePagesForDMA(TLinAddr aAddr, TInt aSize, TPhysAddr* aPhysicalPageList)=0;
   359 	virtual TInt ReleasePagesFromDMA(TPhysAddr* aPhysicalPageList, TInt aPageCount)=0;
   360 	
   361 public:
   362 	TInt GetPageTableId(TLinAddr aAddr);
   363 public:
   364 	inline static Mmu& Get()
   365 		{return *(Mmu*)TheMmu;}
   366 	inline void CopyPageForRemap(TLinAddr aDest, TLinAddr aSrc)
   367 		{iCopyPageFn(aDest, aSrc);}
   368 	static void Panic(TPanic aPanic);
   369 public:
   370 	TLinAddr iDataSectionBase;		// lowest data section address
   371 	TLinAddr iDllDataBase;			// start of DLL static data area
   372 	TLinAddr iDataSectionEnd;		// highest data section address + 1
   373 	TInt iMaxDllDataSize;
   374 	TLinAddr iUserCodeBase;
   375 	TInt iMaxUserCodeSize;
   376 	TLinAddr iKernelCodeBase;
   377 	TInt iMaxKernelCodeSize;
   378 	TLinAddr iPdeBase;
   379 	TPte iUserCodeLoadPtePerm;
   380 	TPte iKernelCodePtePerm;
   381 	TUint32* iHomePdeMap;
   382 	TCopyPageFn iCopyPageFn;
   383 	TPte* iSecondTempPte;		// second PTE used for temporary mappings
   384 	TLinAddr iSecondTempAddr;	// address corresponding to iSecondTempPte
   385 	};
   386 
   387 
   388 /********************************************
   389  * Functions/Data defined in memory model
   390  ********************************************/
   391 
   392 /**
   393 @internalComponent
   394 */
   395 class MM
   396 	{
   397 public:
   398 	enum TMemModelPanic
   399 		{
   400 		EUserCodeNotFixed=0,
   401 		EClaimInitialPagesBadPageTable=1,
   402 		EFreeInvalidDomain=2,
   403 		EFreeDomainNotAllocated=3,
   404 		EFixedChunkMoving=4,
   405 		EChunkDecommitNoPageTable=5,
   406 		ECommitInvalidDllDataAddress=6,
   407 		EDecommitInvalidDllDataAddress=7,
   408 		EPdeAlreadyInUse=8,
   409 		EPteAlreadyInUse=9,
   410 		EMmuMapNoPageTable=10,
   411 		EUnmapBadAlignment=11,
   412 		EBootstrapPageTableBadAddr=12,
   413 		EAddFixedBadPerm=13,
   414 		ERemoveFixedBadPerm=14,
   415 		EUnexpectedPageType=15,
   416 		EOperationNotImplemented=16,
   417 		ECodeAddressOutOfRange=17,
   418 		ETempMappingAlreadyInUse=18,
   419 		EChunkRemapNoPageTable=19,
   420 		EChunkRemapWrongPageTable=20,
   421 		};
   422 
   423 	static void Panic(TMemModelPanic aPanic);
   424 public:
   425 	static void Init1();
   426 	static TAny* CurrentAddress(DThread* aThread, const TAny* aAddress, TInt aSize, TBool aWrite);
   427 	static void StartCrashDebugger();
   428 	static TInt CreateCodeChunk(TBool aKernel);
   429 public:
   430 	static TInt MaxPagesInOneGo;
   431 	static DMemModelChunk* SvStackChunk;
   432 	static DMemModelChunk* TheRamDriveChunk;
   433 	static DMemModelChunk* UserCodeChunk;
   434 	static DMemModelChunk* KernelCodeChunk;
   435 	static TBitMapAllocator* DllDataAllocator;
   436 	};
   437 
   438 #endif