sl@0: // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32\memmodel\emul\nvram.cpp sl@0: // sl@0: // sl@0: sl@0: #include "plat_priv.h" sl@0: #include sl@0: #include sl@0: #include "execs.h" sl@0: sl@0: _LIT(KLitMachineConfigMutex,"MCConfMutex"); sl@0: _LIT(KLitRamDriveMutex,"RamDriveMutex"); sl@0: sl@0: void K::InitNvRam() sl@0: { sl@0: __KTRACE_OPT(KBOOT,Kern::Printf("K::InitNvRam")); sl@0: if (K::MutexCreate(K::MachineConfigMutex, KLitMachineConfigMutex, NULL, EFalse, KMutexOrdMachineConfig) != KErrNone) sl@0: K::Fault(K::EMachineConfigMutexCreateFailed); sl@0: sl@0: TInt r=TInternalRamDrive::Create(); sl@0: if (r!=KErrNone) sl@0: K::Fault(K::ERamDriveInitFailed); sl@0: sl@0: __KTRACE_OPT(KBOOT,Kern::Printf("K::InitNvRam() completed")); sl@0: } sl@0: sl@0: // Internal RAM Drive sl@0: sl@0: // We emulated this on WINS by memory mapping a 2MB+4KB file (IRAMLDRV.BIN in the EmulatorMediaPath) sl@0: // The word of the last page of this file contains the nominal size of the RAM drive 'chunk' sl@0: sl@0: const CHAR KIRamFileName[] = "IRAMLDRV.BIN"; sl@0: sl@0: TInt TInternalRamDrive::Create() sl@0: { sl@0: __KTRACE_OPT(KBOOT, Kern::Printf("TInternalRamDrive::Create()")); sl@0: sl@0: // create the RAM drive mutex sl@0: TInt r = K::MutexCreate((DMutex*&)Mutex, KLitRamDriveMutex, NULL, EFalse, KMutexOrdRamDrive); sl@0: if (r != KErrNone) sl@0: return r; sl@0: __KTRACE_OPT(KBOOT, Kern::Printf("RAM drive mutex created at %08x",Mutex)); sl@0: sl@0: // locate/open the RAM drive sl@0: CHAR filename[MAX_PATH]; sl@0: strcpy(filename, Arch::TheAsic()->EmulatorMediaPath()); sl@0: if (!Emulator::CreateAllDirectories(filename)) sl@0: return Emulator::LastError(); sl@0: strcat(filename, KIRamFileName); sl@0: PP::RamDriveFile = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, NULL); sl@0: if (PP::RamDriveFile == INVALID_HANDLE_VALUE) sl@0: return Emulator::LastError(); sl@0: TInt filesize = GetFileSize(PP::RamDriveFile, NULL); sl@0: TInt size = 0; sl@0: sl@0: // deal with ram drives that were created on a real device and opened in the emulator sl@0: // and also with ones created with a different max size setting sl@0: sl@0: if ((filesize&0x1ff) == 0) sl@0: { sl@0: // the file is from a real internal drive on a device sl@0: size = filesize; sl@0: } sl@0: else if ((filesize&0x1ff) == sizeof(TRamDriveInfo)) sl@0: { sl@0: // created by us sl@0: DWORD bytes; sl@0: if (SetFilePointer(PP::RamDriveFile, -4, NULL, FILE_END) == 0xffffffff sl@0: || !ReadFile(PP::RamDriveFile, &size, sizeof(size), &bytes, NULL)) sl@0: return Emulator::LastError(); sl@0: } sl@0: if (size > PP::RamDriveMaxSize) sl@0: PP::RamDriveMaxSize = size; sl@0: sl@0: // deal with a resized ram drive file sl@0: if (filesize != PP::RamDriveMaxSize + TInt(sizeof(TRamDriveInfo))) sl@0: { sl@0: DWORD bytes; sl@0: if (SetFilePointer(PP::RamDriveFile, PP::RamDriveMaxSize, NULL, FILE_BEGIN) == 0xffffffff sl@0: || !WriteFile(PP::RamDriveFile, &size, sizeof(size), &bytes, NULL) sl@0: || !SetEndOfFile(PP::RamDriveFile)) sl@0: return Emulator::LastError(); sl@0: } sl@0: sl@0: PP::RamDriveFileMapping = CreateFileMappingA(PP::RamDriveFile, NULL, PAGE_READWRITE, 0, PP::RamDriveMaxSize + sizeof(TRamDriveInfo), NULL); sl@0: if (PP::RamDriveFileMapping == NULL) sl@0: return Emulator::LastError(); sl@0: sl@0: PP::RamDriveStartAddress = (TLinAddr)MapViewOfFile(PP::RamDriveFileMapping, FILE_MAP_WRITE, 0, 0, PP::RamDriveMaxSize + sizeof(TRamDriveInfo)); sl@0: if (PP::RamDriveStartAddress == NULL) sl@0: return Emulator::LastError(); sl@0: sl@0: PP::RamDriveInfo = (TRamDriveInfo*)(PP::RamDriveStartAddress + PP::RamDriveMaxSize); sl@0: sl@0: TheSuperPage().iRamDriveSize = size; sl@0: return KErrNone; sl@0: } sl@0: sl@0: EXPORT_C TLinAddr TInternalRamDrive::Base() sl@0: // sl@0: // Return the Internal Ram Drive base address sl@0: // sl@0: { sl@0: return PP::RamDriveStartAddress; sl@0: } sl@0: sl@0: EXPORT_C TInt TInternalRamDrive::Size() sl@0: // sl@0: // Return the Internal Ram Drive size sl@0: // sl@0: { sl@0: return PP::RamDriveInfo->iSize; sl@0: } sl@0: sl@0: EXPORT_C TInt TInternalRamDrive::Adjust(TInt aNewSize) sl@0: // sl@0: // Adjust the size of the internal ram drive sl@0: // sl@0: { sl@0: if (aNewSize<0) sl@0: return KErrArgument; sl@0: if (aNewSize>PP::RamDriveMaxSize) sl@0: return KErrDiskFull; sl@0: if (aNewSize != PP::RamDriveInfo->iSize) sl@0: PP::RamDriveInfo->iSize = aNewSize; sl@0: return KErrNone; sl@0: } sl@0: sl@0: EXPORT_C void TInternalRamDrive::Wait() sl@0: { sl@0: Kern::MutexWait(*Mutex); sl@0: } sl@0: sl@0: EXPORT_C void TInternalRamDrive::Signal() sl@0: { sl@0: Kern::MutexSignal(*Mutex); sl@0: } sl@0: sl@0: void ExecHandler::UnlockRamDrive() sl@0: { sl@0: } sl@0: sl@0: EXPORT_C void TInternalRamDrive::Unlock() sl@0: {} sl@0: sl@0: EXPORT_C void TInternalRamDrive::Lock() sl@0: {} sl@0: