kernel/eka/include/memmodel/epoc/moving/memmodel.h
changeset 0 a41df078684a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/include/memmodel/epoc/moving/memmodel.h	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,438 @@
+// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32\include\memmodel\epoc\moving\memmodel.h
+// 
+// WARNING: This file contains some APIs which are internal and are subject
+//          to change without notice. Such APIs should therefore not be used
+//          outside the Kernel and Hardware Services package.
+//
+
+#ifndef __MEMMODEL_H__
+#define __MEMMODEL_H__
+#include <memmodel/epoc/mmubase/mmubase.h>
+
+/********************************************
+ * Deterministic Scheduler Implementation
+ ********************************************/
+
+/**
+@internalComponent
+*/
+#define TheCurrentAddressSpace			((DMemModelProcess*&)TheScheduler.iAddressSpace)
+
+/**
+@internalComponent
+*/
+#define TheCurrentVMProcess				((DMemModelProcess*&)TheScheduler.iExtras[0])
+
+/**
+@internalComponent
+*/
+#define TheCurrentDataSectionProcess	((DMemModelProcess*&)TheScheduler.iExtras[1])
+
+/**
+@internalComponent
+*/
+#define TheCompleteDataSectionProcess	((DMemModelProcess*&)TheScheduler.iExtras[2])
+
+/**
+@internalComponent
+*/
+#define FlushProgress					((TInt&)TheScheduler.iExtras[3])
+
+
+/********************************************
+ * Process Control Block
+ ********************************************/
+/**
+@internalComponent
+*/
+const TInt KMaxChunksInProcess=16;
+
+class DMemModelChunk;
+/**
+@internalComponent
+*/
+class DMemModelProcess : public DEpocProcess
+	{
+public:
+	void Destruct();
+public:
+	virtual TInt DoCreate(TBool aKernelProcess, TProcessCreateInfo& aInfo);
+	virtual TInt NewChunk(DChunk*& aChunk, SChunkCreateInfo& anInfo, TLinAddr& aRunAddr);
+	virtual TInt AddChunk(DChunk* aChunk,TBool isReadOnly);
+	virtual TInt NewShPool(DShPool*& aPool, TShPoolCreateInfo& aInfo);
+	virtual TInt CreateDataBssStackArea(TProcessCreateInfo& aInfo);
+	virtual TInt MapCodeSeg(DCodeSeg* aCodeSeg);
+	virtual void UnmapCodeSeg(DCodeSeg* aCodeSeg);
+	virtual void RemoveDllData();
+	virtual void FinalRelease();
+public:
+	virtual TInt GetNewChunk(DMemModelChunk*& aChunk, SChunkCreateInfo& anInfo)=0;
+	virtual TInt AddFixedAccessChunk(DMemModelChunk *aChunk)=0;
+	virtual TInt RemoveFixedAccessChunk(DMemModelChunk *aChunk)=0;
+	virtual void CheckForFixedAccess()=0;
+	virtual void DoAttributeChange()=0;
+public:
+	TInt AddChunk(DMemModelChunk* aChunk, TLinAddr& aDataSectionBase, TBool isReadOnly);
+	TInt AllocateDataSectionBase(DMemModelChunk& aChunk, TUint& aBase);
+	TUint8* DataSectionBase(DMemModelChunk* aChunk);
+	void RemoveChunk(DMemModelChunk *aChunk);
+	void DoRemoveChunk(TInt aIndex);
+	TInt ChunkIndex(DMemModelChunk* aChunk,TInt& aPos);
+	TInt CreateDllDataChunk();
+	void FreeDllDataChunk();
+	TInt CommitDllData(TLinAddr aBase, TInt aSize);
+	void DecommitDllData(TLinAddr aBase, TInt aSize);
+public:
+	enum TMemModelProcessAttributes
+		{
+		EFixedAddress=1,
+		EMoving=0x40000000,
+		EVariableAccess=0x20000000,
+//		EMovingCode=0x10000000,		NEVER USED
+		EVariableCode=0x04000000,
+		EMMProcessAttributesMask = EFixedAddress|EMoving|EVariableAccess|EVariableCode,
+		};
+
+	struct SChunkInfo
+		{
+		TLinAddr iDataSectionBase;
+		DMemModelChunk *iChunk;
+		TInt16 iAccessCount;
+		TInt16 isReadOnly;
+		};
+
+	TInt iNumChunks;
+	SChunkInfo iChunks[KMaxChunksInProcess];
+	TInt iNumMovingChunks;
+	TInt iNumNonFixedAccessChunks;
+	TInt iNumNonFixedAccessCodeChunks;
+	DMemModelChunk* iDllDataChunk;
+public:
+	friend class Monitor;
+	};
+
+
+/********************************************
+ * Chunk Control Block
+ ********************************************/
+/**
+@internalComponent
+*/
+class DMemModelChunk : public DChunk
+	{
+public:
+	/**
+	@see DChunk::TChunkAttributes for generic attribute flags
+	*/
+	enum TMemModelChunkAttributes
+		{
+		EFixedAccess	=0x80000000,
+		EFixedAddress	=0x40000000,
+		EPrivate		=0x10000000,
+		ECode			=0x08000000,
+
+		EMMChunkAttributesMask = EFixedAccess | EFixedAddress | EPrivate | ECode,
+		};
+
+	enum TChunkState {ENotRunning=0, ERunningRO=1, ERunningRW=2};
+public:
+	DMemModelChunk();
+	void Destruct();
+public:
+	virtual TInt Close(TAny* aPtr);
+	virtual TInt DoCreate(SChunkCreateInfo& anInfo);
+	virtual TInt Adjust(TInt aNewSize);
+	virtual TInt AdjustDoubleEnded(TInt aBottom, TInt aTop);
+	virtual TInt CheckAccess();
+	virtual TInt Commit(TInt anOffset, TInt aSize, TCommitType aCommitType=DChunk::ECommitDiscontiguous, TUint32* aExtraArg=0);
+	virtual TInt Allocate(TInt aSize, TInt aGuard=0, TInt aAlign=0);
+	TInt Decommit(TInt anOffset, TInt aSize);
+	virtual TInt Lock(TInt anOffset, TInt aSize);
+	virtual TInt Unlock(TInt anOffset, TInt aSize);
+	virtual TInt Address(TInt aOffset, TInt aSize, TLinAddr& aKernelAddress);
+	virtual TInt PhysicalAddress(TInt aOffset, TInt aSize, TLinAddr& aKernelAddress, TUint32& aPhysicalAddress, TUint32* aPhysicalPageList=NULL);
+	virtual void BTracePrime(TInt aCategory);
+	virtual void Substitute(TInt aOffset, TPhysAddr aOldAddr, TPhysAddr aNewAddr);
+	virtual TUint8* Base(DProcess* aProcess);
+	inline TUint8* Base() const { return DChunk::Base(); }
+public:
+	TInt Decommit(TInt aOffset, TInt aSize, TDecommitType aDecommitType);
+	TInt FindFree(TInt aSize, TInt aGuard, TInt aAlign);
+	void SetFixedAddress(TLinAddr anAddr, TInt anInitialSize);
+	TInt Reserve(TInt anInitialSize);
+	TUint32 ApplyTopLevelPermissions(TChunkState aChunkState);
+	TUint32 MoveToRunAddress(TLinAddr aLinearAddr,TChunkState aChunkState);
+	TUint32 MoveToHomeSection();
+	TZonePageType GetPageType();
+protected:
+	TInt DoCommit(TInt aOffset, TInt aSize, TCommitType aCommitType=DChunk::ECommitDiscontiguous, TUint32* aExtraArg=0);
+	void DoDecommit(TInt aOffset, TInt aSize, TDecommitType aDecommitType=EDecommitNormal);
+private:
+	void ClaimInitialPages();
+	TInt ExpandHomeRegion(TInt anOffset, TInt aSize);
+	TLinAddr AllocateHomeAddress(TInt aSize);
+	void DeallocateHomeAddress();
+	TLinAddr ReallocateHomeAddress(TInt aNewSize);
+	TInt DoAllocate(TInt aSize, TInt aGuard, TInt aAlign, TBool aCommit);
+private:
+	virtual TInt SetupPermissions()=0;
+	virtual void AddPde(TInt anOffset)=0;
+	virtual void RemovePde(TInt anOffset)=0;
+	virtual void MoveHomePdes(TLinAddr anOldAddr, TLinAddr aNewAddr)=0;
+	virtual void MoveCurrentPdes(TLinAddr anOldAddr, TLinAddr aNewAddr)=0;
+public:
+	TChunkState iChunkState;
+	TPte iPtePermissions;
+	TPde iPdePermissions[3];	// indexed by iChunkState
+	TInt iHomeRegionOffset;
+	TInt iHomeRegionSize;
+	TLinAddr iHomeRegionBase;
+	TLinAddr iHomeBase;
+	TInt iNumPdes;
+	TPde* iPdes;
+	TPde* iHomePdes;
+	TUint32* iPdeBitMap;
+	TBitMapAllocator* iPageBitMap;
+	TBitMapAllocator* iPermanentPageBitMap;
+public:
+	friend class Monitor;
+	};
+
+
+/********************************************
+ * Code segment
+ ********************************************/
+
+class DMemModelCodeSegMemory : public DMmuCodeSegMemory
+	{
+public:
+	DMemModelCodeSegMemory(DEpocCodeSeg* aCodeSeg);
+	~DMemModelCodeSegMemory();
+	TInt Create(TCodeSegCreateInfo& aInfo);
+	TInt Loaded(TCodeSegCreateInfo& aInfo);
+	void Destroy();
+	};
+
+/**
+@internalComponent
+*/
+class DMemModelCodeSeg: public DEpocCodeSeg
+	{
+public:
+	DMemModelCodeSeg();
+	virtual ~DMemModelCodeSeg();
+	virtual TInt DoCreateRam(TCodeSegCreateInfo& aInfo, DProcess* aProcess);
+	virtual TInt DoCreateXIP(DProcess* aProcess);
+	virtual TInt Loaded(TCodeSegCreateInfo& aInfo);
+	virtual void ReadExportDir(TUint32* aDest);
+	virtual TBool FindCheck(DProcess* aProcess);
+	virtual TBool OpenCheck(DProcess* aProcess);
+	inline DMemModelCodeSegMemory* Memory()
+		{ return (DMemModelCodeSegMemory*)iMemory; }
+public:
+	TInt iCodeAllocBase;
+	TInt iDataAllocBase;
+	TAny* iKernelData;			// only for kernel modules
+	};
+
+
+/********************************************
+ * MMU stuff
+ ********************************************/
+
+typedef void (*TCopyPageFn)(TLinAddr aDest, TLinAddr aSrc);
+
+/**
+@internalComponent
+*/
+class Mmu : public MmuBase
+	{
+public:
+	enum TFlushFlags	{
+						EFlushDTLB=0x01,
+						EFlushDCache=0x02,
+						EFlushITLB=0x04,
+						EFlushICache=0x08,
+						EFlushDDecommit=0x80000000,
+						EFlushDPermChg=0x20000000,		// =DProcess::EVariableAccess
+						EFlushDMove=0x40000000,			// =DProcess::EMoving
+						EFlushIPermChg=0x04000000,		// =DProcess::EVariableCode
+						EFlushIMove=0x10000000,			// =DProcess::EMovingCode
+						EFlushInheritMask=EFlushDPermChg|EFlushDMove|EFlushIPermChg|EFlushIMove,
+						};
+
+	enum TPanic
+		{
+		EBadInitialPageAddr,
+		EAssignPageTableInvalidUsage,
+		EUserCodeAllocatorCreateFailed,
+		EDllDataAllocatorCreateFailed,
+		ERomUserDataAddressInvalid,
+		ERomUserDataSizeInvalid,
+		ERomLinearAddressInvalid,
+		ERemapPageFailed,
+		ERemapPageTableFailed,
+		ENoCopyPageFunction,
+		EFixupXPTFailed,
+		ECacheMaintenance,
+		EDefragDisablePageFailed,
+		EDefragFaultWhilstFMHeld,
+		EDefragKernelChunkNoPageTable,
+		};
+
+public:
+	inline TPde& PDE(TLinAddr aAddr)
+		{return *(((TPde*)iPdeBase)+(aAddr>>iChunkShift));}
+
+	// virtual - inherited/overridden from MmuBase
+	virtual void Init1();
+//	virtual void Init2();
+	virtual void DoInit2();
+//	virtual TBool PteIsPresent(TPte aPte)=0;
+//	virtual TPhysAddr PtePhysAddr(TPte aPte, TInt aPteIndex)=0;
+//	virtual TPhysAddr PdePhysAddr(TLinAddr aAddr)=0;
+	virtual void SetupInitialPageInfo(SPageInfo* aPageInfo, TLinAddr aChunkAddr, TInt aPdeIndex);
+	virtual void SetupInitialPageTableInfo(TInt aId, TLinAddr aChunkAddr, TInt aNumPtes);
+	virtual void AssignPageTable(TInt aId, TInt aUsage, TAny* aObject, TLinAddr aAddr, TPde aPdePerm);
+	virtual TInt UnassignPageTable(TLinAddr aAddr);
+//	virtual void BootstrapPageTable(TInt aXptId, TPhysAddr aXptPhys, TInt aId, TPhysAddr aPhysAddr)=0;
+	virtual TInt PageTableId(TLinAddr aAddr);
+//	virtual TInt BootPageTableId(TLinAddr aAddr, TPhysAddr& aPtPhys)=0;
+//	virtual void ClearPageTable(TInt aId, TInt aFirstIndex=0)=0;
+//	virtual TPhysAddr LinearToPhysical(TLinAddr aAddr)=0;
+//	virtual TInt LinearToPhysical(TLinAddr aAddr, TInt aSize, TPhysAddr& aPhysicalAddress, TPhysAddr* aPhysicalPageList=NULL)=0;
+//	virtual void MapRamPages(TInt aId, SPageInfo::TType aType, TAny* aPtr, TUint32 aOffset, const TPhysAddr* aPageList, TInt aNumPages, TPte aPtePerm)=0;
+//	virtual void MapPhysicalPages(TInt aId, SPageInfo::TType aType, TAny* aPtr, TUint32 aOffset, TPhysAddr aPhysAddr, TInt aNumPages, TPte aPtePerm)=0;
+//	virtual TInt UnmapPages(TInt aId, TUint32 aAddr, TInt aNumPages, TPhysAddr* aPageList, TBool aSetPagesFree, TInt& aNumPtes, TInt& aNumFree, DProcess* aProcess)=0;
+//	virtual void ClearRamDrive(TLinAddr aStart)=0;
+//	virtual TInt PdePtePermissions(TUint& aMapAttr, TPde& aPde, TPte& aPte)=0;
+//	virtual void Map(TLinAddr aLinAddr, TPhysAddr aPhysAddr, TInt aSize, TPde aPdePerm, TPte aPtePerm, TInt aMapShift)=0;
+//	virtual void Unmap(TLinAddr aLinAddr, TInt aSize)=0;
+//	virtual void InitShadowPageTable(TInt aId, TLinAddr aRomAddr, TPhysAddr aOrigPhys)=0;
+//	virtual void InitShadowPage(TPhysAddr aShadowPhys, TLinAddr aRomAddr)=0;
+//	virtual void DoUnmapShadowPage(TInt aId, TLinAddr aRomAddr, TPhysAddr aOrigPhys)=0;
+//	virtual TInt UnassignShadowPageTable(TLinAddr aRomAddr, TPhysAddr aOrigPhys)=0;
+//	virtual void DoFreezeShadowPage(TInt aId, TLinAddr aRomAddr)=0;
+//	virtual void FlushShadow(TLinAddr aRomAddr)=0;
+//	virtual void AssignShadowPageTable(TInt aId, TLinAddr aRomAddr)=0;
+//	virtual void ClearPages(TInt aNumPages, TPhysAddr* aPageList)=0;
+	virtual TPte PtePermissions(TChunkType aChunkType)=0;
+	virtual TInt MoveKernelPage(DChunk* aChunk, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest);
+	virtual TInt MoveCodeSegMemoryPage(DMemModelCodeSegMemory* aCodeSegMemory, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest);
+	virtual TInt MoveCodeChunkPage(DChunk* aChunk, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest);
+	virtual TInt MoveDataChunkPage(DChunk* aChunk, TUint32 aOffset, TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest);
+
+	// pure virtual - new in Mmu
+	virtual void DoAssignPageTable(TInt aId, TLinAddr aAddr, TPde aPdePerm)=0;
+	virtual void RemapPageTable(TPhysAddr aOld, TPhysAddr aNewId, TLinAddr aAddr)=0;
+	virtual void DoUnassignPageTable(TLinAddr aAddr)=0;
+	virtual void MoveChunk(TLinAddr anInitAddr, TUint aSize, TLinAddr aFinalAddr, TPde aPermissions)=0;
+	virtual void MoveChunk(TLinAddr anInitAddr, TLinAddr aFinalAddr, TInt aNumPdes)=0;
+	virtual void ApplyTopLevelPermissions(TLinAddr anAddr, TUint aChunkSize, TPde aPermissions)=0;
+	virtual void ApplyPagePermissions(TInt aId, TInt aPageOffset, TInt aNumPages, TPte aPtePerm)=0;
+	virtual void SyncCodeMappings()=0;
+	virtual void GenericFlush(TUint32 aMask)=0;
+	virtual TPde PdePermissions(TChunkType aChunkType, TInt aChunkState)=0;
+	virtual TInt UnlockRamCachePages(TUint8* volatile & aBase, TInt aFirstPage, TInt aNumPages)=0;
+	virtual TInt LockRamCachePages(TUint8* volatile & aBase, TInt aFirstPage, TInt aNumPages)=0;
+	virtual void MapVirtual(TInt aId, TInt aNumPages)=0;
+	virtual TInt UnmapVirtual(TInt aId, TUint32 aAddr, TInt aNumPages, TPhysAddr* aPageList, TBool aSetPagesFree, TInt& aNumPtes, TInt& aNumFree, DProcess* aProcess)=0;
+	virtual TLinAddr MapTemp(TPhysAddr aPage, TBool aCached)=0;
+	virtual TLinAddr MapSecondTemp(TPhysAddr aPage, TBool aCached)=0;
+	virtual void UnmapTemp()=0;
+	virtual void UnmapSecondTemp()=0;
+	virtual void RemapKernelPage(TInt aId, TLinAddr aSrc, TLinAddr aDest, TPhysAddr aNewPhys, TPte aPtePerm)=0;
+	virtual TInt PreparePagesForDMA(TLinAddr aAddr, TInt aSize, TPhysAddr* aPhysicalPageList)=0;
+	virtual TInt ReleasePagesFromDMA(TPhysAddr* aPhysicalPageList, TInt aPageCount)=0;
+	
+public:
+	TInt GetPageTableId(TLinAddr aAddr);
+public:
+	inline static Mmu& Get()
+		{return *(Mmu*)TheMmu;}
+	inline void CopyPageForRemap(TLinAddr aDest, TLinAddr aSrc)
+		{iCopyPageFn(aDest, aSrc);}
+	static void Panic(TPanic aPanic);
+public:
+	TLinAddr iDataSectionBase;		// lowest data section address
+	TLinAddr iDllDataBase;			// start of DLL static data area
+	TLinAddr iDataSectionEnd;		// highest data section address + 1
+	TInt iMaxDllDataSize;
+	TLinAddr iUserCodeBase;
+	TInt iMaxUserCodeSize;
+	TLinAddr iKernelCodeBase;
+	TInt iMaxKernelCodeSize;
+	TLinAddr iPdeBase;
+	TPte iUserCodeLoadPtePerm;
+	TPte iKernelCodePtePerm;
+	TUint32* iHomePdeMap;
+	TCopyPageFn iCopyPageFn;
+	TPte* iSecondTempPte;		// second PTE used for temporary mappings
+	TLinAddr iSecondTempAddr;	// address corresponding to iSecondTempPte
+	};
+
+
+/********************************************
+ * Functions/Data defined in memory model
+ ********************************************/
+
+/**
+@internalComponent
+*/
+class MM
+	{
+public:
+	enum TMemModelPanic
+		{
+		EUserCodeNotFixed=0,
+		EClaimInitialPagesBadPageTable=1,
+		EFreeInvalidDomain=2,
+		EFreeDomainNotAllocated=3,
+		EFixedChunkMoving=4,
+		EChunkDecommitNoPageTable=5,
+		ECommitInvalidDllDataAddress=6,
+		EDecommitInvalidDllDataAddress=7,
+		EPdeAlreadyInUse=8,
+		EPteAlreadyInUse=9,
+		EMmuMapNoPageTable=10,
+		EUnmapBadAlignment=11,
+		EBootstrapPageTableBadAddr=12,
+		EAddFixedBadPerm=13,
+		ERemoveFixedBadPerm=14,
+		EUnexpectedPageType=15,
+		EOperationNotImplemented=16,
+		ECodeAddressOutOfRange=17,
+		ETempMappingAlreadyInUse=18,
+		EChunkRemapNoPageTable=19,
+		EChunkRemapWrongPageTable=20,
+		};
+
+	static void Panic(TMemModelPanic aPanic);
+public:
+	static void Init1();
+	static TAny* CurrentAddress(DThread* aThread, const TAny* aAddress, TInt aSize, TBool aWrite);
+	static void StartCrashDebugger();
+	static TInt CreateCodeChunk(TBool aKernel);
+public:
+	static TInt MaxPagesInOneGo;
+	static DMemModelChunk* SvStackChunk;
+	static DMemModelChunk* TheRamDriveChunk;
+	static DMemModelChunk* UserCodeChunk;
+	static DMemModelChunk* KernelCodeChunk;
+	static TBitMapAllocator* DllDataAllocator;
+	};
+
+#endif