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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\include\memmodel\epoc\moving\memmodel.h
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.
21 #ifndef __MEMMODEL_H__
22 #define __MEMMODEL_H__
23 #include <memmodel/epoc/mmubase/mmubase.h>
25 /********************************************
26 * Deterministic Scheduler Implementation
27 ********************************************/
32 #define TheCurrentAddressSpace ((DMemModelProcess*&)TheScheduler.iAddressSpace)
37 #define TheCurrentVMProcess ((DMemModelProcess*&)TheScheduler.iExtras[0])
42 #define TheCurrentDataSectionProcess ((DMemModelProcess*&)TheScheduler.iExtras[1])
47 #define TheCompleteDataSectionProcess ((DMemModelProcess*&)TheScheduler.iExtras[2])
52 #define FlushProgress ((TInt&)TheScheduler.iExtras[3])
55 /********************************************
56 * Process Control Block
57 ********************************************/
61 const TInt KMaxChunksInProcess=16;
67 class DMemModelProcess : public DEpocProcess
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();
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;
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);
99 enum TMemModelProcessAttributes
103 EVariableAccess=0x20000000,
104 // EMovingCode=0x10000000, NEVER USED
105 EVariableCode=0x04000000,
106 EMMProcessAttributesMask = EFixedAddress|EMoving|EVariableAccess|EVariableCode,
111 TLinAddr iDataSectionBase;
112 DMemModelChunk *iChunk;
118 SChunkInfo iChunks[KMaxChunksInProcess];
119 TInt iNumMovingChunks;
120 TInt iNumNonFixedAccessChunks;
121 TInt iNumNonFixedAccessCodeChunks;
122 DMemModelChunk* iDllDataChunk;
124 friend class Monitor;
128 /********************************************
129 * Chunk Control Block
130 ********************************************/
134 class DMemModelChunk : public DChunk
138 @see DChunk::TChunkAttributes for generic attribute flags
140 enum TMemModelChunkAttributes
142 EFixedAccess =0x80000000,
143 EFixedAddress =0x40000000,
144 EPrivate =0x10000000,
147 EMMChunkAttributesMask = EFixedAccess | EFixedAddress | EPrivate | ECode,
150 enum TChunkState {ENotRunning=0, ERunningRO=1, ERunningRW=2};
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(); }
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();
181 TInt DoCommit(TInt aOffset, TInt aSize, TCommitType aCommitType=DChunk::ECommitDiscontiguous, TUint32* aExtraArg=0);
182 void DoDecommit(TInt aOffset, TInt aSize, TDecommitType aDecommitType=EDecommitNormal);
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);
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;
197 TChunkState iChunkState;
198 TPte iPtePermissions;
199 TPde iPdePermissions[3]; // indexed by iChunkState
200 TInt iHomeRegionOffset;
201 TInt iHomeRegionSize;
202 TLinAddr iHomeRegionBase;
208 TBitMapAllocator* iPageBitMap;
209 TBitMapAllocator* iPermanentPageBitMap;
211 friend class Monitor;
215 /********************************************
217 ********************************************/
219 class DMemModelCodeSegMemory : public DMmuCodeSegMemory
222 DMemModelCodeSegMemory(DEpocCodeSeg* aCodeSeg);
223 ~DMemModelCodeSegMemory();
224 TInt Create(TCodeSegCreateInfo& aInfo);
225 TInt Loaded(TCodeSegCreateInfo& aInfo);
232 class DMemModelCodeSeg: public DEpocCodeSeg
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; }
248 TAny* iKernelData; // only for kernel modules
252 /********************************************
254 ********************************************/
256 typedef void (*TCopyPageFn)(TLinAddr aDest, TLinAddr aSrc);
261 class Mmu : public MmuBase
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,
280 EAssignPageTableInvalidUsage,
281 EUserCodeAllocatorCreateFailed,
282 EDllDataAllocatorCreateFailed,
283 ERomUserDataAddressInvalid,
284 ERomUserDataSizeInvalid,
285 ERomLinearAddressInvalid,
287 ERemapPageTableFailed,
291 EDefragDisablePageFailed,
292 EDefragFaultWhilstFMHeld,
293 EDefragKernelChunkNoPageTable,
297 inline TPde& PDE(TLinAddr aAddr)
298 {return *(((TPde*)iPdeBase)+(aAddr>>iChunkShift));}
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);
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;
362 TInt GetPageTableId(TLinAddr aAddr);
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);
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;
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
388 /********************************************
389 * Functions/Data defined in memory model
390 ********************************************/
401 EClaimInitialPagesBadPageTable=1,
402 EFreeInvalidDomain=2,
403 EFreeDomainNotAllocated=3,
405 EChunkDecommitNoPageTable=5,
406 ECommitInvalidDllDataAddress=6,
407 EDecommitInvalidDllDataAddress=7,
410 EMmuMapNoPageTable=10,
411 EUnmapBadAlignment=11,
412 EBootstrapPageTableBadAddr=12,
414 ERemoveFixedBadPerm=14,
415 EUnexpectedPageType=15,
416 EOperationNotImplemented=16,
417 ECodeAddressOutOfRange=17,
418 ETempMappingAlreadyInUse=18,
419 EChunkRemapNoPageTable=19,
420 EChunkRemapWrongPageTable=20,
423 static void Panic(TMemModelPanic aPanic);
426 static TAny* CurrentAddress(DThread* aThread, const TAny* aAddress, TInt aSize, TBool aWrite);
427 static void StartCrashDebugger();
428 static TInt CreateCodeChunk(TBool aKernel);
430 static TInt MaxPagesInOneGo;
431 static DMemModelChunk* SvStackChunk;
432 static DMemModelChunk* TheRamDriveChunk;
433 static DMemModelChunk* UserCodeChunk;
434 static DMemModelChunk* KernelCodeChunk;
435 static TBitMapAllocator* DllDataAllocator;