os/kernelhwsrv/kernel/eka/include/memmodel/epoc/flexible/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/flexible/memmodel.h
    15 // Flexible Memory Model header file
    16 
    17 /**
    18  @file
    19  @internalComponent
    20 */
    21 
    22 
    23 #ifndef __MEMMODEL_H__
    24 #define __MEMMODEL_H__
    25 
    26 #include <plat_priv.h>
    27 #include <memmodel/epoc/mmubase/kblockmap.h>
    28 #include <mmtypes.h>
    29 #include <mmboot.h>
    30 
    31 #ifdef __SMP__
    32 // SubScheduler fields for each processor
    33 #define	i_AliasLinAddr			iExtras[0]
    34 #define	i_AliasPdePtr			iExtras[1]
    35 #endif
    36 
    37 /********************************************
    38  * Deterministic Scheduler Implementation
    39  ********************************************/
    40 
    41 /**
    42 @internalComponent
    43 */
    44 #define TheCurrentAddressSpace			((DMemModelProcess*&)TheScheduler.iAddressSpace)
    45 
    46 class DMemoryObject;
    47 class DMemoryMapping;
    48 
    49 /********************************************
    50  * Thread Control Block
    51  ********************************************/
    52 
    53 class DMemModelProcess;
    54 
    55 /**
    56 @internalComponent
    57 */
    58 class DMemModelThread : public DThread
    59 	{
    60 public:
    61 	TInt Alias(TLinAddr aAddr, DMemModelProcess* aProcess, TInt aSize, TLinAddr& aAliasAddr, TUint& aAliasSize);
    62 	void RemoveAlias();
    63 	void RefreshAlias();
    64 	virtual void DoExit1();
    65 	static void RestoreAddressSpace();
    66  	virtual void BTracePrime(TInt aCategory);
    67 protected:
    68 	virtual void SetPaging(TUint& aCreateFlags);
    69 private:
    70 	void DoRemoveAlias(TLinAddr aAddr);
    71 public:
    72 	TLinAddr iAliasLinAddr;	// linear address to access aliased memory (0 means no alias is present).
    73 	TPde* iAliasPdePtr;		// Address of PDE which has been modified to make aliased memory accessible.
    74 	TPde iAliasPde;			// PDE to store at iAliasPdePtr.
    75 	DMemModelProcess* iAliasProcess;		// The process whose memory is aliased.
    76 	SDblQueLink iAliasLink;	// link to make TheMmu.iAliasList.
    77 	TLinAddr iAliasTarget;	// linear address of the memory which has been aliased
    78 	DMemoryMapping* iKernelStackMapping;
    79 	DMemoryMapping* iUserStackMapping;
    80 #ifdef __SMP__
    81 	TInt iCpuRestoreCookie;
    82 #endif
    83 	};
    84 
    85 
    86 /********************************************
    87  * Process Control Block
    88  ********************************************/
    89 
    90 class DMemModelChunk;
    91 class DMemModelCodeSegMemory;
    92 class RAddressedContainer;
    93 
    94 #ifdef INCLUDED_FROM_ASM
    95 #define PRIVATE_EXCEPT_ASM public
    96 #else
    97 #define PRIVATE_EXCEPT_ASM private
    98 #endif
    99 
   100 
   101 /**
   102 @internalComponent
   103 */
   104 class DMemModelProcess : public DEpocProcess
   105 	{
   106 public:
   107 	~DMemModelProcess();
   108 private:
   109 	void Destruct();
   110 protected:
   111 	virtual TInt AttachExistingCodeSeg(TProcessCreateInfo& aInfo);
   112 	virtual TInt SetPaging(const TProcessCreateInfo& aInfo);
   113 public:
   114 	virtual TInt DoCreate(TBool aKernelProcess, TProcessCreateInfo& aInfo);
   115 	virtual TInt NewChunk(DChunk*& aChunk, SChunkCreateInfo& aInfo, TLinAddr& aRunAddr);
   116 	virtual TInt AddChunk(DChunk* aChunk,TBool aIsReadOnly);
   117 	virtual TInt NewShPool(DShPool*& aPool, TShPoolCreateInfo& aInfo);
   118 	virtual TInt CreateDataBssStackArea(TProcessCreateInfo& aInfo);
   119 	virtual TInt MapCodeSeg(DCodeSeg* aCodeSeg);
   120 	virtual void UnmapCodeSeg(DCodeSeg* aCodeSeg);
   121 	virtual void RemoveDllData();
   122 	virtual void FinalRelease();
   123 	virtual void BTracePrime(TInt aCategory);
   124 public:
   125 	TInt DoAddChunk(DMemModelChunk* aChunk, TBool aIsReadOnly);
   126 	TInt AllocateDataSectionBase(DMemModelChunk& aChunk, TUint& aBase);
   127 	TUint8* DataSectionBase(DMemModelChunk* aChunk);
   128 	void RemoveChunk(DMemModelChunk *aChunk);
   129 	void DoRemoveChunk(TInt aIndex);
   130 	TInt ChunkIndex(DMemModelChunk* aChunk);
   131 	TUint ChunkInsertIndex(DMemModelChunk* aChunk);
   132 	TInt CommitDllData(TLinAddr aBase, TInt aSize, DCodeSeg* aCodeSeg);
   133 	void DecommitDllData(TLinAddr aBase, TInt aSize);
   134 	TInt MapUserRamCode(DMemModelCodeSegMemory* aMemory);
   135 	void UnmapUserRamCode(DMemModelCodeSegMemory* aMemory);
   136 	inline TInt OsAsid()
   137 		{__NK_ASSERT_DEBUG(	TheCurrentThread->iOwningProcess == this || // current thread's process so asid can't be freed.
   138 							iOsAsid == (TInt)KKernelOsAsid ||	// kernel process so asid can't be freed.
   139 							iContainerID != EProcess ||	// process not fully created yet so asid can't be freed.
   140 							iOsAsidRefCount > 1);		// if none of the others are true then should have a reference 
   141 														// to prevent asid being freed (this check isn't very 
   142 														// robust but best we can do).
   143 		return iOsAsid;
   144 		};
   145 
   146 	TInt TryOpenOsAsid();
   147 	void CloseOsAsid();
   148 	void AsyncCloseOsAsid();
   149 public:
   150 	struct SChunkInfo
   151 		{
   152 		DMemModelChunk* iChunk;
   153 		DMemoryMapping* iMapping;
   154 		TInt16 iAccessCount;
   155 		TInt16 iIsReadOnly;
   156 		};
   157 
   158 	TInt iChunkCount;
   159 	TInt iChunkAlloc;
   160 	SChunkInfo* iChunks;
   161 	RAddressedContainer* iSharedChunks;
   162 	TPhysAddr iPageDir;
   163 	DMemoryMapping* iDataBssMapping;
   164 	/**
   165 	Size of virtual memory allocated in process for EXE code, but which hasn't yet been been
   166 	adopted by the codeseg memory mapping.
   167 	*/
   168 	TUint iCodeVirtualAllocSize;
   169 	/**
   170 	Address of virtual memory allocated in process for EXE code.
   171 	*/
   172 	TLinAddr iCodeVirtualAllocAddress;
   173 
   174 PRIVATE_EXCEPT_ASM:
   175 	TInt iOsAsid;		// This should only be accessed directly by the scheduler, 
   176 						// in all other cases use either OsAsid() or TryOpenOsAsid().
   177 private:
   178 	TUint iOsAsidRefCount;
   179 public:
   180 	friend class Monitor;
   181 	};
   182 
   183 
   184 /********************************************
   185  * Chunk Control Block
   186  ********************************************/
   187 
   188 /**
   189 @internalComponent
   190 */
   191 class DMemModelChunk : public DChunk
   192 	{
   193 public:
   194 	/**
   195 	@see DChunk::TChunkAttributes for generic attribute flags
   196 	*/
   197 	enum TMemModelChunkAttributes
   198 		{
   199 		EPrivate			=0x00000000, // need to be iOwningProcess in order to map or change chunk
   200 		EPublic				=0x80000000, // not EPrivate
   201 		ECode				=0x40000000, // contents are executable
   202 		EMMChunkAttributesMask = EPrivate | EPublic | ECode,
   203 		};
   204 	
   205 public:
   206 	DMemModelChunk();
   207 	~DMemModelChunk();
   208 public:
   209 	virtual TInt Close(TAny* aPtr);
   210 	virtual TInt DoCreate(SChunkCreateInfo& aInfo);
   211 	virtual TInt Adjust(TInt aNewSize);
   212 	virtual TInt AdjustDoubleEnded(TInt aBottom, TInt aTop);
   213 	virtual TInt CheckAccess();
   214 	virtual TInt Commit(TInt aOffset, TInt aSize, TCommitType aCommitType=DChunk::ECommitDiscontiguous, TUint32* aExtraArg=0);
   215 	virtual TInt Allocate(TInt aSize, TInt aGuard=0, TInt aAlign=0);
   216 	virtual TInt Decommit(TInt aOffset, TInt aSize);
   217 	virtual TInt Lock(TInt aOffset, TInt aSize);
   218 	virtual TInt Unlock(TInt aOffset, TInt aSize);
   219 	virtual TInt Address(TInt aOffset, TInt aSize, TLinAddr& aKernelAddress);
   220 	virtual TInt PhysicalAddress(TInt aOffset, TInt aSize, TLinAddr& aKernelAddress, TUint32& aPhysicalAddress, TUint32* aPhysicalPageList=NULL);
   221 	virtual void BTracePrime(TInt aCategory);
   222 	virtual void Substitute(TInt aOffset, TPhysAddr aOldAddr, TPhysAddr aNewAddr);
   223 	virtual TUint8* Base(DProcess* aProcess);
   224 protected:
   225 	virtual void SetPaging(TUint aCreateAtt);
   226 public:
   227 	void SetFixedAddress(TLinAddr aAddr, TInt aInitialSize);
   228 	TInt SetAttributes(SChunkCreateInfo& aInfo);
   229 	TInt DoCommit(TInt aOffset, TInt aSize, TCommitType aCommitType=DChunk::ECommitDiscontiguous, TUint32* aExtraArg=0);
   230 	void DoDecommit(TInt aOffset, TInt aSize);
   231 	TInt CheckRegion(TInt& aOffset, TInt& aSize);
   232 public:
   233 	TBitMapAllocator* iPageBitMap;		// NULL if not disconnected chunk
   234 	TBitMapAllocator* iPermanentPageBitMap;
   235 
   236 	/**
   237 	The memory object containing this chunk's memory.
   238 	*/
   239 	DMemoryObject* iMemoryObject;
   240 
   241 	/**
   242 	For shared chunks and shared i/o buffers this is the mapping
   243 	which maps #iMemoryObject into the kernel's address space.
   244 	*/
   245 	DMemoryMapping* iKernelMapping;
   246 public:
   247 	friend class Monitor;
   248 	};
   249 
   250 
   251 /**
   252 @internalComponent
   253 */
   254 class DMemModelChunkHw : public DPlatChunkHw
   255 	{
   256 public:
   257 	virtual TInt Close(TAny* aPtr);
   258 public:
   259 	DMemoryObject* iMemoryObject;
   260 	DMemoryMapping* iKernelMapping;
   261 	};
   262 
   263 
   264 	
   265 /********************************************
   266  * Code segment
   267  ********************************************/
   268 
   269 class TPagedCodeInfo;
   270 
   271 /**
   272 @internalComponent
   273 */
   274 class DMemModelCodeSegMemory : public DEpocCodeSegMemory
   275 	{
   276 public:
   277 	DMemModelCodeSegMemory(DEpocCodeSeg* aCodeSeg);
   278 	~DMemModelCodeSegMemory();
   279 	TInt Create(TCodeSegCreateInfo& aInfo, DMemModelProcess* aProcess);
   280 	TInt Loaded(TCodeSegCreateInfo& aInfo);
   281 	void Destroy();
   282 public:
   283 	/**
   284 	The process loading this code segment.
   285 	*/
   286 	DMemModelProcess* iCreator;
   287 
   288 	/**
   289 	Kernel side copy of the codeseg's export directory or NULL.
   290 	*/
   291 	TLinAddr* iCopyOfExportDir;
   292 
   293 	/**
   294 	For demand paged codeseg's, pointer to saved copy of the data section.
   295 	*/
   296 	TAny* iDataSectionMemory;
   297 
   298 	/**
   299 	The memory object containing the memory for the codeseg.
   300 	*/
   301 	DMemoryObject* iCodeMemoryObject;
   302 
   303 	/**
   304 	A writable mapping which maps #iCodeMemoryObject into the loader
   305 	process's memory so it can be accessed by the loader.
   306 
   307 	This mapping is destroyed once #Loaded is called.
   308 	*/
   309 	DMemoryMapping* iCodeLoadMapping;
   310 
   311 	/**
   312 	For demand paged codeseg's, this is a writable mapping added to the
   313 	loader process's address space which maps a memory object used to
   314 	hold the initial contents of the codeseg's data section.
   315 
   316 	This mapping, and it's memory object, is destroyed once #Loaded is called.
   317 	*/
   318 	DMemoryMapping* iDataLoadMapping;
   319 
   320 	/**
   321 	Size of any shared virtual memory allocated for the code.
   322 	*/
   323 	TUint iVirtualAllocCommonSize;
   324 
   325 	/**
   326 	For demand paged codeseg's, a pointer to the #TPagedCodeInfo
   327 	used with #iCodeMemoryObject.
   328 	*/
   329 	TPagedCodeInfo* iPagedCodeInfo;
   330 	};
   331 
   332 
   333 /**
   334 @internalComponent
   335 */
   336 class DMemModelCodeSeg: public DEpocCodeSeg
   337 	{
   338 public:
   339 	DMemModelCodeSeg();
   340 	virtual ~DMemModelCodeSeg();
   341 	virtual TInt DoCreateRam(TCodeSegCreateInfo& aInfo, DProcess* aProcess);
   342 	virtual TInt DoCreateXIP(DProcess* aProcess);
   343 	virtual TInt Loaded(TCodeSegCreateInfo& aInfo);
   344 	virtual void ReadExportDir(TUint32* aDest);
   345 	virtual TBool FindCheck(DProcess* aProcess);
   346 	virtual TBool OpenCheck(DProcess* aProcess);
   347 	inline DMemModelCodeSegMemory* Memory()
   348 		{ return (DMemModelCodeSegMemory*)iMemory; }
   349 	virtual void BTracePrime(TInt aCategory);
   350 public:
   351 	/**
   352 	For kernel codesegs, the address of the memory allocated for its static data.
   353 	*/
   354 	TAny* iKernelData;
   355 
   356 	/**
   357 	The memory object containing the memory for this codeseg.
   358 	*/
   359 	DMemoryObject* iCodeMemoryObject;
   360 
   361 	/**
   362 	A writable mapping which maps #iCodeMemoryObject into the loader
   363 	process's memory so it can be accessed by the loader.
   364 
   365 	This mapping is destroyed once #Loaded is called.
   366 	*/
   367 	DMemoryMapping* iCodeLoadMapping;
   368 
   369 	/**
   370 	The read=only mapping used for kernel and global codesegs to map
   371 	#iCodeMemoryObject into the global address region.
   372 	*/
   373 	DMemoryMapping* iCodeGlobalMapping;
   374 
   375 	/**
   376 	Base address of virtual memory allocated for the codeseg's static data.
   377 	*/
   378 	TLinAddr iDataAllocBase;	
   379 
   380 	/**
   381 	Size of virtual memory allocated for the codeseg's static data.
   382 	*/
   383 	TUint iDataAllocSize;
   384 	};
   385 
   386 
   387 /********************************************
   388  * Shared buffers and pools
   389  ********************************************/
   390 
   391 #include <kernel/sshbuf.h>
   392 
   393 class DShBufMapping;
   394 
   395 
   396 class DMemModelNonAlignedShBuf : public DShBuf
   397 	{
   398 public:
   399 	DMemModelNonAlignedShBuf(DShPool* aPool, TLinAddr aRelAddr);
   400 	~DMemModelNonAlignedShBuf();
   401 
   402 	TInt Close(TAny*);
   403 	TInt AddToProcess(DProcess* aProcess, TUint aAttr);
   404 
   405 protected:
   406 	virtual TInt Pin(TPhysicalPinObject* aPinObject, TBool aReadOnly, TPhysAddr& aAddress, TPhysAddr* aPages, TUint32& aMapAttr, TUint& aColour);
   407 	virtual TInt Map(TUint, DProcess*, TLinAddr&);
   408 	virtual TInt UnMap(DProcess*);
   409 	virtual TUint8* Base(DProcess* aProcess);
   410 	virtual TUint8* Base();
   411 	};
   412 
   413 
   414 class DMemModelAlignedShBuf : public DShBuf
   415 	{
   416 public:
   417 	DMemModelAlignedShBuf(DShPool* aPool);
   418 	virtual ~DMemModelAlignedShBuf();
   419 
   420 	TInt Create();
   421 	virtual TInt Construct();
   422 
   423 	TInt Close(TAny*);
   424 	TInt AddToProcess(DProcess* aProcess, TUint aAttr);
   425 
   426 protected:
   427 	TUint8* Base(DProcess* aProcess);
   428 	TUint8* Base();
   429 	TInt Map(TUint, DProcess*, TLinAddr&);
   430 	TInt UnMap(DProcess*);
   431 	TInt Pin(TPhysicalPinObject* aPinObject, TBool aReadOnly, TPhysAddr& Address, TPhysAddr* aPages, TUint32& aMapAttr, TUint& aColour);
   432 
   433 private:
   434 	TInt FindMapping(DShBufMapping*&, DMemModelProcess*);
   435 	DMemoryObject* iMemoryObject;
   436 	DMemoryMapping* iKernelMapping;
   437 	SDblQue iMappings;
   438 	friend class DMemModelAlignedShPool;
   439 	};
   440 
   441 class DMemModelShPool : public DShPool
   442 	{
   443 public:
   444 	DMemModelShPool();
   445 	virtual ~DMemModelShPool();
   446 protected:
   447 	void DestroyClientResources(DProcess* aProcess);
   448 	virtual TInt DestroyAllMappingsAndReservedHandles(DProcess* aProcess) = 0;
   449 	};
   450 
   451 class DMemModelAlignedShPoolClient : public DShPoolClient
   452 	{
   453 public:
   454 	SDblQue iMappingFreeList;
   455 	TInt iWindowSize;
   456 	};
   457 
   458 class DMemModelNonAlignedShPoolClient : public DShPoolClient
   459 	{
   460 public:
   461 	DMemoryMapping* iMapping;
   462 	};
   463 
   464 class DShBufMapping;
   465 
   466 class DMemModelAlignedShPool : public DMemModelShPool
   467 	{
   468 public:
   469 	DMemModelAlignedShPool();
   470 	virtual ~DMemModelAlignedShPool();
   471 
   472 	TInt Close(TAny* aPtr);
   473 	TInt CreateInitialBuffers();
   474 	TInt SetBufferWindow(DProcess* aProcess, TInt aWindowSize);
   475 	TInt AddToProcess(DProcess* aProcess, TUint aAttr);
   476 	TInt Alloc(DShBuf*&);
   477 
   478 private:
   479 	TInt DoCreate(TShPoolCreateInfo& aInfo);
   480 	TInt GrowPool();
   481 	TInt ShrinkPool();
   482 	TInt MappingNew(DShBufMapping*& aMapping, DMemModelProcess* aProcess);
   483 	TInt GetFreeMapping(DShBufMapping*& aMapping, DMemModelAlignedShPoolClient* aClient);
   484 	TInt ReleaseMapping(DShBufMapping*& aMapping, DMemModelAlignedShPoolClient* aClient);
   485 	TInt UpdateMappingsAndReservedHandles(TInt aNoOfBuffers);
   486 	TInt UpdateFreeList();
   487 	void Free(DShBuf* aBuf);
   488 	TInt CreateMappings(DMemModelAlignedShPoolClient* aClient, TInt aNoOfMappings, DMemModelProcess* aProcess);
   489 	TInt DestroyAllMappingsAndReservedHandles(DProcess* aProcess);
   490 	TInt DestroyMappings(DMemModelAlignedShPoolClient* aClient, TInt aNoOfMappings);
   491 
   492 	TInt DeleteInitialBuffers();
   493 
   494 	SDblQue iPendingList;
   495 	DMemModelAlignedShBuf* iInitialBuffersArray;
   496 
   497 	friend class DMemModelAlignedShBuf;
   498 	};
   499 
   500 class DMemModelNonAlignedShPool : public DMemModelShPool
   501 	{
   502 public:
   503 	DMemModelNonAlignedShPool();
   504 	virtual ~DMemModelNonAlignedShPool();
   505 
   506 	TInt Close(TAny* aPtr);
   507 
   508 	TInt DoInitFreeList();
   509 	TUint8* Base(DProcess* aProcess);
   510 
   511 	inline TUint8* Base()
   512 		{
   513 		return reinterpret_cast<TUint8*>(iBaseAddress);
   514 		};
   515 	TInt AddToProcess(DProcess* aProcess, TUint aAttr);
   516 	TInt CreateInitialBuffers();
   517 
   518 	TInt Alloc(DShBuf*&);
   519 
   520 private:
   521 	void Free(DShBuf* aBuf);
   522 	TInt UpdateFreeList();
   523 
   524 	TInt DoCreate(TShPoolCreateInfo& aInfo);
   525 	void FreeBufferPages(TUint aOffset);
   526 	TInt GrowPool();
   527 	TInt ShrinkPool();
   528 	TInt DeleteInitialBuffers();
   529 	TInt DestroyAllMappingsAndReservedHandles(DProcess* aProcess);
   530 
   531 private:
   532 	TLinAddr iBaseAddress;
   533 	DMemoryObject* iMemoryObject;		// the 'real' memory pool (in the kernel)
   534 	DMemModelNonAlignedShBuf* iInitialBuffersArray;
   535 	TBitMapAllocator* iBufMap;
   536 	TBitMapAllocator* iPagesMap;
   537 
   538 	friend class DMemModelNonAlignedShBuf;
   539 	};
   540 
   541 #endif