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