|
1 // Copyright (c) 1997-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 // e32\memmodel\emul\nvram.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 #include "plat_priv.h" |
|
19 #include <assp.h> |
|
20 #include <emulator.h> |
|
21 #include "execs.h" |
|
22 |
|
23 _LIT(KLitMachineConfigMutex,"MCConfMutex"); |
|
24 _LIT(KLitRamDriveMutex,"RamDriveMutex"); |
|
25 |
|
26 void K::InitNvRam() |
|
27 { |
|
28 __KTRACE_OPT(KBOOT,Kern::Printf("K::InitNvRam")); |
|
29 if (K::MutexCreate(K::MachineConfigMutex, KLitMachineConfigMutex, NULL, EFalse, KMutexOrdMachineConfig) != KErrNone) |
|
30 K::Fault(K::EMachineConfigMutexCreateFailed); |
|
31 |
|
32 TInt r=TInternalRamDrive::Create(); |
|
33 if (r!=KErrNone) |
|
34 K::Fault(K::ERamDriveInitFailed); |
|
35 |
|
36 __KTRACE_OPT(KBOOT,Kern::Printf("K::InitNvRam() completed")); |
|
37 } |
|
38 |
|
39 // Internal RAM Drive |
|
40 |
|
41 // We emulated this on WINS by memory mapping a 2MB+4KB file (IRAMLDRV.BIN in the EmulatorMediaPath) |
|
42 // The word of the last page of this file contains the nominal size of the RAM drive 'chunk' |
|
43 |
|
44 const CHAR KIRamFileName[] = "IRAMLDRV.BIN"; |
|
45 |
|
46 TInt TInternalRamDrive::Create() |
|
47 { |
|
48 __KTRACE_OPT(KBOOT, Kern::Printf("TInternalRamDrive::Create()")); |
|
49 |
|
50 // create the RAM drive mutex |
|
51 TInt r = K::MutexCreate((DMutex*&)Mutex, KLitRamDriveMutex, NULL, EFalse, KMutexOrdRamDrive); |
|
52 if (r != KErrNone) |
|
53 return r; |
|
54 __KTRACE_OPT(KBOOT, Kern::Printf("RAM drive mutex created at %08x",Mutex)); |
|
55 |
|
56 // locate/open the RAM drive |
|
57 CHAR filename[MAX_PATH]; |
|
58 strcpy(filename, Arch::TheAsic()->EmulatorMediaPath()); |
|
59 if (!Emulator::CreateAllDirectories(filename)) |
|
60 return Emulator::LastError(); |
|
61 strcat(filename, KIRamFileName); |
|
62 PP::RamDriveFile = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, NULL); |
|
63 if (PP::RamDriveFile == INVALID_HANDLE_VALUE) |
|
64 return Emulator::LastError(); |
|
65 TInt filesize = GetFileSize(PP::RamDriveFile, NULL); |
|
66 TInt size = 0; |
|
67 |
|
68 // deal with ram drives that were created on a real device and opened in the emulator |
|
69 // and also with ones created with a different max size setting |
|
70 |
|
71 if ((filesize&0x1ff) == 0) |
|
72 { |
|
73 // the file is from a real internal drive on a device |
|
74 size = filesize; |
|
75 } |
|
76 else if ((filesize&0x1ff) == sizeof(TRamDriveInfo)) |
|
77 { |
|
78 // created by us |
|
79 DWORD bytes; |
|
80 if (SetFilePointer(PP::RamDriveFile, -4, NULL, FILE_END) == 0xffffffff |
|
81 || !ReadFile(PP::RamDriveFile, &size, sizeof(size), &bytes, NULL)) |
|
82 return Emulator::LastError(); |
|
83 } |
|
84 if (size > PP::RamDriveMaxSize) |
|
85 PP::RamDriveMaxSize = size; |
|
86 |
|
87 // deal with a resized ram drive file |
|
88 if (filesize != PP::RamDriveMaxSize + TInt(sizeof(TRamDriveInfo))) |
|
89 { |
|
90 DWORD bytes; |
|
91 if (SetFilePointer(PP::RamDriveFile, PP::RamDriveMaxSize, NULL, FILE_BEGIN) == 0xffffffff |
|
92 || !WriteFile(PP::RamDriveFile, &size, sizeof(size), &bytes, NULL) |
|
93 || !SetEndOfFile(PP::RamDriveFile)) |
|
94 return Emulator::LastError(); |
|
95 } |
|
96 |
|
97 PP::RamDriveFileMapping = CreateFileMappingA(PP::RamDriveFile, NULL, PAGE_READWRITE, 0, PP::RamDriveMaxSize + sizeof(TRamDriveInfo), NULL); |
|
98 if (PP::RamDriveFileMapping == NULL) |
|
99 return Emulator::LastError(); |
|
100 |
|
101 PP::RamDriveStartAddress = (TLinAddr)MapViewOfFile(PP::RamDriveFileMapping, FILE_MAP_WRITE, 0, 0, PP::RamDriveMaxSize + sizeof(TRamDriveInfo)); |
|
102 if (PP::RamDriveStartAddress == NULL) |
|
103 return Emulator::LastError(); |
|
104 |
|
105 PP::RamDriveInfo = (TRamDriveInfo*)(PP::RamDriveStartAddress + PP::RamDriveMaxSize); |
|
106 |
|
107 TheSuperPage().iRamDriveSize = size; |
|
108 return KErrNone; |
|
109 } |
|
110 |
|
111 EXPORT_C TLinAddr TInternalRamDrive::Base() |
|
112 // |
|
113 // Return the Internal Ram Drive base address |
|
114 // |
|
115 { |
|
116 return PP::RamDriveStartAddress; |
|
117 } |
|
118 |
|
119 EXPORT_C TInt TInternalRamDrive::Size() |
|
120 // |
|
121 // Return the Internal Ram Drive size |
|
122 // |
|
123 { |
|
124 return PP::RamDriveInfo->iSize; |
|
125 } |
|
126 |
|
127 EXPORT_C TInt TInternalRamDrive::Adjust(TInt aNewSize) |
|
128 // |
|
129 // Adjust the size of the internal ram drive |
|
130 // |
|
131 { |
|
132 if (aNewSize<0) |
|
133 return KErrArgument; |
|
134 if (aNewSize>PP::RamDriveMaxSize) |
|
135 return KErrDiskFull; |
|
136 if (aNewSize != PP::RamDriveInfo->iSize) |
|
137 PP::RamDriveInfo->iSize = aNewSize; |
|
138 return KErrNone; |
|
139 } |
|
140 |
|
141 EXPORT_C void TInternalRamDrive::Wait() |
|
142 { |
|
143 Kern::MutexWait(*Mutex); |
|
144 } |
|
145 |
|
146 EXPORT_C void TInternalRamDrive::Signal() |
|
147 { |
|
148 Kern::MutexSignal(*Mutex); |
|
149 } |
|
150 |
|
151 void ExecHandler::UnlockRamDrive() |
|
152 { |
|
153 } |
|
154 |
|
155 EXPORT_C void TInternalRamDrive::Unlock() |
|
156 {} |
|
157 |
|
158 EXPORT_C void TInternalRamDrive::Lock() |
|
159 {} |
|
160 |