kernel/eka/memmodel/epoc/direct/mutils.cpp
changeset 0 a41df078684a
child 13 46fffbe7b5a7
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 1994-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 // eka\memmodel\epoc\direct\mutils.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <memmodel.h>
       
    19 #include "execs.h"
       
    20 #include "cache_maintenance.h"
       
    21 #include <kernel/cache.h>
       
    22 
       
    23 #ifdef BTRACE_KERNEL_MEMORY
       
    24 TInt   Epoc::DriverAllocdPhysRam = 0;
       
    25 #endif
       
    26 
       
    27 void RHeapK::Mutate(TInt aOffset, TInt aMaxLength)
       
    28 //
       
    29 // Used by the kernel to mutate a fixed heap into a chunk heap.
       
    30 //
       
    31 	{
       
    32 	(void)aOffset;
       
    33 	(void)aMaxLength;
       
    34 	}
       
    35 
       
    36 void MM::Panic(MM::TMemModelPanic aPanic)
       
    37 	{
       
    38 	Kern::Fault("MemModel", aPanic);
       
    39 	}
       
    40 
       
    41 TInt M::PageSizeInBytes()
       
    42 	{
       
    43 	return MM::RamBlockSize;
       
    44 	}
       
    45 
       
    46 EXPORT_C TUint32 Kern::RoundToPageSize(TUint32 aSize)
       
    47 	{
       
    48 	return MM::RoundToBlockSize(aSize);
       
    49 	}
       
    50 
       
    51 EXPORT_C TUint32 Kern::RoundToChunkSize(TUint32 aSize)
       
    52 	{
       
    53 	return MM::RoundToBlockSize(aSize);
       
    54 	}
       
    55 
       
    56 
       
    57 /**
       
    58 Allows the variant/BSP to specify the details of the RAM zones.
       
    59 This should to be invoked by the variant in its implementation of
       
    60 the pure virtual function Asic::Init1().
       
    61 
       
    62 There are some limitations to the how RAM zones can be specified:
       
    63 - Each RAM zone's address space must be distinct and not overlap with any 
       
    64 other RAM zone's address space
       
    65 - Each RAM zone's address space must have a size that is multiples of the 
       
    66 ASIC's MMU small page size and be aligned to the ASIC's MMU small page size, 
       
    67 usually 4KB on ARM MMUs.
       
    68 - When taken together all of the RAM zones must cover the whole of the physical RAM
       
    69 address space as specified by the bootstrap in the SuperPage members iTotalRamSize
       
    70 and iRamBootData;.
       
    71 - There can be no more than KMaxRamZones RAM zones specified by the base port
       
    72 
       
    73 Note the verification of the RAM zone data is not performed here but by the ram 
       
    74 allocator later in the boot up sequence.  This is because it is only possible to
       
    75 verify the zone data once the physical RAM configuration has been read from 
       
    76 the super page.  Any verification errors will result in a "RAM-ALLOC" panic 
       
    77 faulting the kernel during initialisation.
       
    78 
       
    79 @param aZones Pointer to an array of SRamZone structs containing each zone's details
       
    80 The end of the array is specified by an element with iSize==0.  The array must 
       
    81 remain in memory at least until the kernel has successfully booted.
       
    82 
       
    83 @param aCallback Pointer to call back function that kernel may invoke to request
       
    84 one of the opeartions specified from enum TRamZoneOp is performed
       
    85 
       
    86 @return KErrNone if successful, otherwise one of the system wide error codes
       
    87 */
       
    88 EXPORT_C TInt Epoc::SetRamZoneConfig(const SRamZone* /*aZones*/, TRamZoneCallback /*aCallback*/)
       
    89 	{// RAM zones not supported for this memory model
       
    90 	return KErrNotSupported;
       
    91 	}
       
    92 
       
    93 
       
    94 /**
       
    95 Gets the current count of a paricular RAM zone's free and allocated pages.
       
    96 
       
    97 @param aId The ID of the RAM zone to enquire about
       
    98 @param aPageData If successful, on return this will contain the page counts
       
    99 
       
   100 @return KErrNone if successful, KErrArgument if a RAM zone of aId is not found or
       
   101 one of the system wide error codes 
       
   102 */
       
   103 EXPORT_C TInt Epoc::GetRamZonePageCount(TUint /*aId*/, SRamZonePageCount& /*aPageData*/)
       
   104 	{// RAM zones not supported for this memory model
       
   105 	return KErrNotSupported;
       
   106 	}
       
   107 
       
   108 /**
       
   109 Modify the specified RAM zone's flags.
       
   110 
       
   111 This allows the BSP or device driver to configure which type of pages, if any,
       
   112 can be allocated into a RAM zone by the system.
       
   113 
       
   114 Note updating a RAM zone's flags can result in
       
   115 	1 - memory allocations failing despite there being enough free RAM in the system.
       
   116 	2 - the methods TRamDefragRequest::EmptyRamZone(), TRamDefragRequest::ClaimRamZone()
       
   117 	or TRamDefragRequest::DefragRam() never succeeding.
       
   118 
       
   119 The flag masks KRamZoneFlagDiscardOnly, KRamZoneFlagMovAndDisOnly and KRamZoneFlagNoAlloc
       
   120 are intended to be used with this method.
       
   121 
       
   122 
       
   123 @param aId			The ID of the RAM zone to modify.
       
   124 @param aClearFlags	The bit flags to clear, each of which must already be set on the RAM zone.
       
   125 @param aSetFlags	The bit flags to set.
       
   126 
       
   127 @return KErrNone on success, KErrArgument if the RAM zone of aId not found
       
   128 or if any of aClearFlags are not already set.
       
   129 */
       
   130 EXPORT_C TInt Epoc::ModifyRamZoneFlags(TUint /*aId*/, TUint /*aClearMask*/, TUint /*aSetMask*/)
       
   131 	{// RAM zone not supported for this memory model
       
   132 	return KErrNotSupported;
       
   133 	}
       
   134 
       
   135 /**
       
   136 	@pre	Call in a thread context.
       
   137 	@pre	Interrupts must be enabled.
       
   138 	@pre	Kernel must be unlocked.
       
   139 	@pre    No fast mutex can be held.
       
   140 	@pre	Calling thread must be in a critical section.
       
   141  */
       
   142 EXPORT_C TInt Epoc::AllocShadowPage(TLinAddr aRomAddr)
       
   143 	{
       
   144 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::AllocShadowPage");
       
   145 	return KErrNotSupported;
       
   146 	}
       
   147 
       
   148 /**
       
   149 	@pre	Call in a thread context.
       
   150 	@pre	Interrupts must be enabled.
       
   151 	@pre	Kernel must be unlocked.
       
   152 	@pre    No fast mutex can be held.
       
   153 	@pre	Calling thread must be in a critical section.
       
   154  */
       
   155 EXPORT_C TInt Epoc::FreeShadowPage(TLinAddr aRomAddr)
       
   156 	{
       
   157 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::FreeShadowPage");
       
   158 	return KErrNotSupported;
       
   159 	}
       
   160 
       
   161 /**
       
   162 @pre Calling thread must be in a critical section.
       
   163 @pre Interrupts must be enabled.
       
   164 @pre Kernel must be unlocked.
       
   165 @pre No fast mutex can be held.
       
   166 @pre Call in a thread context.
       
   167 */
       
   168 EXPORT_C TInt Epoc::CopyToShadowMemory(TLinAddr /*aDest*/, TLinAddr /*aSrc*/, TUint32 /*aLength*/)
       
   169 	{
       
   170 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::CopyToShadowPage");
       
   171 	return KErrNotSupported;
       
   172 	}
       
   173 
       
   174 /**
       
   175 	@pre	Call in a thread context.
       
   176 	@pre	Interrupts must be enabled.
       
   177 	@pre	Kernel must be unlocked.
       
   178 	@pre    No fast mutex can be held.
       
   179 	@pre	Calling thread must be in a critical section.
       
   180  */
       
   181 EXPORT_C TInt Epoc::FreezeShadowPage(TLinAddr aRomAddr)
       
   182 	{
       
   183 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::FreezeShadowPage");
       
   184 	return KErrNotSupported;
       
   185 	}
       
   186 
       
   187 /**
       
   188 	@pre	Call in a thread context.
       
   189 	@pre	Interrupts must be enabled.
       
   190 	@pre	Kernel must be unlocked.
       
   191 	@pre    No fast mutex can be held.
       
   192 	@pre	Calling thread must be in a critical section.
       
   193  */
       
   194 EXPORT_C TInt Epoc::AllocPhysicalRam(TInt aSize, TPhysAddr& aPhysAddr, TInt aAlign)
       
   195 	{
       
   196 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::AllocPhysicalRam");
       
   197 	MM::WaitRamAlloc();
       
   198 	TLinAddr lin;
       
   199 	TInt r=MM::AllocContiguousRegion(lin, aSize, aAlign);
       
   200 	if (r!=KErrNone)
       
   201 		MM::AllocFailed=ETrue;
       
   202 	else
       
   203 		{
       
   204 		aPhysAddr = LinearToPhysical(lin);
       
   205 #if defined(__CPU_HAS_CACHE) && !defined(__CPU_X86)
       
   206 		CacheMaintenance::MemoryToReuse(lin, aSize);
       
   207 #endif
       
   208 #ifdef BTRACE_KERNEL_MEMORY
       
   209 		TUint size = Kern::RoundToPageSize(aSize);
       
   210 		BTrace8(BTrace::EKernelMemory, BTrace::EKernelMemoryDrvPhysAlloc, size, aPhysAddr);
       
   211 		Epoc::DriverAllocdPhysRam += size;
       
   212 #endif
       
   213 		}
       
   214 	MM::SignalRamAlloc();
       
   215 	return r;
       
   216 	}
       
   217 
       
   218 /**
       
   219 	@pre	Call in a thread context.
       
   220 	@pre	Interrupts must be enabled.
       
   221 	@pre	Kernel must be unlocked.
       
   222 	@pre    No fast mutex can be held.
       
   223 	@pre	Calling thread must be in a critical section.
       
   224  */
       
   225 EXPORT_C TInt Epoc::FreePhysicalRam(TPhysAddr aPhysAddr, TInt aSize)
       
   226 	{
       
   227 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::FreePhysicalRam");
       
   228 	MM::WaitRamAlloc();
       
   229 #ifndef __CPU_HAS_MMU
       
   230 	MM::FreeRegion(aPhysAddr, aSize);
       
   231 #else
       
   232 	TInt bn = MM::BlockNumber(aPhysAddr);
       
   233 	TInt bn0 = MM::BlockNumber(MM::UserDataSectionBase);
       
   234 	TLinAddr lin = TLinAddr((bn - bn0)<<MM::RamBlockShift) + MM::UserDataSectionBase;
       
   235 	MM::FreeRegion(lin, aSize);
       
   236 #endif
       
   237 #ifdef BTRACE_KERNEL_MEMORY
       
   238 	TUint size = Kern::RoundToPageSize(aSize);
       
   239 	BTrace8(BTrace::EKernelMemory, BTrace::EKernelMemoryDrvPhysFree, aPhysAddr, size);
       
   240 	Epoc::DriverAllocdPhysRam -= size;
       
   241 #endif
       
   242 	MM::SignalRamAlloc();
       
   243 	return KErrNone;
       
   244 	}
       
   245 
       
   246 /**
       
   247 Allocate a block of physically contiguous RAM with a physical address aligned
       
   248 to a specified power of 2 boundary from the specified zone.
       
   249 When the RAM is no longer required it should be freed using Epoc::FreePhysicalRam().
       
   250 
       
   251 Note that this method only repsects the KRamZoneFlagNoAlloc flag and will always attempt
       
   252 to allocate regardless of whether the other flags are set for the specified RAM zones 
       
   253 or not.
       
   254 
       
   255 When the RAM is no longer required it should be freed using Epoc::FreePhysicalRam().
       
   256 
       
   257 @param 	aZoneId		The ID of the zone to attempt to allocate from.
       
   258 @param	aSize		The size in bytes of the required block. The specified size
       
   259 					is rounded up to the page size, since only whole pages of
       
   260 					physical RAM can be allocated.
       
   261 @param	aPhysAddr	Receives the physical address of the base of the block on
       
   262 					successful allocation.
       
   263 @param	aAlign		Specifies the number of least significant bits of the
       
   264 					physical address which are required to be zero. If a value
       
   265 					less than log2(page size) is specified, page alignment is
       
   266 					assumed. Pass 0 for aAlign if there are no special alignment
       
   267 					constraints (other than page alignment).
       
   268 @return	KErrNone if the allocation was successful.
       
   269 		KErrNoMemory if a sufficiently large physically contiguous block of free
       
   270 		RAM	with the specified alignment could not be found within the specified 
       
   271 		zone.
       
   272 		KErrArgument if a RAM zone of the specified ID can't be found or if the
       
   273 		RAM zone has a total number of physical pages which is less than those 
       
   274 		requested for the allocation.
       
   275 
       
   276 @pre Calling thread must be in a critical section.
       
   277 @pre Interrupts must be enabled.
       
   278 @pre Kernel must be unlocked.
       
   279 @pre No fast mutex can be held.
       
   280 @pre Call in a thread context.
       
   281 @pre Can be used in a device driver.
       
   282 */
       
   283 EXPORT_C TInt Epoc::ZoneAllocPhysicalRam(TUint aZoneId, TInt aSize, TPhysAddr& aPhysAddr, TInt aAlign)
       
   284 	{
       
   285 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::ZoneAllocPhysicalRam");
       
   286 	return KErrNotSupported;
       
   287 	}
       
   288 
       
   289 
       
   290 /**
       
   291 Allocate a block of physically contiguous RAM with a physical address aligned
       
   292 to a specified power of 2 boundary from the specified RAM zones.
       
   293 When the RAM is no longer required it should be freed using Epoc::FreePhysicalRam().
       
   294 
       
   295 RAM will be allocated into the RAM zones in the order they are specified in the 
       
   296 aZoneId parameter. If the contiguous allocations are intended to span RAM zones 
       
   297 when required then aZoneId should be listed with the RAM zones in ascending 
       
   298 physical address order.
       
   299 
       
   300 Note that this method only repsects the KRamZoneFlagNoAlloc flag and will always attempt
       
   301 to allocate regardless of whether the other flags are set for the specified RAM zones 
       
   302 or not.
       
   303 
       
   304 When the RAM is no longer required it should be freed using Epoc::FreePhysicalRam().
       
   305 
       
   306 @param 	aZoneIdList	A pointer to an array of RAM zone IDs of the RAM zones to 
       
   307 					attempt to allocate from.
       
   308 @param 	aZoneIdCount The number of RAM zone IDs contained in aZoneIdList.
       
   309 @param	aSize		The size in bytes of the required block. The specified size
       
   310 					is rounded up to the page size, since only whole pages of
       
   311 					physical RAM can be allocated.
       
   312 @param	aPhysAddr	Receives the physical address of the base of the block on
       
   313 					successful allocation.
       
   314 @param	aAlign		Specifies the number of least significant bits of the
       
   315 					physical address which are required to be zero. If a value
       
   316 					less than log2(page size) is specified, page alignment is
       
   317 					assumed. Pass 0 for aAlign if there are no special alignment
       
   318 					constraints (other than page alignment).
       
   319 @return	KErrNone if the allocation was successful.
       
   320 		KErrNoMemory if a sufficiently large physically contiguous block of free
       
   321 		RAM	with the specified alignment could not be found within the specified 
       
   322 		zone.
       
   323 		KErrArgument if a RAM zone of a specified ID can't be found or if the
       
   324 		RAM zones have a total number of physical pages which is less than those 
       
   325 		requested for the allocation.
       
   326 
       
   327 @pre Calling thread must be in a critical section.
       
   328 @pre Interrupts must be enabled.
       
   329 @pre Kernel must be unlocked.
       
   330 @pre No fast mutex can be held.
       
   331 @pre Call in a thread context.
       
   332 @pre Can be used in a device driver.
       
   333 */
       
   334 EXPORT_C TInt Epoc::ZoneAllocPhysicalRam(TUint* aZoneIdList, TUint aZoneIdCount, TInt aSize, TPhysAddr& aPhysAddr, TInt aAlign)
       
   335 	{
       
   336 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::ZoneAllocPhysicalRam");
       
   337 	return KErrNotSupported;
       
   338 	}
       
   339 
       
   340 
       
   341 /**
       
   342 Attempt to allocate discontiguous RAM pages.
       
   343 
       
   344 When the RAM is no longer required it should be freed using Epoc::FreePhysicalRam().
       
   345 
       
   346 @param	aNumPages	The number of discontiguous pages required to be allocated
       
   347 @param	aPageList	This should be a pointer to a previously allocated array of
       
   348 					aNumPages TPhysAddr elements.  On a succesful allocation it 
       
   349 					will receive the physical addresses of each page allocated.
       
   350 
       
   351 @return	KErrNone if the allocation was successful.
       
   352 		KErrNoMemory if the requested number of pages can't be allocated
       
   353 
       
   354 @pre Calling thread must be in a critical section.
       
   355 @pre Interrupts must be enabled.
       
   356 @pre Kernel must be unlocked.
       
   357 @pre No fast mutex can be held.
       
   358 @pre Call in a thread context.
       
   359 @pre Can be used in a device driver.
       
   360 */
       
   361 EXPORT_C TInt Epoc::AllocPhysicalRam(TInt aNumPages, TPhysAddr* aPageList)
       
   362 	{
       
   363 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL, "Epoc::AllocPhysicalRam");
       
   364 	return KErrNotSupported;
       
   365 	}
       
   366 
       
   367 
       
   368 /**
       
   369 Attempt to allocate discontiguous RAM pages from the specified zone.
       
   370 
       
   371 Note that this method only repsects the KRamZoneFlagNoAlloc flag and will always attempt
       
   372 to allocate regardless of whether the other flags are set for the specified RAM zones 
       
   373 or not.
       
   374 
       
   375 When the RAM is no longer required it should be freed using Epoc::FreePhysicalRam().
       
   376 
       
   377 @param 	aZoneId		The ID of the zone to attempt to allocate from.
       
   378 @param	aNumPages	The number of discontiguous pages required to be allocated 
       
   379 					from the specified zone.
       
   380 @param	aPageList	This should be a pointer to a previously allocated array of
       
   381 					aNumPages TPhysAddr elements.  On a succesful 
       
   382 					allocation it will receive the physical addresses of each 
       
   383 					page allocated.
       
   384 @return	KErrNone if the allocation was successful.
       
   385 		KErrNoMemory if the requested number of pages can't be allocated from the 
       
   386 		specified zone.
       
   387 		KErrArgument if a RAM zone of the specified ID can't be found or if the
       
   388 		RAM zone has a total number of physical pages which is less than those 
       
   389 		requested for the allocation.
       
   390 
       
   391 @pre Calling thread must be in a critical section.
       
   392 @pre Interrupts must be enabled.
       
   393 @pre Kernel must be unlocked.
       
   394 @pre No fast mutex can be held.
       
   395 @pre Call in a thread context.
       
   396 @pre Can be used in a device driver.
       
   397 */
       
   398 EXPORT_C TInt Epoc::ZoneAllocPhysicalRam(TUint aZoneId, TInt aNumPages, TPhysAddr* aPageList)
       
   399 	{
       
   400 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL, "Epoc::ZoneAllocPhysicalRam");
       
   401 	return KErrNotSupported;
       
   402 	}
       
   403 
       
   404 
       
   405 /**
       
   406 Attempt to allocate discontiguous RAM pages from the specified RAM zones.
       
   407 The RAM pages will be allocated into the RAM zones in the order that they are specified 
       
   408 in the aZoneId parameter, the RAM zone preferences will be ignored.
       
   409 
       
   410 Note that this method only repsects the KRamZoneFlagNoAlloc flag and will always attempt
       
   411 to allocate regardless of whether the other flags are set for the specified RAM zones 
       
   412 or not.
       
   413 
       
   414 When the RAM is no longer required it should be freed using Epoc::FreePhysicalRam().
       
   415 
       
   416 @param 	aZoneIdList	A pointer to an array of RAM zone IDs of the RAM zones to 
       
   417 					attempt to allocate from.
       
   418 @param	aZoneIdCount The number of RAM zone IDs pointed to by aZoneIdList.
       
   419 @param	aNumPages	The number of discontiguous pages required to be allocated 
       
   420 					from the specified zone.
       
   421 @param	aPageList	This should be a pointer to a previously allocated array of
       
   422 					aNumPages TPhysAddr elements.  On a succesful 
       
   423 					allocation it will receive the physical addresses of each 
       
   424 					page allocated.
       
   425 @return	KErrNone if the allocation was successful.
       
   426 		KErrNoMemory if the requested number of pages can't be allocated from the 
       
   427 		specified zone.
       
   428 		KErrArgument if a RAM zone of a specified ID can't be found or if the
       
   429 		RAM zones have a total number of physical pages which is less than those 
       
   430 		requested for the allocation.
       
   431 
       
   432 @pre Calling thread must be in a critical section.
       
   433 @pre Interrupts must be enabled.
       
   434 @pre Kernel must be unlocked.
       
   435 @pre No fast mutex can be held.
       
   436 @pre Call in a thread context.
       
   437 @pre Can be used in a device driver.
       
   438 */
       
   439 EXPORT_C TInt Epoc::ZoneAllocPhysicalRam(TUint* aZoneIdList, TUint aZoneIdCount, TInt aNumPages, TPhysAddr* aPageList)
       
   440 	{
       
   441 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL, "Epoc::ZoneAllocPhysicalRam");
       
   442 	return KErrNotSupported;
       
   443 	}
       
   444 
       
   445 
       
   446 /**
       
   447 Free a number of physical RAM pages that were previously allocated using
       
   448 Epoc::AllocPhysicalRam().
       
   449 
       
   450 @param	aNumPages	The number of pages to be freed.
       
   451 @param	aPhysAddr	An array of aNumPages TPhysAddr elements.  Where each element
       
   452 					should contain the physical address of each page to be freed.
       
   453 					This must be the same set of addresses as those returned by a 
       
   454 					previous call to Epoc::AllocPhysicalRam() or 
       
   455 					Epoc::ZoneAllocPhysicalRam().
       
   456 @return	KErrNone if the operation was successful.
       
   457 		KErrArgument if one or more of the physical addresses specified is not 
       
   458 					a valid physical RAM address.
       
   459 		KErrGeneral if the physical addresses specified are all valid
       
   460 					physical RAM addresses but some of them had not
       
   461 					been previously allocated.
       
   462 @pre Calling thread must be in a critical section.
       
   463 @pre Interrupts must be enabled.
       
   464 @pre Kernel must be unlocked.
       
   465 @pre No fast mutex can be held.
       
   466 @pre Call in a thread context.
       
   467 @pre Can be used in a device driver.
       
   468 */
       
   469 EXPORT_C TInt Epoc::FreePhysicalRam(TInt aNumPages, TPhysAddr* aPageList)
       
   470 	{
       
   471 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::FreePhysicalRam");
       
   472 	return KErrNotSupported;
       
   473 	}
       
   474 
       
   475 
       
   476 /**
       
   477 	@pre	Call in a thread context.
       
   478 	@pre	Interrupts must be enabled.
       
   479 	@pre	Kernel must be unlocked.
       
   480 	@pre    No fast mutex can be held.
       
   481 	@pre	Calling thread must be in a critical section.
       
   482  */
       
   483 EXPORT_C TInt Epoc::ClaimPhysicalRam(TPhysAddr aPhysAddr, TInt aSize)
       
   484 	{
       
   485 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::ClaimPhysicalRam");
       
   486 	MM::WaitRamAlloc();
       
   487 #ifndef __CPU_HAS_MMU
       
   488 	TInt r=MM::ClaimRegion(aPhysAddr, aSize);
       
   489 #else
       
   490 	TInt bn = MM::BlockNumber(aPhysAddr);
       
   491 	TInt bn0 = MM::BlockNumber(MM::UserDataSectionBase);
       
   492 	TLinAddr lin = TLinAddr((bn - bn0)<<MM::RamBlockShift) + MM::UserDataSectionBase;
       
   493 	TInt r=MM::ClaimRegion(lin, aSize);
       
   494 #endif
       
   495 	MM::SignalRamAlloc();
       
   496 	return r;
       
   497 	}
       
   498 
       
   499 void ExecHandler::UnlockRamDrive()
       
   500 	{
       
   501 	}
       
   502 
       
   503 EXPORT_C void TInternalRamDrive::Unlock()
       
   504 	{
       
   505 	}
       
   506 
       
   507 EXPORT_C void TInternalRamDrive::Lock()
       
   508 	{
       
   509 	}
       
   510 
       
   511 void MM::WaitRamAlloc()
       
   512 	{
       
   513 	Kern::MutexWait(*RamAllocatorMutex);
       
   514 	if (RamAllocatorMutex->iHoldCount==1)
       
   515 		{
       
   516 		MM::InitialFreeMemory=Kern::FreeRamInBytes();
       
   517 		MM::AllocFailed=EFalse;
       
   518 		}
       
   519 	}
       
   520 
       
   521 void MM::SignalRamAlloc()
       
   522 	{
       
   523 	if (RamAllocatorMutex->iHoldCount>1)
       
   524 		{
       
   525 		Kern::MutexSignal(*RamAllocatorMutex);
       
   526 		return;
       
   527 		}
       
   528 	TInt initial=MM::InitialFreeMemory;
       
   529 	TBool failed=MM::AllocFailed;
       
   530 	TInt final=Kern::FreeRamInBytes();
       
   531 	Kern::MutexSignal(*RamAllocatorMutex);
       
   532 	K::CheckFreeMemoryLevel(initial,final,failed);
       
   533 	}
       
   534 
       
   535 EXPORT_C TInt TInternalRamDrive::MaxSize()
       
   536 	{
       
   537 	return PP::RamDriveMaxSize;
       
   538 	}
       
   539 
       
   540 void M::FsRegisterThread()
       
   541 	{
       
   542 	}
       
   543 
       
   544 void M::BTracePrime(TUint aCategory)
       
   545 	{
       
   546 	(void)aCategory;
       
   547 #ifdef BTRACE_KERNEL_MEMORY	
       
   548 	// Must check for -1 as that is the default value of aCategory for
       
   549 	// BTrace::Prime() which is intended to prime all categories that are 
       
   550 	// currently enabled via a single invocation of BTrace::Prime().
       
   551 	if(aCategory==BTrace::EKernelMemory || (TInt)aCategory == -1)
       
   552 		{
       
   553 		BTrace4(BTrace::EKernelMemory,BTrace::EKernelMemoryInitialFree,TheSuperPage().iTotalRamSize);
       
   554 		BTrace4(BTrace::EKernelMemory,BTrace::EKernelMemoryCurrentFree,Kern::FreeRamInBytes());
       
   555 		BTrace8(BTrace::EKernelMemory,BTrace::EKernelMemoryDrvPhysAlloc, Epoc::DriverAllocdPhysRam, -1);
       
   556 		}
       
   557 #endif
       
   558 	}
       
   559 
       
   560 EXPORT_C DDemandPagingLock::DDemandPagingLock()
       
   561 	: iLockedPageCount(0)
       
   562 	{
       
   563 	}
       
   564 
       
   565 EXPORT_C TInt DDemandPagingLock::Alloc(TInt /*aSize*/)
       
   566 	{
       
   567 	return KErrNone;
       
   568 	}
       
   569 
       
   570 EXPORT_C TBool DDemandPagingLock::Lock(DThread* /*aThread*/, TLinAddr /*aStart*/, TInt /*aSize*/)
       
   571 	{
       
   572 	return EFalse;
       
   573 	}
       
   574 
       
   575 EXPORT_C void DDemandPagingLock::DoUnlock()
       
   576 	{
       
   577 	}
       
   578 
       
   579 EXPORT_C void DDemandPagingLock::Free()
       
   580 	{
       
   581 	}
       
   582 
       
   583 EXPORT_C TInt Kern::InstallPagingDevice(DPagingDevice* aDevice)
       
   584 	{
       
   585 	return KErrNotSupported;
       
   586 	}
       
   587 
       
   588 // Dummy implementation of kernel pin APIs
       
   589 
       
   590 class TVirtualPinObject
       
   591 	{	
       
   592 	};
       
   593 
       
   594 TInt M::CreateVirtualPinObject(TVirtualPinObject*& aPinObject)
       
   595 	{
       
   596 	aPinObject = new TVirtualPinObject;
       
   597 	return aPinObject != NULL ? KErrNone : KErrNoMemory;
       
   598 	}
       
   599 
       
   600 TInt M::PinVirtualMemory(TVirtualPinObject* aPinObject, TLinAddr, TUint, DThread*)
       
   601 	{
       
   602 	__ASSERT_DEBUG(aPinObject, K::Fault(K::EVirtualPinObjectBad));
       
   603 	(void)aPinObject;
       
   604 	return KErrNone;
       
   605 	}
       
   606 
       
   607 TInt M::CreateAndPinVirtualMemory(TVirtualPinObject*& aPinObject, TLinAddr, TUint)
       
   608 	{
       
   609 	aPinObject = 0;
       
   610 	return KErrNone;
       
   611 	}
       
   612 
       
   613 void M::UnpinVirtualMemory(TVirtualPinObject* aPinObject)
       
   614 	{
       
   615 	__ASSERT_DEBUG(aPinObject, K::Fault(K::EVirtualPinObjectBad));
       
   616 	(void)aPinObject;
       
   617 	}
       
   618 
       
   619 void M::DestroyVirtualPinObject(TVirtualPinObject*& aPinObject)
       
   620 	{
       
   621 	TVirtualPinObject* object = (TVirtualPinObject*)__e32_atomic_swp_ord_ptr(&aPinObject, 0);
       
   622 	if (object)
       
   623 		Kern::AsyncFree(object);
       
   624 	}
       
   625 
       
   626 TInt M::CreatePhysicalPinObject(TPhysicalPinObject*& aPinObject)
       
   627 	{
       
   628 	return KErrNotSupported;
       
   629 	}
       
   630 
       
   631 TInt M::PinPhysicalMemory(TPhysicalPinObject*, TLinAddr, TUint, TBool, TPhysAddr& , TPhysAddr*, TUint32&, TUint&, DThread*)
       
   632 	{
       
   633 	K::Fault(K::EPhysicalPinObjectBad);
       
   634 	return KErrNone;
       
   635 	}
       
   636 
       
   637 void M::UnpinPhysicalMemory(TPhysicalPinObject* aPinObject)
       
   638 	{
       
   639 	K::Fault(K::EPhysicalPinObjectBad);
       
   640 	}
       
   641 
       
   642 void M::DestroyPhysicalPinObject(TPhysicalPinObject*& aPinObject)
       
   643 	{
       
   644 	K::Fault(K::EPhysicalPinObjectBad);
       
   645 	}
       
   646 
       
   647 // Misc DPagingDevice methods
       
   648 
       
   649 EXPORT_C void DPagingDevice::NotifyIdle()
       
   650 	{
       
   651 	// Not used on this memory model
       
   652 	}
       
   653 
       
   654 EXPORT_C void DPagingDevice::NotifyBusy()
       
   655 	{
       
   656 	// Not used on this memory model
       
   657 	}
       
   658 
       
   659 EXPORT_C TInt Cache::SyncPhysicalMemoryBeforeDmaWrite(TPhysAddr* , TUint , TUint , TUint , TUint32 )
       
   660 	{
       
   661 	CHECK_PRECONDITIONS(MASK_THREAD_STANDARD,"Cache::SyncPhysicalMemoryBeforeDmaWrite");
       
   662 	return KErrNotSupported;
       
   663 	}
       
   664 
       
   665 EXPORT_C TInt Cache::SyncPhysicalMemoryBeforeDmaRead(TPhysAddr* , TUint , TUint , TUint , TUint32 )
       
   666 	{
       
   667 	CHECK_PRECONDITIONS(MASK_THREAD_STANDARD,"Cache::SyncPhysicalMemoryBeforeDmaRead");
       
   668 	return KErrNotSupported;
       
   669 	}
       
   670 EXPORT_C TInt Cache::SyncPhysicalMemoryAfterDmaRead(TPhysAddr* , TUint , TUint , TUint , TUint32 )
       
   671 	{
       
   672 	CHECK_PRECONDITIONS(MASK_THREAD_STANDARD,"Cache::SyncPhysicalMemoryAfterDmaRead");
       
   673 	return KErrNotSupported;
       
   674 	}