1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/memmodel/epoc/flexible/mmu/maddressspace.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,311 @@
1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +/**
1.20 +@file
1.21 +@internalComponent
1.22 +*/
1.23 +
1.24 +#ifndef MADDRESSSPACE_H
1.25 +#define MADDRESSSPACE_H
1.26 +
1.27 +#include "mrefcntobj.h"
1.28 +#include "maddrcont.h"
1.29 +#include "mvalloc.h"
1.30 +
1.31 +
1.32 +
1.33 +//
1.34 +// DAddressSpace
1.35 +//
1.36 +
1.37 +/**
1.38 +Class representing the virtual address space used by a single process.
1.39 +
1.40 +Each address space has:
1.41 +- An MMU page directory.
1.42 +- An allocator for virtual addresses.
1.43 +- A list of memory mappings currently mapped into it.
1.44 +
1.45 +Most other APIs in the kernel which make use of address spaces don't use pointers to
1.46 +the address space object itself, instead they use an OS Address Space ID (OS ASID).
1.47 +This is an integer less than KNumOsAsids and can be used to index into the array of
1.48 +address space objects - #AddressSpace.
1.49 +*/
1.50 +class DAddressSpace : public DReferenceCountedObject
1.51 + {
1.52 +public:
1.53 + /**
1.54 + Initialiser called during stage 2 of system boot.
1.55 + This includes initialisation of the kernel's address space object.
1.56 + */
1.57 + static void Init2();
1.58 +
1.59 + /**
1.60 + Create a new address space.
1.61 +
1.62 + This creates a DAddressSpace address space object and adds it to the array
1.63 + of all address space objects - #AddressSpace. The function returns the objects
1.64 + index into this array, this value is used as OS Address Space ID (OS ASID)
1.65 + in most kernel APIs which refer to address spaces.
1.66 +
1.67 + @param[out] aPageDirectory Returns the physical address of the MMU page directory
1.68 + which was created for the new address space.
1.69 +
1.70 + @return On success, the OS ASID value for the new address space;
1.71 + otherwise one of the system wide error codes
1.72 + */
1.73 + static TInt New(TPhysAddr& aPageDirectory);
1.74 +public:
1.75 + DAddressSpace();
1.76 + ~DAddressSpace();
1.77 +
1.78 + /**
1.79 + Allocate a region of virtual addresses within this address space.
1.80 +
1.81 + The returned region may have a start address and/or size which is different to
1.82 + those requested due to various alignment requirements in the implementation.
1.83 + However the returned region will always include all addresses requested.
1.84 +
1.85 + The range of virtual addresses available to a user-side address space is
1.86 + #KUserLocalDataBase through to #KUserLocalDataEnd.
1.87 +
1.88 + The range of virtual addresses available to the kernel's address space (#KKernelOsAsid)
1.89 + is #KKernelSectionBase though to #KKernelSectionEnd.
1.90 +
1.91 + @param[out] aAddr Returns the start address of the region which was allocated.
1.92 + This will always be aligned to a multiple of the page colouring
1.93 + size: #KPageColourCount*#KPageSize.
1.94 + @param[out] aSize Returns the size, in bytes, of the region which was allocated.
1.95 + @param aRequestedAddr The requested start address of the region to allocate,
1.96 + or zero if no specific address is required.
1.97 + @param aRequestedSize The requested size, in bytes, of the region to allocate.
1.98 + @param aPdeType A value from #TPdeType ORed with flags from #TVirtualSlabType.
1.99 + This is used to prevent incompatible memory uses (different
1.100 + \a aPdeType values) from being allocated virtual addresses
1.101 + which would share the same MMU page table.
1.102 +
1.103 + @return KErrNone if successful, otherwise one of the system wide error codes.
1.104 + */
1.105 + TInt AllocateVirtualMemory(TLinAddr& aAddr, TUint& aSize, TLinAddr aRequestedAddr, TUint aRequestedSize, TUint aPdeType);
1.106 +
1.107 + /**
1.108 + Allocate a region of virtual addresses within the global address region, for use by
1.109 + user-side code. These global addresses are outside the range of addresses used
1.110 + by any individual address space, and so are globally unique. They lie in the range
1.111 + from #KGlobalMemoryBase through to #KUserMemoryLimit.
1.112 +
1.113 + The arguments for this function are of the same type and use as #AllocateVirtualMemory.
1.114 + */
1.115 + static TInt AllocateUserGlobalVirtualMemory(TLinAddr& aAddr, TUint& aSize, TLinAddr aRequestedAddr, TUint aRequestedSize, TUint aPdeType);
1.116 +
1.117 + /**
1.118 + Free a virtual addresses region which was allocated with #AllocateVirtualMemory
1.119 + or #AllocateUserGlobalVirtualMemory. The region supplied to this function
1.120 + must either be one supplied to a previous call to AllocateVirtualMemory or
1.121 + be one returned by that function.
1.122 +
1.123 + @param aAddr Start address of the region to be freed.
1.124 + @param aSize Size, in bytes, of the region to be freed.
1.125 + */
1.126 + void FreeVirtualMemory(TLinAddr aAddr, TUint aSize);
1.127 +
1.128 + /**
1.129 + Allocate a region of virtual addresses for use by memory which should appear at
1.130 + the same address in all user-side processes which map it. E.g. for position dependant
1.131 + memory like executable code.
1.132 +
1.133 + The region allocated lies in the range used by normal user-side address spaces
1.134 + but there is no guarantee that the addresses are not already in use by any of them,
1.135 + and there is nothing to prevent the allocated addresses from being returned by any
1.136 + future call to #AllocateVirtualMemory.
1.137 +
1.138 + However, as the 'common' addresses are allocated from the top of memory downwards
1.139 + and #AllocateVirtualMemory allocates upwards from the bottom of memory it XXX TODO
1.140 +
1.141 + The arguments for this function are of the same type and use as #AllocateVirtualMemory.
1.142 + */
1.143 + static TInt AllocateUserCommonVirtualMemory(TLinAddr& aAddr, TUint& aSize, TLinAddr aRequestedAddr, TUint aRequestedSize, TUint aPdeType);
1.144 +
1.145 + /**
1.146 + Free a virtual addresses region which was allocated with #AllocateUserCommonVirtualMemory.
1.147 + The region supplied to this function must either be one supplied to a previous
1.148 + call to AllocateVirtualMemory or be one returned by that function.
1.149 +
1.150 + @param aAddr Start address of the region to be freed.
1.151 + @param aSize Size, in bytes, of the region to be freed.
1.152 + */
1.153 + static void FreeUserCommonVirtualMemory(TLinAddr aAddr, TUint aSize);
1.154 +
1.155 + /**
1.156 + Add a memory mapping to this address space's list of mappings.
1.157 +
1.158 + This is intended only for use by #DMemoryMapping.
1.159 +
1.160 + @param aAddr The address which is allocated to the mapping
1.161 + (DMemoryMapping::iAllocatedLinAddrAndOsAsid&~KPageMask).
1.162 + @param aMapping The mapping to add.
1.163 +
1.164 + @return KErrNone if successful, otherwise one of the system wide error codes.
1.165 + */
1.166 + TInt AddMapping(TLinAddr aAddr, DMemoryMapping* aMapping);
1.167 +
1.168 + /**
1.169 + Remove a memory mapping from this address space's list of mappings.
1.170 +
1.171 + This is intended only for use by #DMemoryMapping.
1.172 +
1.173 + @param aAddr The address which was used to add the mapping with AddMapping.
1.174 +
1.175 + @return Pointer to the removed mapping or the null pointer if no mapping
1.176 + was found to match the specified address.
1.177 + */
1.178 + DMemoryMapping* RemoveMapping(TLinAddr aAddr);
1.179 +
1.180 + /**
1.181 + Get a pointer to a memory mapping which was previously added to this
1.182 + address space's list of mappings. This function does not perform any additional
1.183 + reference counting or locking to prevent the returned pointer becoming invalid,
1.184 + therefore the caller must ensure that it is not possible for another thread to
1.185 + destroy the mapping.
1.186 +
1.187 + The typical use case for this function is where the owner of the mapping has
1.188 + not saved the pointer to the mapping object but has instead kept track of the
1.189 + virtual address it uses. This function can then be used to retrieve the pointer
1.190 + to the object again.
1.191 +
1.192 + If no mapping exists for the specified address the results are unpredictable.
1.193 +
1.194 + @param aAddr The address which was used to add the mapping with AddMapping.
1.195 +
1.196 + @return Pointer to the mapping.
1.197 + */
1.198 + DMemoryMapping* GetMapping(TLinAddr aAddr);
1.199 +
1.200 + /**
1.201 + Find the mapping within this address space which maps a specified region of
1.202 + addresses. A mapping is only found if all of the bytes in the specified region
1.203 + lie within it and it is current mapping a memory object (#DMemoryMapping::IsAttached
1.204 + returns true).
1.205 +
1.206 + The returned mapping will have had its reference count incremented and it is
1.207 + the callers responsibility to balance this with a #Close or #AsyncClose.
1.208 +
1.209 + @param aAddr The start address of the region.
1.210 + @param aSize The size, in bytes, of the region.
1.211 + @param[out] aOffsetInMapping Returns the byte address offset within the found
1.212 + mapping which corresponds to \a aAddr.
1.213 + @param[out] aInstanceCount The instance count of the found mapping.
1.214 +
1.215 + @return Pointer to the mapping which contains the specified region
1.216 + or the null pointer if no mapping was found.
1.217 +
1.218 + @post The returned mapping will have had its reference count incremented.
1.219 + */
1.220 + DMemoryMapping* FindMapping(TLinAddr aAddr, TUint aSize, TUint& aOffsetInMapping, TUint& aInstanceCount);
1.221 +
1.222 + /**
1.223 + Check that the virtual addresses previously allocated with #AllocateVirtualMemory
1.224 + or #AllocateUserGlobalVirtualMemory are compatible with the specified 'pde type'.
1.225 +
1.226 + This is only intended for used by error checking in debug builds.
1.227 +
1.228 + @param aAddr The start address of the region.
1.229 + @param aSize The size, in bytes, of the region.
1.230 + @param aPdeType See description in AllocateVirtualMemory.
1.231 + */
1.232 + TBool CheckPdeType(TLinAddr aAddr, TUint aSize, TUint aPdeType);
1.233 +
1.234 +private:
1.235 + /**
1.236 + Second phase constructor.
1.237 +
1.238 + @param aOsAsid The OS ASID for the address space.
1.239 + @param aStart The first virtual address available in the address space.
1.240 + @param aEnd The last virtual address (plus one) available in the address space.
1.241 +
1.242 + @return KErrNone if successful, otherwise one of the system wide error codes.
1.243 + */
1.244 + TInt Construct(TInt aOsAsid, TLinAddr aStart, TLinAddr aEnd);
1.245 +
1.246 + /**
1.247 + Wait on the mutex used to protect virtual address allocation and the
1.248 + addition/removal of memory mappings. This is only used internally by
1.249 + the DAddressSpace methods.
1.250 + */
1.251 + void Lock();
1.252 +
1.253 + /**
1.254 + Reverse the action of #Lock.
1.255 + */
1.256 + void Unlock();
1.257 +
1.258 + /**
1.259 + In debug builds, dump information about each mapping in the address to the
1.260 + kernel trace port.
1.261 + */
1.262 + void Dump();
1.263 +
1.264 +private:
1.265 + /**
1.266 + The OS ASID value for this address space.
1.267 + This is its index in the array #AddressSpace.
1.268 + */
1.269 + TInt iOsAsid;
1.270 +
1.271 + /**
1.272 + Lock currently being used to protect virtual address allocation (#iVirtualAllocator)
1.273 + and changes to the mapping container (#iMappings).
1.274 + */
1.275 + DMutex* iLock;
1.276 +
1.277 + /**
1.278 + Container containing all mappings added to this address space.
1.279 + */
1.280 + RAddressedContainer iMappings;
1.281 +
1.282 + /**
1.283 + Allocator object for virtual addresses within the address space.
1.284 + */
1.285 + RVirtualAllocator iVirtualAllocator;
1.286 +
1.287 +private:
1.288 + /**
1.289 + Allocator for virtual addresses within the global address region for use by user-side code.
1.290 +
1.291 + This is used by #AllocateUserGlobalVirtualMemory and the lock mutex for the
1.292 + kernel's address space is used to protect access.
1.293 + */
1.294 + static RVirtualAllocator UserGlobalVirtualAllocator;
1.295 +
1.296 + /**
1.297 + Allocator for virtual addresses for use by memory which should appear at
1.298 + the same address in all user-side processes which map it.
1.299 +
1.300 + This is used by AllocateUserCommonVirtualMemory and the lock mutex for the
1.301 + kernel's address space is used to protect access.
1.302 + */
1.303 + static RBackwardsVirtualAllocator UserCommonVirtualAllocator;
1.304 + };
1.305 +
1.306 +
1.307 +/**
1.308 +Array of all address spaces. An OS Address Space ID (OS ASID) can be used to
1.309 +index this array to find the corresponding DAddressSpace object.
1.310 +*/
1.311 +extern DAddressSpace* AddressSpace[];
1.312 +
1.313 +
1.314 +#endif