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