1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/memmodel/epoc/direct/mutils.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,701 @@
1.4 +// Copyright (c) 1994-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 +// eka\memmodel\epoc\direct\mutils.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include <memmodel.h>
1.22 +#include "execs.h"
1.23 +#include "cache_maintenance.h"
1.24 +#include <kernel/cache.h>
1.25 +
1.26 +#ifdef BTRACE_KERNEL_MEMORY
1.27 +TInt Epoc::DriverAllocdPhysRam = 0;
1.28 +#endif
1.29 +
1.30 +void RHeapK::Mutate(TInt aOffset, TInt aMaxLength)
1.31 +//
1.32 +// Used by the kernel to mutate a fixed heap into a chunk heap.
1.33 +//
1.34 + {
1.35 + (void)aOffset;
1.36 + (void)aMaxLength;
1.37 + }
1.38 +
1.39 +void MM::Panic(MM::TMemModelPanic aPanic)
1.40 + {
1.41 + Kern::Fault("MemModel", aPanic);
1.42 + }
1.43 +
1.44 +TInt M::PageSizeInBytes()
1.45 + {
1.46 + return MM::RamBlockSize;
1.47 + }
1.48 +
1.49 +EXPORT_C TUint32 Kern::RoundToPageSize(TUint32 aSize)
1.50 + {
1.51 + return MM::RoundToBlockSize(aSize);
1.52 + }
1.53 +
1.54 +EXPORT_C TUint32 Kern::RoundToChunkSize(TUint32 aSize)
1.55 + {
1.56 + return MM::RoundToBlockSize(aSize);
1.57 + }
1.58 +
1.59 +
1.60 +/**
1.61 +Allows the variant/BSP to specify the details of the RAM zones.
1.62 +This should to be invoked by the variant in its implementation of
1.63 +the pure virtual function Asic::Init1().
1.64 +
1.65 +There are some limitations to the how RAM zones can be specified:
1.66 +- Each RAM zone's address space must be distinct and not overlap with any
1.67 +other RAM zone's address space
1.68 +- Each RAM zone's address space must have a size that is multiples of the
1.69 +ASIC's MMU small page size and be aligned to the ASIC's MMU small page size,
1.70 +usually 4KB on ARM MMUs.
1.71 +- When taken together all of the RAM zones must cover the whole of the physical RAM
1.72 +address space as specified by the bootstrap in the SuperPage members iTotalRamSize
1.73 +and iRamBootData;.
1.74 +- There can be no more than KMaxRamZones RAM zones specified by the base port
1.75 +
1.76 +Note the verification of the RAM zone data is not performed here but by the ram
1.77 +allocator later in the boot up sequence. This is because it is only possible to
1.78 +verify the zone data once the physical RAM configuration has been read from
1.79 +the super page. Any verification errors will result in a "RAM-ALLOC" panic
1.80 +faulting the kernel during initialisation.
1.81 +
1.82 +@param aZones Pointer to an array of SRamZone structs containing each zone's details
1.83 +The end of the array is specified by an element with iSize==0. The array must
1.84 +remain in memory at least until the kernel has successfully booted.
1.85 +
1.86 +@param aCallback Pointer to call back function that kernel may invoke to request
1.87 +one of the opeartions specified from enum TRamZoneOp is performed
1.88 +
1.89 +@return KErrNone if successful, otherwise one of the system wide error codes
1.90 +*/
1.91 +EXPORT_C TInt Epoc::SetRamZoneConfig(const SRamZone* /*aZones*/, TRamZoneCallback /*aCallback*/)
1.92 + {// RAM zones not supported for this memory model
1.93 + return KErrNotSupported;
1.94 + }
1.95 +
1.96 +
1.97 +/**
1.98 +Gets the current count of a paricular RAM zone's free and allocated pages.
1.99 +
1.100 +@param aId The ID of the RAM zone to enquire about
1.101 +@param aPageData If successful, on return this will contain the page counts
1.102 +
1.103 +@return KErrNone if successful, KErrArgument if a RAM zone of aId is not found or
1.104 +one of the system wide error codes
1.105 +*/
1.106 +EXPORT_C TInt Epoc::GetRamZonePageCount(TUint /*aId*/, SRamZonePageCount& /*aPageData*/)
1.107 + {// RAM zones not supported for this memory model
1.108 + return KErrNotSupported;
1.109 + }
1.110 +
1.111 +/**
1.112 +Modify the specified RAM zone's flags.
1.113 +
1.114 +This allows the BSP or device driver to configure which type of pages, if any,
1.115 +can be allocated into a RAM zone by the system.
1.116 +
1.117 +Note updating a RAM zone's flags can result in
1.118 + 1 - memory allocations failing despite there being enough free RAM in the system.
1.119 + 2 - the methods TRamDefragRequest::EmptyRamZone(), TRamDefragRequest::ClaimRamZone()
1.120 + or TRamDefragRequest::DefragRam() never succeeding.
1.121 +
1.122 +The flag masks KRamZoneFlagDiscardOnly, KRamZoneFlagMovAndDisOnly and KRamZoneFlagNoAlloc
1.123 +are intended to be used with this method.
1.124 +
1.125 +
1.126 +@param aId The ID of the RAM zone to modify.
1.127 +@param aClearFlags The bit flags to clear, each of which must already be set on the RAM zone.
1.128 +@param aSetFlags The bit flags to set.
1.129 +
1.130 +@return KErrNone on success, KErrArgument if the RAM zone of aId not found
1.131 +or if any of aClearFlags are not already set.
1.132 +*/
1.133 +EXPORT_C TInt Epoc::ModifyRamZoneFlags(TUint /*aId*/, TUint /*aClearMask*/, TUint /*aSetMask*/)
1.134 + {// RAM zone not supported for this memory model
1.135 + return KErrNotSupported;
1.136 + }
1.137 +
1.138 +/**
1.139 + @pre Call in a thread context.
1.140 + @pre Interrupts must be enabled.
1.141 + @pre Kernel must be unlocked.
1.142 + @pre No fast mutex can be held.
1.143 + @pre Calling thread must be in a critical section.
1.144 + */
1.145 +EXPORT_C TInt Epoc::AllocShadowPage(TLinAddr aRomAddr)
1.146 + {
1.147 + CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::AllocShadowPage");
1.148 + return KErrNotSupported;
1.149 + }
1.150 +
1.151 +/**
1.152 + @pre Call in a thread context.
1.153 + @pre Interrupts must be enabled.
1.154 + @pre Kernel must be unlocked.
1.155 + @pre No fast mutex can be held.
1.156 + @pre Calling thread must be in a critical section.
1.157 + */
1.158 +EXPORT_C TInt Epoc::FreeShadowPage(TLinAddr aRomAddr)
1.159 + {
1.160 + CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::FreeShadowPage");
1.161 + return KErrNotSupported;
1.162 + }
1.163 +
1.164 +/**
1.165 +@pre Calling thread must be in a critical section.
1.166 +@pre Interrupts must be enabled.
1.167 +@pre Kernel must be unlocked.
1.168 +@pre No fast mutex can be held.
1.169 +@pre Call in a thread context.
1.170 +*/
1.171 +EXPORT_C TInt Epoc::CopyToShadowMemory(TLinAddr /*aDest*/, TLinAddr /*aSrc*/, TUint32 /*aLength*/)
1.172 + {
1.173 + CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::CopyToShadowPage");
1.174 + return KErrNotSupported;
1.175 + }
1.176 +
1.177 +/**
1.178 + @pre Call in a thread context.
1.179 + @pre Interrupts must be enabled.
1.180 + @pre Kernel must be unlocked.
1.181 + @pre No fast mutex can be held.
1.182 + @pre Calling thread must be in a critical section.
1.183 + */
1.184 +EXPORT_C TInt Epoc::FreezeShadowPage(TLinAddr aRomAddr)
1.185 + {
1.186 + CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::FreezeShadowPage");
1.187 + return KErrNotSupported;
1.188 + }
1.189 +
1.190 +/**
1.191 + @pre Call in a thread context.
1.192 + @pre Interrupts must be enabled.
1.193 + @pre Kernel must be unlocked.
1.194 + @pre No fast mutex can be held.
1.195 + @pre Calling thread must be in a critical section.
1.196 + */
1.197 +EXPORT_C TInt Epoc::AllocPhysicalRam(TInt aSize, TPhysAddr& aPhysAddr, TInt aAlign)
1.198 + {
1.199 + CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::AllocPhysicalRam");
1.200 + MM::WaitRamAlloc();
1.201 + TLinAddr lin;
1.202 + TInt r=MM::AllocContiguousRegion(lin, aSize, aAlign);
1.203 + if (r!=KErrNone)
1.204 + MM::AllocFailed=ETrue;
1.205 + else
1.206 + {
1.207 + aPhysAddr = LinearToPhysical(lin);
1.208 +#if defined(__CPU_HAS_CACHE) && !defined(__CPU_X86)
1.209 + CacheMaintenance::MemoryToReuse(lin, aSize);
1.210 +#endif
1.211 +#ifdef BTRACE_KERNEL_MEMORY
1.212 + TUint size = Kern::RoundToPageSize(aSize);
1.213 + BTrace8(BTrace::EKernelMemory, BTrace::EKernelMemoryDrvPhysAlloc, size, aPhysAddr);
1.214 + Epoc::DriverAllocdPhysRam += size;
1.215 +#endif
1.216 + }
1.217 + MM::SignalRamAlloc();
1.218 + return r;
1.219 + }
1.220 +
1.221 +/**
1.222 + @pre Call in a thread context.
1.223 + @pre Interrupts must be enabled.
1.224 + @pre Kernel must be unlocked.
1.225 + @pre No fast mutex can be held.
1.226 + @pre Calling thread must be in a critical section.
1.227 + */
1.228 +EXPORT_C TInt Epoc::FreePhysicalRam(TPhysAddr aPhysAddr, TInt aSize)
1.229 + {
1.230 + CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::FreePhysicalRam");
1.231 + MM::WaitRamAlloc();
1.232 +#ifndef __CPU_HAS_MMU
1.233 + MM::FreeRegion(aPhysAddr, aSize);
1.234 +#else
1.235 + TInt bn = MM::BlockNumber(aPhysAddr);
1.236 + TInt bn0 = MM::BlockNumber(MM::UserDataSectionBase);
1.237 + TLinAddr lin = TLinAddr((bn - bn0)<<MM::RamBlockShift) + MM::UserDataSectionBase;
1.238 + MM::FreeRegion(lin, aSize);
1.239 +#endif
1.240 +#ifdef BTRACE_KERNEL_MEMORY
1.241 + TUint size = Kern::RoundToPageSize(aSize);
1.242 + BTrace8(BTrace::EKernelMemory, BTrace::EKernelMemoryDrvPhysFree, aPhysAddr, size);
1.243 + Epoc::DriverAllocdPhysRam -= size;
1.244 +#endif
1.245 + MM::SignalRamAlloc();
1.246 + return KErrNone;
1.247 + }
1.248 +
1.249 +/**
1.250 +Allocate a block of physically contiguous RAM with a physical address aligned
1.251 +to a specified power of 2 boundary from the specified zone.
1.252 +When the RAM is no longer required it should be freed using Epoc::FreePhysicalRam().
1.253 +
1.254 +Note that this method only repsects the KRamZoneFlagNoAlloc flag and will always attempt
1.255 +to allocate regardless of whether the other flags are set for the specified RAM zones
1.256 +or not.
1.257 +
1.258 +When the RAM is no longer required it should be freed using Epoc::FreePhysicalRam().
1.259 +
1.260 +@param aZoneId The ID of the zone to attempt to allocate from.
1.261 +@param aSize The size in bytes of the required block. The specified size
1.262 + is rounded up to the page size, since only whole pages of
1.263 + physical RAM can be allocated.
1.264 +@param aPhysAddr Receives the physical address of the base of the block on
1.265 + successful allocation.
1.266 +@param aAlign Specifies the number of least significant bits of the
1.267 + physical address which are required to be zero. If a value
1.268 + less than log2(page size) is specified, page alignment is
1.269 + assumed. Pass 0 for aAlign if there are no special alignment
1.270 + constraints (other than page alignment).
1.271 +@return KErrNone if the allocation was successful.
1.272 + KErrNoMemory if a sufficiently large physically contiguous block of free
1.273 + RAM with the specified alignment could not be found within the specified
1.274 + zone.
1.275 + KErrArgument if a RAM zone of the specified ID can't be found or if the
1.276 + RAM zone has a total number of physical pages which is less than those
1.277 + requested for the allocation.
1.278 +
1.279 +@pre Calling thread must be in a critical section.
1.280 +@pre Interrupts must be enabled.
1.281 +@pre Kernel must be unlocked.
1.282 +@pre No fast mutex can be held.
1.283 +@pre Call in a thread context.
1.284 +@pre Can be used in a device driver.
1.285 +*/
1.286 +EXPORT_C TInt Epoc::ZoneAllocPhysicalRam(TUint aZoneId, TInt aSize, TPhysAddr& aPhysAddr, TInt aAlign)
1.287 + {
1.288 + CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::ZoneAllocPhysicalRam");
1.289 + return KErrNotSupported;
1.290 + }
1.291 +
1.292 +
1.293 +/**
1.294 +Allocate a block of physically contiguous RAM with a physical address aligned
1.295 +to a specified power of 2 boundary from the specified RAM zones.
1.296 +When the RAM is no longer required it should be freed using Epoc::FreePhysicalRam().
1.297 +
1.298 +RAM will be allocated into the RAM zones in the order they are specified in the
1.299 +aZoneId parameter. If the contiguous allocations are intended to span RAM zones
1.300 +when required then aZoneId should be listed with the RAM zones in ascending
1.301 +physical address order.
1.302 +
1.303 +Note that this method only repsects the KRamZoneFlagNoAlloc flag and will always attempt
1.304 +to allocate regardless of whether the other flags are set for the specified RAM zones
1.305 +or not.
1.306 +
1.307 +When the RAM is no longer required it should be freed using Epoc::FreePhysicalRam().
1.308 +
1.309 +@param aZoneIdList A pointer to an array of RAM zone IDs of the RAM zones to
1.310 + attempt to allocate from.
1.311 +@param aZoneIdCount The number of RAM zone IDs contained in aZoneIdList.
1.312 +@param aSize The size in bytes of the required block. The specified size
1.313 + is rounded up to the page size, since only whole pages of
1.314 + physical RAM can be allocated.
1.315 +@param aPhysAddr Receives the physical address of the base of the block on
1.316 + successful allocation.
1.317 +@param aAlign Specifies the number of least significant bits of the
1.318 + physical address which are required to be zero. If a value
1.319 + less than log2(page size) is specified, page alignment is
1.320 + assumed. Pass 0 for aAlign if there are no special alignment
1.321 + constraints (other than page alignment).
1.322 +@return KErrNone if the allocation was successful.
1.323 + KErrNoMemory if a sufficiently large physically contiguous block of free
1.324 + RAM with the specified alignment could not be found within the specified
1.325 + zone.
1.326 + KErrArgument if a RAM zone of a specified ID can't be found or if the
1.327 + RAM zones have a total number of physical pages which is less than those
1.328 + requested for the allocation.
1.329 +
1.330 +@pre Calling thread must be in a critical section.
1.331 +@pre Interrupts must be enabled.
1.332 +@pre Kernel must be unlocked.
1.333 +@pre No fast mutex can be held.
1.334 +@pre Call in a thread context.
1.335 +@pre Can be used in a device driver.
1.336 +*/
1.337 +EXPORT_C TInt Epoc::ZoneAllocPhysicalRam(TUint* aZoneIdList, TUint aZoneIdCount, TInt aSize, TPhysAddr& aPhysAddr, TInt aAlign)
1.338 + {
1.339 + CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::ZoneAllocPhysicalRam");
1.340 + return KErrNotSupported;
1.341 + }
1.342 +
1.343 +
1.344 +/**
1.345 +Attempt to allocate discontiguous RAM pages.
1.346 +
1.347 +When the RAM is no longer required it should be freed using Epoc::FreePhysicalRam().
1.348 +
1.349 +@param aNumPages The number of discontiguous pages required to be allocated
1.350 +@param aPageList This should be a pointer to a previously allocated array of
1.351 + aNumPages TPhysAddr elements. On a succesful allocation it
1.352 + will receive the physical addresses of each page allocated.
1.353 +
1.354 +@return KErrNone if the allocation was successful.
1.355 + KErrNoMemory if the requested number of pages can't be allocated
1.356 +
1.357 +@pre Calling thread must be in a critical section.
1.358 +@pre Interrupts must be enabled.
1.359 +@pre Kernel must be unlocked.
1.360 +@pre No fast mutex can be held.
1.361 +@pre Call in a thread context.
1.362 +@pre Can be used in a device driver.
1.363 +*/
1.364 +EXPORT_C TInt Epoc::AllocPhysicalRam(TInt aNumPages, TPhysAddr* aPageList)
1.365 + {
1.366 + CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL, "Epoc::AllocPhysicalRam");
1.367 + return KErrNotSupported;
1.368 + }
1.369 +
1.370 +
1.371 +/**
1.372 +Attempt to allocate discontiguous RAM pages from the specified zone.
1.373 +
1.374 +Note that this method only repsects the KRamZoneFlagNoAlloc flag and will always attempt
1.375 +to allocate regardless of whether the other flags are set for the specified RAM zones
1.376 +or not.
1.377 +
1.378 +When the RAM is no longer required it should be freed using Epoc::FreePhysicalRam().
1.379 +
1.380 +@param aZoneId The ID of the zone to attempt to allocate from.
1.381 +@param aNumPages The number of discontiguous pages required to be allocated
1.382 + from the specified zone.
1.383 +@param aPageList This should be a pointer to a previously allocated array of
1.384 + aNumPages TPhysAddr elements. On a succesful
1.385 + allocation it will receive the physical addresses of each
1.386 + page allocated.
1.387 +@return KErrNone if the allocation was successful.
1.388 + KErrNoMemory if the requested number of pages can't be allocated from the
1.389 + specified zone.
1.390 + KErrArgument if a RAM zone of the specified ID can't be found or if the
1.391 + RAM zone has a total number of physical pages which is less than those
1.392 + requested for the allocation.
1.393 +
1.394 +@pre Calling thread must be in a critical section.
1.395 +@pre Interrupts must be enabled.
1.396 +@pre Kernel must be unlocked.
1.397 +@pre No fast mutex can be held.
1.398 +@pre Call in a thread context.
1.399 +@pre Can be used in a device driver.
1.400 +*/
1.401 +EXPORT_C TInt Epoc::ZoneAllocPhysicalRam(TUint aZoneId, TInt aNumPages, TPhysAddr* aPageList)
1.402 + {
1.403 + CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL, "Epoc::ZoneAllocPhysicalRam");
1.404 + return KErrNotSupported;
1.405 + }
1.406 +
1.407 +
1.408 +/**
1.409 +Attempt to allocate discontiguous RAM pages from the specified RAM zones.
1.410 +The RAM pages will be allocated into the RAM zones in the order that they are specified
1.411 +in the aZoneId parameter, the RAM zone preferences will be ignored.
1.412 +
1.413 +Note that this method only repsects the KRamZoneFlagNoAlloc flag and will always attempt
1.414 +to allocate regardless of whether the other flags are set for the specified RAM zones
1.415 +or not.
1.416 +
1.417 +When the RAM is no longer required it should be freed using Epoc::FreePhysicalRam().
1.418 +
1.419 +@param aZoneIdList A pointer to an array of RAM zone IDs of the RAM zones to
1.420 + attempt to allocate from.
1.421 +@param aZoneIdCount The number of RAM zone IDs pointed to by aZoneIdList.
1.422 +@param aNumPages The number of discontiguous pages required to be allocated
1.423 + from the specified zone.
1.424 +@param aPageList This should be a pointer to a previously allocated array of
1.425 + aNumPages TPhysAddr elements. On a succesful
1.426 + allocation it will receive the physical addresses of each
1.427 + page allocated.
1.428 +@return KErrNone if the allocation was successful.
1.429 + KErrNoMemory if the requested number of pages can't be allocated from the
1.430 + specified zone.
1.431 + KErrArgument if a RAM zone of a specified ID can't be found or if the
1.432 + RAM zones have a total number of physical pages which is less than those
1.433 + requested for the allocation.
1.434 +
1.435 +@pre Calling thread must be in a critical section.
1.436 +@pre Interrupts must be enabled.
1.437 +@pre Kernel must be unlocked.
1.438 +@pre No fast mutex can be held.
1.439 +@pre Call in a thread context.
1.440 +@pre Can be used in a device driver.
1.441 +*/
1.442 +EXPORT_C TInt Epoc::ZoneAllocPhysicalRam(TUint* aZoneIdList, TUint aZoneIdCount, TInt aNumPages, TPhysAddr* aPageList)
1.443 + {
1.444 + CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL, "Epoc::ZoneAllocPhysicalRam");
1.445 + return KErrNotSupported;
1.446 + }
1.447 +
1.448 +
1.449 +/**
1.450 +Free a number of physical RAM pages that were previously allocated using
1.451 +Epoc::AllocPhysicalRam().
1.452 +
1.453 +@param aNumPages The number of pages to be freed.
1.454 +@param aPhysAddr An array of aNumPages TPhysAddr elements. Where each element
1.455 + should contain the physical address of each page to be freed.
1.456 + This must be the same set of addresses as those returned by a
1.457 + previous call to Epoc::AllocPhysicalRam() or
1.458 + Epoc::ZoneAllocPhysicalRam().
1.459 +@return KErrNone if the operation was successful.
1.460 + KErrArgument if one or more of the physical addresses specified is not
1.461 + a valid physical RAM address.
1.462 + KErrGeneral if the physical addresses specified are all valid
1.463 + physical RAM addresses but some of them had not
1.464 + been previously allocated.
1.465 +@pre Calling thread must be in a critical section.
1.466 +@pre Interrupts must be enabled.
1.467 +@pre Kernel must be unlocked.
1.468 +@pre No fast mutex can be held.
1.469 +@pre Call in a thread context.
1.470 +@pre Can be used in a device driver.
1.471 +*/
1.472 +EXPORT_C TInt Epoc::FreePhysicalRam(TInt aNumPages, TPhysAddr* aPageList)
1.473 + {
1.474 + CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::FreePhysicalRam");
1.475 + return KErrNotSupported;
1.476 + }
1.477 +
1.478 +
1.479 +/**
1.480 + @pre Call in a thread context.
1.481 + @pre Interrupts must be enabled.
1.482 + @pre Kernel must be unlocked.
1.483 + @pre No fast mutex can be held.
1.484 + @pre Calling thread must be in a critical section.
1.485 + */
1.486 +EXPORT_C TInt Epoc::ClaimPhysicalRam(TPhysAddr aPhysAddr, TInt aSize)
1.487 + {
1.488 + CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"Epoc::ClaimPhysicalRam");
1.489 + MM::WaitRamAlloc();
1.490 +#ifndef __CPU_HAS_MMU
1.491 + TInt r=MM::ClaimRegion(aPhysAddr, aSize);
1.492 +#else
1.493 + TInt bn = MM::BlockNumber(aPhysAddr);
1.494 + TInt bn0 = MM::BlockNumber(MM::UserDataSectionBase);
1.495 + TLinAddr lin = TLinAddr((bn - bn0)<<MM::RamBlockShift) + MM::UserDataSectionBase;
1.496 + TInt r=MM::ClaimRegion(lin, aSize);
1.497 +#endif
1.498 + MM::SignalRamAlloc();
1.499 + return r;
1.500 + }
1.501 +
1.502 +void ExecHandler::UnlockRamDrive()
1.503 + {
1.504 + }
1.505 +
1.506 +EXPORT_C void TInternalRamDrive::Unlock()
1.507 + {
1.508 + }
1.509 +
1.510 +EXPORT_C void TInternalRamDrive::Lock()
1.511 + {
1.512 + }
1.513 +
1.514 +void MM::WaitRamAlloc()
1.515 + {
1.516 + Kern::MutexWait(*RamAllocatorMutex);
1.517 + if (RamAllocatorMutex->iHoldCount==1)
1.518 + {
1.519 + MM::InitialFreeMemory=Kern::FreeRamInBytes();
1.520 + MM::AllocFailed=EFalse;
1.521 + }
1.522 + }
1.523 +
1.524 +void MM::SignalRamAlloc()
1.525 + {
1.526 + if (RamAllocatorMutex->iHoldCount>1)
1.527 + {
1.528 + Kern::MutexSignal(*RamAllocatorMutex);
1.529 + return;
1.530 + }
1.531 + TInt initial=MM::InitialFreeMemory;
1.532 + TBool failed=MM::AllocFailed;
1.533 + TInt final=Kern::FreeRamInBytes();
1.534 + Kern::MutexSignal(*RamAllocatorMutex);
1.535 + K::CheckFreeMemoryLevel(initial,final,failed);
1.536 + }
1.537 +
1.538 +EXPORT_C TInt TInternalRamDrive::MaxSize()
1.539 + {
1.540 + return PP::RamDriveMaxSize;
1.541 + }
1.542 +
1.543 +void M::FsRegisterThread()
1.544 + {
1.545 + }
1.546 +
1.547 +void M::BTracePrime(TUint aCategory)
1.548 + {
1.549 + (void)aCategory;
1.550 +#ifdef BTRACE_KERNEL_MEMORY
1.551 + // Must check for -1 as that is the default value of aCategory for
1.552 + // BTrace::Prime() which is intended to prime all categories that are
1.553 + // currently enabled via a single invocation of BTrace::Prime().
1.554 + if(aCategory==BTrace::EKernelMemory || (TInt)aCategory == -1)
1.555 + {
1.556 + BTrace4(BTrace::EKernelMemory,BTrace::EKernelMemoryInitialFree,TheSuperPage().iTotalRamSize);
1.557 + BTrace4(BTrace::EKernelMemory,BTrace::EKernelMemoryCurrentFree,Kern::FreeRamInBytes());
1.558 + BTrace8(BTrace::EKernelMemory,BTrace::EKernelMemoryDrvPhysAlloc, Epoc::DriverAllocdPhysRam, -1);
1.559 + }
1.560 +#endif
1.561 + }
1.562 +
1.563 +EXPORT_C DDemandPagingLock::DDemandPagingLock()
1.564 + : iLockedPageCount(0)
1.565 + {
1.566 + }
1.567 +
1.568 +EXPORT_C TInt DDemandPagingLock::Alloc(TInt /*aSize*/)
1.569 + {
1.570 + return KErrNone;
1.571 + }
1.572 +
1.573 +EXPORT_C TBool DDemandPagingLock::Lock(DThread* /*aThread*/, TLinAddr /*aStart*/, TInt /*aSize*/)
1.574 + {
1.575 + return EFalse;
1.576 + }
1.577 +
1.578 +EXPORT_C void DDemandPagingLock::DoUnlock()
1.579 + {
1.580 + }
1.581 +
1.582 +EXPORT_C void DDemandPagingLock::Free()
1.583 + {
1.584 + }
1.585 +
1.586 +EXPORT_C TInt Kern::InstallPagingDevice(DPagingDevice* aDevice)
1.587 + {
1.588 + return KErrNotSupported;
1.589 + }
1.590 +
1.591 +// Dummy implementation of kernel pin APIs
1.592 +
1.593 +class TVirtualPinObject
1.594 + {
1.595 + };
1.596 +
1.597 +TInt M::CreateVirtualPinObject(TVirtualPinObject*& aPinObject)
1.598 + {
1.599 + aPinObject = new TVirtualPinObject;
1.600 + return aPinObject != NULL ? KErrNone : KErrNoMemory;
1.601 + }
1.602 +
1.603 +TInt M::PinVirtualMemory(TVirtualPinObject* aPinObject, TLinAddr, TUint, DThread*)
1.604 + {
1.605 + __ASSERT_DEBUG(aPinObject, K::Fault(K::EVirtualPinObjectBad));
1.606 + (void)aPinObject;
1.607 + return KErrNone;
1.608 + }
1.609 +
1.610 +TInt M::CreateAndPinVirtualMemory(TVirtualPinObject*& aPinObject, TLinAddr, TUint)
1.611 + {
1.612 + aPinObject = 0;
1.613 + return KErrNone;
1.614 + }
1.615 +
1.616 +void M::UnpinVirtualMemory(TVirtualPinObject* aPinObject)
1.617 + {
1.618 + __ASSERT_DEBUG(aPinObject, K::Fault(K::EVirtualPinObjectBad));
1.619 + (void)aPinObject;
1.620 + }
1.621 +
1.622 +void M::DestroyVirtualPinObject(TVirtualPinObject*& aPinObject)
1.623 + {
1.624 + TVirtualPinObject* object = (TVirtualPinObject*)__e32_atomic_swp_ord_ptr(&aPinObject, 0);
1.625 + if (object)
1.626 + Kern::AsyncFree(object);
1.627 + }
1.628 +
1.629 +TInt M::CreatePhysicalPinObject(TPhysicalPinObject*& aPinObject)
1.630 + {
1.631 + return KErrNotSupported;
1.632 + }
1.633 +
1.634 +TInt M::PinPhysicalMemory(TPhysicalPinObject*, TLinAddr, TUint, TBool, TPhysAddr& , TPhysAddr*, TUint32&, TUint&, DThread*)
1.635 + {
1.636 + K::Fault(K::EPhysicalPinObjectBad);
1.637 + return KErrNone;
1.638 + }
1.639 +
1.640 +void M::UnpinPhysicalMemory(TPhysicalPinObject* aPinObject)
1.641 + {
1.642 + K::Fault(K::EPhysicalPinObjectBad);
1.643 + }
1.644 +
1.645 +void M::DestroyPhysicalPinObject(TPhysicalPinObject*& aPinObject)
1.646 + {
1.647 + K::Fault(K::EPhysicalPinObjectBad);
1.648 + }
1.649 +
1.650 +
1.651 +//
1.652 +// Kernel map and pin (Not supported on the direct memory models).
1.653 +//
1.654 +
1.655 +TInt M::CreateKernelMapObject(TKernelMapObject*&, TUint)
1.656 + {
1.657 + return KErrNotSupported;
1.658 + }
1.659 +
1.660 +
1.661 +TInt M::MapAndPinMemory(TKernelMapObject*, DThread*, TLinAddr, TUint, TUint, TLinAddr&, TPhysAddr*)
1.662 + {
1.663 + return KErrNotSupported;
1.664 + }
1.665 +
1.666 +
1.667 +void M::UnmapAndUnpinMemory(TKernelMapObject*)
1.668 + {
1.669 + }
1.670 +
1.671 +
1.672 +void M::DestroyKernelMapObject(TKernelMapObject*&)
1.673 + {
1.674 + }
1.675 +
1.676 +
1.677 +// Misc DPagingDevice methods
1.678 +
1.679 +EXPORT_C void DPagingDevice::NotifyIdle()
1.680 + {
1.681 + // Not used on this memory model
1.682 + }
1.683 +
1.684 +EXPORT_C void DPagingDevice::NotifyBusy()
1.685 + {
1.686 + // Not used on this memory model
1.687 + }
1.688 +
1.689 +EXPORT_C TInt Cache::SyncPhysicalMemoryBeforeDmaWrite(TPhysAddr* , TUint , TUint , TUint , TUint32 )
1.690 + {
1.691 + CHECK_PRECONDITIONS(MASK_THREAD_STANDARD,"Cache::SyncPhysicalMemoryBeforeDmaWrite");
1.692 + return KErrNotSupported;
1.693 + }
1.694 +
1.695 +EXPORT_C TInt Cache::SyncPhysicalMemoryBeforeDmaRead(TPhysAddr* , TUint , TUint , TUint , TUint32 )
1.696 + {
1.697 + CHECK_PRECONDITIONS(MASK_THREAD_STANDARD,"Cache::SyncPhysicalMemoryBeforeDmaRead");
1.698 + return KErrNotSupported;
1.699 + }
1.700 +EXPORT_C TInt Cache::SyncPhysicalMemoryAfterDmaRead(TPhysAddr* , TUint , TUint , TUint , TUint32 )
1.701 + {
1.702 + CHECK_PRECONDITIONS(MASK_THREAD_STANDARD,"Cache::SyncPhysicalMemoryAfterDmaRead");
1.703 + return KErrNotSupported;
1.704 + }