kernel/eka/memmodel/epoc/flexible/mmu/maddressspace.h
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2007-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 //
       
    15 
       
    16 /**
       
    17 @file
       
    18 @internalComponent
       
    19 */
       
    20 
       
    21 #ifndef MADDRESSSPACE_H
       
    22 #define MADDRESSSPACE_H
       
    23 
       
    24 #include "mrefcntobj.h"
       
    25 #include "maddrcont.h"
       
    26 #include "mvalloc.h"
       
    27 
       
    28 
       
    29 
       
    30 //
       
    31 // DAddressSpace
       
    32 //
       
    33 
       
    34 /**
       
    35 Class representing the virtual address space used by a single process.
       
    36 
       
    37 Each address space has:
       
    38 - An MMU page directory.
       
    39 - An allocator for virtual addresses.
       
    40 - A list of memory mappings currently mapped into it.
       
    41 
       
    42 Most other APIs in the kernel which make use of address spaces don't use pointers to
       
    43 the address space object itself, instead they use an OS Address Space ID (OS ASID).
       
    44 This is an integer less than KNumOsAsids and can be used to index into the array of
       
    45 address space objects - #AddressSpace.
       
    46 */
       
    47 class DAddressSpace : public DReferenceCountedObject
       
    48 	{
       
    49 public:
       
    50 	/**
       
    51 	Initialiser called during stage 2 of system boot.
       
    52 	This includes initialisation of the kernel's address space object.
       
    53 	*/
       
    54 	static void Init2();
       
    55 
       
    56 	/**
       
    57 	Create a new address space.
       
    58 
       
    59 	This creates a DAddressSpace address space object and adds it to the array
       
    60 	of all address space objects - #AddressSpace. The function returns the objects
       
    61 	index into this array, this value is used as OS Address Space ID (OS ASID)
       
    62 	in most kernel APIs which refer to address spaces.
       
    63 
       
    64 	@param[out] aPageDirectory	Returns the physical address of the MMU page directory
       
    65 								which was created for the new address space.
       
    66 
       
    67 	@return On success, the OS ASID value for the new address space;
       
    68 			otherwise one of the system wide error codes
       
    69 	*/
       
    70 	static TInt New(TPhysAddr& aPageDirectory);
       
    71 public:
       
    72 	DAddressSpace();
       
    73 	~DAddressSpace();
       
    74 
       
    75 	/**
       
    76 	Allocate a region of virtual addresses within this address space.
       
    77 
       
    78 	The returned region may have a start address and/or size which is different to
       
    79 	those requested due to various alignment requirements in the implementation.
       
    80 	However the returned region will always include all addresses requested.
       
    81 
       
    82 	The range of virtual addresses available to a user-side address space is
       
    83 	#KUserLocalDataBase through to #KUserLocalDataEnd.
       
    84 
       
    85 	The range of virtual addresses available to the kernel's address space (#KKernelOsAsid)
       
    86 	is #KKernelSectionBase though to #KKernelSectionEnd.
       
    87 
       
    88 	@param[out] aAddr			Returns the start address of the region which was allocated.
       
    89 								This will always be aligned to a multiple of the page colouring
       
    90 								size: #KPageColourCount*#KPageSize.
       
    91 	@param[out] aSize			Returns the size, in bytes, of the region which was allocated.
       
    92 	@param		aRequestedAddr	The requested start address of the region to allocate,
       
    93 								or zero if no specific address is required.
       
    94 	@param		aRequestedSize	The requested size, in bytes, of the region to allocate.
       
    95 	@param		aPdeType		A value from #TPdeType ORed with flags from #TVirtualSlabType.
       
    96 								This is used to prevent incompatible memory uses (different
       
    97 								\a aPdeType values) from being allocated virtual addresses
       
    98 								which would share the same MMU page table.
       
    99 
       
   100 	@return KErrNone if successful, otherwise one of the system wide error codes.
       
   101 	*/
       
   102 	TInt AllocateVirtualMemory(TLinAddr& aAddr, TUint& aSize, TLinAddr aRequestedAddr, TUint aRequestedSize, TUint aPdeType);
       
   103 
       
   104 	/**
       
   105 	Allocate a region of virtual addresses within the global address region, for use by
       
   106 	user-side code. These global addresses are outside the range of addresses used
       
   107 	by any individual address space, and so are globally unique. They lie in the range
       
   108 	from #KGlobalMemoryBase through to #KUserMemoryLimit.
       
   109 
       
   110 	The arguments for this function are of the same type and use as #AllocateVirtualMemory.
       
   111 	*/
       
   112 	static TInt AllocateUserGlobalVirtualMemory(TLinAddr& aAddr, TUint& aSize, TLinAddr aRequestedAddr, TUint aRequestedSize, TUint aPdeType);
       
   113 
       
   114 	/**
       
   115 	Free a virtual addresses region which was allocated with #AllocateVirtualMemory
       
   116 	or #AllocateUserGlobalVirtualMemory. The region supplied to this function
       
   117 	must either be one supplied to a previous call to AllocateVirtualMemory or
       
   118 	be one returned by that function.
       
   119 
       
   120 	@param aAddr	Start address of the region to be freed.
       
   121 	@param aSize	Size, in bytes, of the region to be freed.
       
   122 	*/
       
   123 	void FreeVirtualMemory(TLinAddr aAddr, TUint aSize);
       
   124 
       
   125 	/**
       
   126 	Allocate a region of virtual addresses for use by memory which should appear at
       
   127 	the same address in all user-side processes which map it. E.g. for position dependant
       
   128 	memory like executable code.
       
   129 
       
   130 	The region allocated lies in the range used by normal user-side address spaces
       
   131 	but there is no guarantee that the addresses are not already in use by any of them,
       
   132 	and there is nothing to prevent the allocated addresses from being returned by any
       
   133 	future call to #AllocateVirtualMemory.
       
   134 
       
   135 	However, as the 'common' addresses are allocated from the top of memory downwards
       
   136 	and #AllocateVirtualMemory allocates upwards from the bottom of memory it XXX TODO
       
   137 
       
   138 	The arguments for this function are of the same type and use as #AllocateVirtualMemory.
       
   139 	*/
       
   140 	static TInt AllocateUserCommonVirtualMemory(TLinAddr& aAddr, TUint& aSize, TLinAddr aRequestedAddr, TUint aRequestedSize, TUint aPdeType);
       
   141 
       
   142 	/**
       
   143 	Free a virtual addresses region which was allocated with #AllocateUserCommonVirtualMemory.
       
   144 	The region supplied to this function must either be one supplied to a previous
       
   145 	call to AllocateVirtualMemory or be one returned by that function.
       
   146 
       
   147 	@param aAddr	Start address of the region to be freed.
       
   148 	@param aSize	Size, in bytes, of the region to be freed.
       
   149 	*/
       
   150 	static void FreeUserCommonVirtualMemory(TLinAddr aAddr, TUint aSize);
       
   151 
       
   152 	/**
       
   153 	Add a memory mapping to this address space's list of mappings.
       
   154 
       
   155 	This is intended only for use by #DMemoryMapping.
       
   156 
       
   157 	@param aAddr	The address which is allocated to the mapping
       
   158 					(DMemoryMapping::iAllocatedLinAddrAndOsAsid&~KPageMask).
       
   159 	@param aMapping	The mapping to add.
       
   160 
       
   161 	@return KErrNone if successful, otherwise one of the system wide error codes.
       
   162 	*/
       
   163 	TInt AddMapping(TLinAddr aAddr, DMemoryMapping* aMapping);
       
   164 
       
   165 	/**
       
   166 	Remove a memory mapping from this address space's list of mappings.
       
   167 
       
   168 	This is intended only for use by #DMemoryMapping.
       
   169 
       
   170 	@param aAddr	The address which was used to add the mapping with AddMapping.
       
   171 
       
   172 	@return Pointer to the removed mapping or the null pointer if no mapping
       
   173 			was found to match the specified address.
       
   174 	*/
       
   175 	DMemoryMapping* RemoveMapping(TLinAddr aAddr);
       
   176 
       
   177 	/**
       
   178 	Get a pointer to a memory mapping which was previously added to this
       
   179 	address space's list of mappings. This function does not perform any additional
       
   180 	reference counting or locking to prevent the returned pointer becoming invalid,
       
   181 	therefore the caller must ensure that it is not possible for another thread to
       
   182 	destroy the mapping.
       
   183 
       
   184 	The typical use case for this function is where the owner of the mapping has
       
   185 	not saved the pointer to the mapping object but has instead kept track of the
       
   186 	virtual address it uses. This function can then be used to retrieve the pointer
       
   187 	to the object again.
       
   188 
       
   189 	If no mapping exists for the specified address the results are unpredictable.
       
   190 
       
   191 	@param aAddr	The address which was used to add the mapping with AddMapping.
       
   192 
       
   193 	@return Pointer to the mapping.
       
   194 	*/
       
   195 	DMemoryMapping* GetMapping(TLinAddr aAddr);
       
   196 
       
   197 	/**
       
   198 	Find the mapping within this address space which maps a specified region of
       
   199 	addresses. A mapping is only found if all of the bytes in the specified region
       
   200 	lie within it and it is current mapping a memory object (#DMemoryMapping::IsAttached
       
   201 	returns true).
       
   202 
       
   203 	The returned mapping will have had its reference count incremented and it is
       
   204 	the callers responsibility to balance this with a #Close or #AsyncClose.
       
   205 
       
   206 	@param		aAddr				The start address of the region.
       
   207 	@param		aSize				The size, in bytes, of the region.
       
   208 	@param[out] aOffsetInMapping	Returns the byte address offset within the found
       
   209 									mapping which corresponds to \a aAddr.
       
   210 	@param[out] aInstanceCount		The instance count of the found mapping.
       
   211 
       
   212 	@return Pointer to the mapping which contains the specified region
       
   213 			or the null pointer if no mapping was found.
       
   214 
       
   215 	@post The returned mapping will have had its reference count incremented.
       
   216 	*/
       
   217 	DMemoryMapping* FindMapping(TLinAddr aAddr, TUint aSize, TUint& aOffsetInMapping, TUint& aInstanceCount);
       
   218 
       
   219 	/**
       
   220 	Check that the virtual addresses previously allocated with #AllocateVirtualMemory
       
   221 	or #AllocateUserGlobalVirtualMemory are compatible with the specified 'pde type'.
       
   222 
       
   223 	This is only intended for used by error checking in debug builds.
       
   224 
       
   225 	@param aAddr	The start address of the region.
       
   226 	@param aSize	The size, in bytes, of the region.
       
   227 	@param aPdeType	See description in AllocateVirtualMemory.
       
   228 	*/
       
   229 	TBool CheckPdeType(TLinAddr aAddr, TUint aSize, TUint aPdeType);
       
   230 
       
   231 private:
       
   232 	/**
       
   233 	Second phase constructor.
       
   234 
       
   235 	@param aOsAsid	The OS ASID for the address space.
       
   236 	@param aStart	The first virtual address available in the address space.
       
   237 	@param aEnd		The last virtual address (plus one) available in the address space.
       
   238 
       
   239 	@return KErrNone if successful, otherwise one of the system wide error codes.
       
   240 	*/
       
   241 	TInt Construct(TInt aOsAsid, TLinAddr aStart, TLinAddr aEnd);
       
   242 
       
   243 	/**
       
   244 	Wait on the mutex used to protect virtual address allocation and the
       
   245 	addition/removal of memory mappings. This is only used internally by
       
   246 	the DAddressSpace methods.
       
   247 	*/
       
   248 	void Lock();
       
   249 
       
   250 	/**
       
   251 	Reverse the action of #Lock.
       
   252 	*/
       
   253 	void Unlock();
       
   254 
       
   255 	/**
       
   256 	In debug builds, dump information about each mapping in the address to the
       
   257 	kernel trace port.
       
   258 	*/
       
   259 	void Dump();
       
   260 
       
   261 private:
       
   262 	/**
       
   263 	The OS ASID value for this address space.
       
   264 	This is its index in the array #AddressSpace.
       
   265 	*/
       
   266 	TInt iOsAsid;
       
   267 
       
   268 	/**
       
   269 	Lock currently being used to protect virtual address allocation (#iVirtualAllocator)
       
   270 	and changes to the mapping container (#iMappings).
       
   271 	*/
       
   272 	DMutex* iLock;
       
   273 
       
   274 	/**
       
   275 	Container containing all mappings added to this address space.
       
   276 	*/
       
   277 	RAddressedContainer iMappings;
       
   278 
       
   279 	/**
       
   280 	Allocator object for virtual addresses within the address space.
       
   281 	*/
       
   282 	RVirtualAllocator iVirtualAllocator;
       
   283 
       
   284 private:
       
   285 	/**
       
   286 	Allocator for virtual addresses within the global address region for use by user-side code.
       
   287 
       
   288 	This is used by #AllocateUserGlobalVirtualMemory and the lock mutex for the
       
   289 	kernel's address space is used to protect access.
       
   290 	*/
       
   291 	static RVirtualAllocator UserGlobalVirtualAllocator;
       
   292 
       
   293 	/**
       
   294 	Allocator for virtual addresses for use by memory which should appear at
       
   295 	the same address in all user-side processes which map it.
       
   296 
       
   297 	This is used by AllocateUserCommonVirtualMemory and the lock mutex for the
       
   298 	kernel's address space is used to protect access.
       
   299 	*/
       
   300 	static RBackwardsVirtualAllocator UserCommonVirtualAllocator;
       
   301 	};
       
   302 
       
   303 
       
   304 /**
       
   305 Array of all address spaces. An OS Address Space ID (OS ASID) can be used to
       
   306 index this array to find the corresponding DAddressSpace object.
       
   307 */
       
   308 extern DAddressSpace* AddressSpace[];
       
   309 
       
   310 
       
   311 #endif