--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/maddressspace.h Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,311 @@
+// Copyright (c) 2007-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:
+//
+
+/**
+@file
+@internalComponent
+*/
+
+#ifndef MADDRESSSPACE_H
+#define MADDRESSSPACE_H
+
+#include "mrefcntobj.h"
+#include "maddrcont.h"
+#include "mvalloc.h"
+
+
+
+//
+// DAddressSpace
+//
+
+/**
+Class representing the virtual address space used by a single process.
+
+Each address space has:
+- An MMU page directory.
+- An allocator for virtual addresses.
+- A list of memory mappings currently mapped into it.
+
+Most other APIs in the kernel which make use of address spaces don't use pointers to
+the address space object itself, instead they use an OS Address Space ID (OS ASID).
+This is an integer less than KNumOsAsids and can be used to index into the array of
+address space objects - #AddressSpace.
+*/
+class DAddressSpace : public DReferenceCountedObject
+ {
+public:
+ /**
+ Initialiser called during stage 2 of system boot.
+ This includes initialisation of the kernel's address space object.
+ */
+ static void Init2();
+
+ /**
+ Create a new address space.
+
+ This creates a DAddressSpace address space object and adds it to the array
+ of all address space objects - #AddressSpace. The function returns the objects
+ index into this array, this value is used as OS Address Space ID (OS ASID)
+ in most kernel APIs which refer to address spaces.
+
+ @param[out] aPageDirectory Returns the physical address of the MMU page directory
+ which was created for the new address space.
+
+ @return On success, the OS ASID value for the new address space;
+ otherwise one of the system wide error codes
+ */
+ static TInt New(TPhysAddr& aPageDirectory);
+public:
+ DAddressSpace();
+ ~DAddressSpace();
+
+ /**
+ Allocate a region of virtual addresses within this address space.
+
+ The returned region may have a start address and/or size which is different to
+ those requested due to various alignment requirements in the implementation.
+ However the returned region will always include all addresses requested.
+
+ The range of virtual addresses available to a user-side address space is
+ #KUserLocalDataBase through to #KUserLocalDataEnd.
+
+ The range of virtual addresses available to the kernel's address space (#KKernelOsAsid)
+ is #KKernelSectionBase though to #KKernelSectionEnd.
+
+ @param[out] aAddr Returns the start address of the region which was allocated.
+ This will always be aligned to a multiple of the page colouring
+ size: #KPageColourCount*#KPageSize.
+ @param[out] aSize Returns the size, in bytes, of the region which was allocated.
+ @param aRequestedAddr The requested start address of the region to allocate,
+ or zero if no specific address is required.
+ @param aRequestedSize The requested size, in bytes, of the region to allocate.
+ @param aPdeType A value from #TPdeType ORed with flags from #TVirtualSlabType.
+ This is used to prevent incompatible memory uses (different
+ \a aPdeType values) from being allocated virtual addresses
+ which would share the same MMU page table.
+
+ @return KErrNone if successful, otherwise one of the system wide error codes.
+ */
+ TInt AllocateVirtualMemory(TLinAddr& aAddr, TUint& aSize, TLinAddr aRequestedAddr, TUint aRequestedSize, TUint aPdeType);
+
+ /**
+ Allocate a region of virtual addresses within the global address region, for use by
+ user-side code. These global addresses are outside the range of addresses used
+ by any individual address space, and so are globally unique. They lie in the range
+ from #KGlobalMemoryBase through to #KUserMemoryLimit.
+
+ The arguments for this function are of the same type and use as #AllocateVirtualMemory.
+ */
+ static TInt AllocateUserGlobalVirtualMemory(TLinAddr& aAddr, TUint& aSize, TLinAddr aRequestedAddr, TUint aRequestedSize, TUint aPdeType);
+
+ /**
+ Free a virtual addresses region which was allocated with #AllocateVirtualMemory
+ or #AllocateUserGlobalVirtualMemory. The region supplied to this function
+ must either be one supplied to a previous call to AllocateVirtualMemory or
+ be one returned by that function.
+
+ @param aAddr Start address of the region to be freed.
+ @param aSize Size, in bytes, of the region to be freed.
+ */
+ void FreeVirtualMemory(TLinAddr aAddr, TUint aSize);
+
+ /**
+ Allocate a region of virtual addresses for use by memory which should appear at
+ the same address in all user-side processes which map it. E.g. for position dependant
+ memory like executable code.
+
+ The region allocated lies in the range used by normal user-side address spaces
+ but there is no guarantee that the addresses are not already in use by any of them,
+ and there is nothing to prevent the allocated addresses from being returned by any
+ future call to #AllocateVirtualMemory.
+
+ However, as the 'common' addresses are allocated from the top of memory downwards
+ and #AllocateVirtualMemory allocates upwards from the bottom of memory it XXX TODO
+
+ The arguments for this function are of the same type and use as #AllocateVirtualMemory.
+ */
+ static TInt AllocateUserCommonVirtualMemory(TLinAddr& aAddr, TUint& aSize, TLinAddr aRequestedAddr, TUint aRequestedSize, TUint aPdeType);
+
+ /**
+ Free a virtual addresses region which was allocated with #AllocateUserCommonVirtualMemory.
+ The region supplied to this function must either be one supplied to a previous
+ call to AllocateVirtualMemory or be one returned by that function.
+
+ @param aAddr Start address of the region to be freed.
+ @param aSize Size, in bytes, of the region to be freed.
+ */
+ static void FreeUserCommonVirtualMemory(TLinAddr aAddr, TUint aSize);
+
+ /**
+ Add a memory mapping to this address space's list of mappings.
+
+ This is intended only for use by #DMemoryMapping.
+
+ @param aAddr The address which is allocated to the mapping
+ (DMemoryMapping::iAllocatedLinAddrAndOsAsid&~KPageMask).
+ @param aMapping The mapping to add.
+
+ @return KErrNone if successful, otherwise one of the system wide error codes.
+ */
+ TInt AddMapping(TLinAddr aAddr, DMemoryMapping* aMapping);
+
+ /**
+ Remove a memory mapping from this address space's list of mappings.
+
+ This is intended only for use by #DMemoryMapping.
+
+ @param aAddr The address which was used to add the mapping with AddMapping.
+
+ @return Pointer to the removed mapping or the null pointer if no mapping
+ was found to match the specified address.
+ */
+ DMemoryMapping* RemoveMapping(TLinAddr aAddr);
+
+ /**
+ Get a pointer to a memory mapping which was previously added to this
+ address space's list of mappings. This function does not perform any additional
+ reference counting or locking to prevent the returned pointer becoming invalid,
+ therefore the caller must ensure that it is not possible for another thread to
+ destroy the mapping.
+
+ The typical use case for this function is where the owner of the mapping has
+ not saved the pointer to the mapping object but has instead kept track of the
+ virtual address it uses. This function can then be used to retrieve the pointer
+ to the object again.
+
+ If no mapping exists for the specified address the results are unpredictable.
+
+ @param aAddr The address which was used to add the mapping with AddMapping.
+
+ @return Pointer to the mapping.
+ */
+ DMemoryMapping* GetMapping(TLinAddr aAddr);
+
+ /**
+ Find the mapping within this address space which maps a specified region of
+ addresses. A mapping is only found if all of the bytes in the specified region
+ lie within it and it is current mapping a memory object (#DMemoryMapping::IsAttached
+ returns true).
+
+ The returned mapping will have had its reference count incremented and it is
+ the callers responsibility to balance this with a #Close or #AsyncClose.
+
+ @param aAddr The start address of the region.
+ @param aSize The size, in bytes, of the region.
+ @param[out] aOffsetInMapping Returns the byte address offset within the found
+ mapping which corresponds to \a aAddr.
+ @param[out] aInstanceCount The instance count of the found mapping.
+
+ @return Pointer to the mapping which contains the specified region
+ or the null pointer if no mapping was found.
+
+ @post The returned mapping will have had its reference count incremented.
+ */
+ DMemoryMapping* FindMapping(TLinAddr aAddr, TUint aSize, TUint& aOffsetInMapping, TUint& aInstanceCount);
+
+ /**
+ Check that the virtual addresses previously allocated with #AllocateVirtualMemory
+ or #AllocateUserGlobalVirtualMemory are compatible with the specified 'pde type'.
+
+ This is only intended for used by error checking in debug builds.
+
+ @param aAddr The start address of the region.
+ @param aSize The size, in bytes, of the region.
+ @param aPdeType See description in AllocateVirtualMemory.
+ */
+ TBool CheckPdeType(TLinAddr aAddr, TUint aSize, TUint aPdeType);
+
+private:
+ /**
+ Second phase constructor.
+
+ @param aOsAsid The OS ASID for the address space.
+ @param aStart The first virtual address available in the address space.
+ @param aEnd The last virtual address (plus one) available in the address space.
+
+ @return KErrNone if successful, otherwise one of the system wide error codes.
+ */
+ TInt Construct(TInt aOsAsid, TLinAddr aStart, TLinAddr aEnd);
+
+ /**
+ Wait on the mutex used to protect virtual address allocation and the
+ addition/removal of memory mappings. This is only used internally by
+ the DAddressSpace methods.
+ */
+ void Lock();
+
+ /**
+ Reverse the action of #Lock.
+ */
+ void Unlock();
+
+ /**
+ In debug builds, dump information about each mapping in the address to the
+ kernel trace port.
+ */
+ void Dump();
+
+private:
+ /**
+ The OS ASID value for this address space.
+ This is its index in the array #AddressSpace.
+ */
+ TInt iOsAsid;
+
+ /**
+ Lock currently being used to protect virtual address allocation (#iVirtualAllocator)
+ and changes to the mapping container (#iMappings).
+ */
+ DMutex* iLock;
+
+ /**
+ Container containing all mappings added to this address space.
+ */
+ RAddressedContainer iMappings;
+
+ /**
+ Allocator object for virtual addresses within the address space.
+ */
+ RVirtualAllocator iVirtualAllocator;
+
+private:
+ /**
+ Allocator for virtual addresses within the global address region for use by user-side code.
+
+ This is used by #AllocateUserGlobalVirtualMemory and the lock mutex for the
+ kernel's address space is used to protect access.
+ */
+ static RVirtualAllocator UserGlobalVirtualAllocator;
+
+ /**
+ Allocator for virtual addresses for use by memory which should appear at
+ the same address in all user-side processes which map it.
+
+ This is used by AllocateUserCommonVirtualMemory and the lock mutex for the
+ kernel's address space is used to protect access.
+ */
+ static RBackwardsVirtualAllocator UserCommonVirtualAllocator;
+ };
+
+
+/**
+Array of all address spaces. An OS Address Space ID (OS ASID) can be used to
+index this array to find the corresponding DAddressSpace object.
+*/
+extern DAddressSpace* AddressSpace[];
+
+
+#endif