|
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 "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 // wins\specific\variant.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 #include "variant.h" |
|
19 #include "mconf.h" |
|
20 #include <kernel/kern_priv.h> |
|
21 #include <stdlib.h> |
|
22 #include <property.h> |
|
23 #include <emulator.h> |
|
24 |
|
25 const TInt KDefaultRam = 63; // 63MB default internal RAM |
|
26 const TInt KUnlimitedRam = 0x400; // 1GB ~= unlimited memory |
|
27 const TInt KDefaultRamDrive = 0x400000; // 4MB default RAM drive limit |
|
28 |
|
29 _LIT(KLitWins,"Wins"); |
|
30 |
|
31 GLDEF_D Wins TheVariant; |
|
32 |
|
33 GLDEF_D TActualMachineConfig TheConfig; |
|
34 |
|
35 EXPORT_C Asic* VariantInitialise(TBool aRunExe) |
|
36 { |
|
37 return TheVariant.Init(aRunExe) == KErrNone ? &TheVariant : NULL; |
|
38 } |
|
39 |
|
40 void AsicInitialise() |
|
41 { |
|
42 } |
|
43 |
|
44 class DWinsPowerController : public DPowerController |
|
45 { |
|
46 public: // from DPowerComtroller |
|
47 void CpuIdle(); |
|
48 void EnableWakeupEvents(); |
|
49 void AbsoluteTimerExpired(); |
|
50 void DisableWakeupEvents(); |
|
51 void PowerDown(TTimeK aWakeupTime); |
|
52 public: |
|
53 static DWinsPowerController* New(); |
|
54 void AssertWakeupSignal(); |
|
55 void WakeupEvent(); |
|
56 private: |
|
57 HANDLE iStandbySem; |
|
58 TUint iStandby; |
|
59 TBool iWakeupSignal; |
|
60 }; |
|
61 |
|
62 Wins::Wins() |
|
63 :iUi(0), iRealCpuSpeed(0), iCpuSpeed(0), |
|
64 iDebugOutput(INVALID_HANDLE_VALUE), iLogTimeStamp(ETrue), |
|
65 iPurgedImages(EFalse), iPowerController(0), iLogToDebugger(EFalse), |
|
66 iLogToFile(ETrue) |
|
67 {} |
|
68 |
|
69 TInt Wins::Init(TBool aRunExe) |
|
70 { |
|
71 TInt r = InitProperties(aRunExe); |
|
72 if (r == KErrNone) |
|
73 { |
|
74 iProperties.GetInt("LogTimeStamp",iLogTimeStamp); |
|
75 TInt logThreadId=ETrue; |
|
76 iProperties.GetInt("LogThreadId",logThreadId); |
|
77 TInt cpu=NThread::ECpuSingle; |
|
78 iProperties.GetInt("HostCPU",cpu); |
|
79 NThread::SetProperties(logThreadId,cpu); |
|
80 iProperties.GetInt("LogToDebugger",iLogToDebugger); |
|
81 iProperties.GetInt("LogToFile",iLogToFile); |
|
82 |
|
83 TInt mask; |
|
84 Kern::SuperPage().iDebugMask[0] = DebugMask(); // get int or text mask value |
|
85 // check to see if DebugMask0 was used instead of DebugMask |
|
86 if ( (iProperties.GetInt("DebugMask", mask) != KErrNone) && |
|
87 (iProperties.GetInt("DebugMask0", mask) == KErrNone) ) |
|
88 Kern::SuperPage().iDebugMask[0] = ((iProperties.GetInt("DebugMask0", mask) == KErrNone) ? mask : 0); |
|
89 |
|
90 // only int entries are supported for DebugMasks 1-7 |
|
91 Kern::SuperPage().iDebugMask[1] = ((iProperties.GetInt("DebugMask1", mask) == KErrNone) ? mask : 0); |
|
92 Kern::SuperPage().iDebugMask[2] = ((iProperties.GetInt("DebugMask2", mask) == KErrNone) ? mask : 0); |
|
93 Kern::SuperPage().iDebugMask[3] = ((iProperties.GetInt("DebugMask3", mask) == KErrNone) ? mask : 0); |
|
94 Kern::SuperPage().iDebugMask[4] = ((iProperties.GetInt("DebugMask4", mask) == KErrNone) ? mask : 0); |
|
95 Kern::SuperPage().iDebugMask[5] = ((iProperties.GetInt("DebugMask5", mask) == KErrNone) ? mask : 0); |
|
96 Kern::SuperPage().iDebugMask[6] = ((iProperties.GetInt("DebugMask6", mask) == KErrNone) ? mask : 0); |
|
97 Kern::SuperPage().iDebugMask[7] = ((iProperties.GetInt("DebugMask7", mask) == KErrNone) ? mask : 0); |
|
98 |
|
99 // initial values for fast trace... |
|
100 Kern::SuperPage().iInitialBTraceFilter[0] = ((iProperties.GetInt("BTrace0", mask) == KErrNone) ? mask : 0); |
|
101 Kern::SuperPage().iInitialBTraceFilter[1] = ((iProperties.GetInt("BTrace1", mask) == KErrNone) ? mask : 0); |
|
102 Kern::SuperPage().iInitialBTraceFilter[2] = ((iProperties.GetInt("BTrace2", mask) == KErrNone) ? mask : 0); |
|
103 Kern::SuperPage().iInitialBTraceFilter[3] = ((iProperties.GetInt("BTrace3", mask) == KErrNone) ? mask : 0); |
|
104 Kern::SuperPage().iInitialBTraceFilter[4] = ((iProperties.GetInt("BTrace4", mask) == KErrNone) ? mask : 0); |
|
105 Kern::SuperPage().iInitialBTraceFilter[5] = ((iProperties.GetInt("BTrace5", mask) == KErrNone) ? mask : 0); |
|
106 Kern::SuperPage().iInitialBTraceFilter[6] = ((iProperties.GetInt("BTrace6", mask) == KErrNone) ? mask : 0); |
|
107 Kern::SuperPage().iInitialBTraceFilter[7] = ((iProperties.GetInt("BTrace7", mask) == KErrNone) ? mask : 0); |
|
108 Kern::SuperPage().iInitialBTraceBuffer = ((iProperties.GetInt("BTraceBuffer", mask) == KErrNone) ? mask : 0); |
|
109 Kern::SuperPage().iInitialBTraceMode = ((iProperties.GetInt("BTraceMode", mask) == KErrNone) ? mask : 0); |
|
110 |
|
111 Kern::SuperPage().SetKernelConfigFlags(KernelConfigFlags()); |
|
112 |
|
113 SCapabilitySet caps; |
|
114 DisabledCapabilities(caps); |
|
115 memcpy(&Kern::SuperPage().iDisabledCapabilities,&caps,sizeof(caps)); |
|
116 } |
|
117 CalibrateCpuSpeed(); |
|
118 return r; |
|
119 } |
|
120 |
|
121 inline void Wins::InstallUi(DWinsUiBase& aUi) |
|
122 {iUi = &aUi;} |
|
123 |
|
124 void Wins::Init1() |
|
125 { |
|
126 __KTRACE_OPT(KBOOT,Kern::Printf("Wins::Init1()")); |
|
127 |
|
128 TInt tickperiod = WinsTimer::EDefaultPeriod; |
|
129 iProperties.GetInt("TimerResolution",tickperiod); |
|
130 iTimer.Init(tickperiod); |
|
131 TUint speed; |
|
132 if (iProperties.GetInt("CPUSpeed", (TInt&)speed) == KErrNone) |
|
133 SetCpuSpeed(speed); |
|
134 } |
|
135 |
|
136 static TInt emulatorHal(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2) |
|
137 { |
|
138 return ((Wins*)aPtr)->EmulatorHal(aFunction, a1, a2); |
|
139 } |
|
140 |
|
141 void Wins::Init3() |
|
142 // |
|
143 // Initialise timer tick and add emulator hal function |
|
144 // |
|
145 { |
|
146 __KTRACE_OPT(KBOOT,Kern::Printf("Wins::Init3()")); |
|
147 |
|
148 Kern::AddHalEntry(EHalGroupEmulator,&emulatorHal,this); |
|
149 |
|
150 iPowerController = DWinsPowerController::New(); |
|
151 if (iPowerController == 0) |
|
152 __PM_PANIC("Can't create 'DWinsPowerController'"); |
|
153 |
|
154 iTimer.Enable(); |
|
155 } |
|
156 |
|
157 void Wins::AddressInfo(SAddressInfo& aInfo) |
|
158 { |
|
159 TInt megabytes = KDefaultRam; |
|
160 iProperties.GetInt("MegabytesOfFreeMemory", megabytes); |
|
161 if (megabytes == 0) |
|
162 megabytes = KUnlimitedRam; |
|
163 aInfo.iTotalRamSize = megabytes << 20; |
|
164 // |
|
165 TInt ramdisk = KDefaultRamDrive; |
|
166 iProperties.GetInt("RamDriveMaxSize", ramdisk); |
|
167 aInfo.iRamDriveMaxSize = ramdisk; |
|
168 } |
|
169 |
|
170 void Wins::PurgeImages() |
|
171 // |
|
172 // Use the idle thread to clean up remnants of the emulator from the image path |
|
173 // |
|
174 { |
|
175 char path[KMaxFileName+1]; |
|
176 |
|
177 const char* imgPath=0; |
|
178 iProperties.GetString("EmulatorImagePath", imgPath); |
|
179 strcpy(path, imgPath); |
|
180 char* name = path +strlen(path); |
|
181 strcpy(name,"*"); |
|
182 |
|
183 Emulator::Lock(); |
|
184 |
|
185 WIN32_FIND_DATAA fdata; |
|
186 HANDLE finder = FindFirstFileA(path, &fdata); |
|
187 if (finder != INVALID_HANDLE_VALUE) |
|
188 { |
|
189 do |
|
190 { |
|
191 if ((fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) |
|
192 { |
|
193 strcpy(name, fdata.cFileName); |
|
194 DeleteFileA(path); |
|
195 } |
|
196 } while (FindNextFileA(finder, &fdata)); |
|
197 FindClose(finder); |
|
198 } |
|
199 |
|
200 Emulator::Unlock(); |
|
201 } |
|
202 |
|
203 void Wins::Idle() |
|
204 // |
|
205 // Use the win32 NKern idle function |
|
206 // |
|
207 { |
|
208 iTimer.SetIdleThread(); |
|
209 if (!iPurgedImages) |
|
210 { |
|
211 PurgeImages(); |
|
212 iPurgedImages = ETrue; |
|
213 } |
|
214 NThread::Idle(); |
|
215 } |
|
216 |
|
217 TInt Wins::MsTickPeriod() |
|
218 // |
|
219 // Provide the 'millisecond' timer tick period in microseconds |
|
220 // |
|
221 { |
|
222 return 1000 * iTimer.Period(); |
|
223 } |
|
224 |
|
225 TInt Wins::SystemTimeInSecondsFrom2000(TInt& aTime) |
|
226 { |
|
227 aTime = iTimer.SystemTime(); |
|
228 __KTRACE_OPT(KHARDWARE,Kern::Printf("RTC READ: %d",aTime)); |
|
229 return KErrNone; |
|
230 } |
|
231 |
|
232 TInt Wins::SetSystemTimeInSecondsFrom2000(TInt aTime) |
|
233 // |
|
234 // Set the emulator time. We must not change the Win32 time so |
|
235 // we just adjust the offset value to account for the difference |
|
236 // |
|
237 { |
|
238 __KTRACE_OPT(KHARDWARE,Kern::Printf("Set RTC: %d",aTime)); |
|
239 iTimer.SetSystemTime(aTime); |
|
240 return KErrNone; |
|
241 } |
|
242 |
|
243 TInt Wins::VariantHal(TInt aFunction, TAny* a1, TAny* /*a2*/) |
|
244 { |
|
245 TInt r=KErrNone; |
|
246 switch(aFunction) |
|
247 { |
|
248 case EVariantHalVariantInfo: |
|
249 { |
|
250 TVariantInfoV01Buf infoBuf; |
|
251 TVariantInfoV01& info=infoBuf(); |
|
252 |
|
253 // info.iRomVersion=TVersion(KRomMajorVersionNumber,KRomMinorVersionNumber,KRomBuildVersionNumber); |
|
254 info.iMachineUniqueId=0; |
|
255 info.iLedCapabilities=0x0; |
|
256 info.iProcessorClockInKHz=iCpuSpeed ? iCpuSpeed*1000 : 1; |
|
257 info.iSpeedFactor=0; |
|
258 if (iUi) |
|
259 iUi->Info(info); |
|
260 |
|
261 Kern::InfoCopy(*(TDes8*)a1,infoBuf); |
|
262 break; |
|
263 } |
|
264 |
|
265 case EVariantHalCustomRestartReason: |
|
266 { |
|
267 //This will take value from c:\data\epoc.ini. |
|
268 TInt x = Property::GetInt("CustomRestartReason"); |
|
269 kumemput32(a1, &x, sizeof(TInt)); |
|
270 } |
|
271 break; |
|
272 |
|
273 case EVariantHalCustomRestart: |
|
274 { |
|
275 if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EVariantHalCustomRestart"))) |
|
276 return KErrPermissionDenied; |
|
277 //This will only shut down epoc as Custom Restart Reason is not supported on wins. |
|
278 Kern::Restart((TInt)a1); |
|
279 break; |
|
280 } |
|
281 |
|
282 default: |
|
283 r=KErrNotSupported; |
|
284 break; |
|
285 } |
|
286 return r; |
|
287 } |
|
288 |
|
289 TPtr8 Wins::MachineConfiguration() |
|
290 { |
|
291 return TPckg<TActualMachineConfig>(TheConfig); |
|
292 } |
|
293 |
|
294 void Wins::CalibrateCpuSpeed() |
|
295 // |
|
296 // calculate approx. CPU speed in MHz, 0 if we can't tell |
|
297 // |
|
298 { |
|
299 TInt cycleCount =200*1000*20; //take 20ms at 20MHz |
|
300 |
|
301 // This loop will double the cyclecount until the difference is non-zero. |
|
302 FOREVER |
|
303 { |
|
304 if (cycleCount > (KMaxTUint / 2)) |
|
305 { |
|
306 break; |
|
307 } |
|
308 |
|
309 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); |
|
310 LARGE_INTEGER start; |
|
311 if (QueryPerformanceCounter(&start)) |
|
312 { |
|
313 __asm mov eax, cycleCount |
|
314 noploop: |
|
315 __asm dec eax |
|
316 __asm dec eax |
|
317 __asm dec eax |
|
318 __asm dec eax |
|
319 __asm dec eax |
|
320 __asm dec eax |
|
321 __asm dec eax |
|
322 __asm dec eax |
|
323 __asm dec eax |
|
324 __asm dec eax |
|
325 __asm dec eax |
|
326 __asm dec eax |
|
327 __asm dec eax |
|
328 __asm dec eax |
|
329 __asm dec eax |
|
330 __asm dec eax |
|
331 __asm dec eax |
|
332 __asm dec eax |
|
333 __asm dec eax |
|
334 __asm dec eax |
|
335 __asm dec eax |
|
336 __asm dec eax |
|
337 __asm dec eax |
|
338 __asm dec eax |
|
339 __asm dec eax |
|
340 __asm dec eax |
|
341 __asm dec eax |
|
342 __asm dec eax |
|
343 __asm dec eax |
|
344 __asm dec eax |
|
345 __asm dec eax |
|
346 __asm dec eax |
|
347 __asm dec eax |
|
348 __asm dec eax |
|
349 __asm dec eax |
|
350 __asm dec eax |
|
351 __asm dec eax |
|
352 __asm dec eax |
|
353 __asm dec eax |
|
354 __asm dec eax |
|
355 __asm dec eax |
|
356 __asm dec eax |
|
357 __asm dec eax |
|
358 __asm dec eax |
|
359 __asm dec eax |
|
360 __asm dec eax |
|
361 __asm dec eax |
|
362 __asm dec eax |
|
363 __asm sub eax, 2 |
|
364 __asm jnz noploop |
|
365 // |
|
366 LARGE_INTEGER end; |
|
367 QueryPerformanceCounter(&end); |
|
368 LARGE_INTEGER f; |
|
369 QueryPerformanceFrequency(&f); |
|
370 |
|
371 TInt64 diff = (end.QuadPart - start.QuadPart); |
|
372 if(diff!=0) |
|
373 { |
|
374 TInt64 hz = (TInt64(cycleCount) / 1000000) * (f.QuadPart / diff); |
|
375 iRealCpuSpeed = (TUint)(hz); |
|
376 break; |
|
377 } |
|
378 } |
|
379 cycleCount *= 2; // Double the count!! |
|
380 } |
|
381 |
|
382 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); |
|
383 } |
|
384 |
|
385 TInt Wins::SetCpuSpeed(TUint aSpeed) |
|
386 { |
|
387 if (iRealCpuSpeed == 0) |
|
388 return KErrNotSupported; // don't know the real CPUSpeed |
|
389 |
|
390 if (IsDebuggerPresent()) |
|
391 return KErrGeneral; // nobbling not avaliable when debugging |
|
392 |
|
393 if (aSpeed == 0) |
|
394 aSpeed = iRealCpuSpeed; // reset to maximum |
|
395 else if (aSpeed > iRealCpuSpeed) |
|
396 aSpeed = iRealCpuSpeed; |
|
397 else if (aSpeed * 20u < iRealCpuSpeed) |
|
398 aSpeed = (iRealCpuSpeed + 19u) / 20u; |
|
399 |
|
400 __KTRACE_OPT(KHARDWARE,Kern::Printf("Set CPUSpeed: %d",aSpeed)); |
|
401 iCpuSpeed = aSpeed; |
|
402 |
|
403 // calculate CPU time to nobble in parts-per-million |
|
404 TUint nobble = ((iRealCpuSpeed - aSpeed) * 1000000u) / iRealCpuSpeed; |
|
405 iTimer.Nobble(nobble); |
|
406 return KErrNone; |
|
407 } |
|
408 |
|
409 HANDLE Wins::DebugOutput() |
|
410 // |
|
411 // Return a handle to the trace file, creating the file if required. |
|
412 // |
|
413 // The log file name can be specified by a property or environment |
|
414 // variable called 'EmulatorLog', otherwise it defaults to |
|
415 // 'epocwind.out' in the temporary directory. |
|
416 // |
|
417 { |
|
418 HANDLE file = iDebugOutput; |
|
419 if (file == INVALID_HANDLE_VALUE) |
|
420 { |
|
421 CHAR debugfile[MAX_PATH]; |
|
422 const char* logpath; |
|
423 if (iProperties.GetString("EmulatorLog",logpath)==KErrNone) |
|
424 strcpy(debugfile,logpath); |
|
425 else |
|
426 { |
|
427 DWORD len = GetEnvironmentVariableA("EmulatorLog", debugfile, MAX_PATH); |
|
428 debugfile[len]=0; |
|
429 if (len == 0) |
|
430 { |
|
431 len=GetTempPathA(MAX_PATH,debugfile); |
|
432 strcpy(debugfile+len,"epocwind.out"); // EPOC WINS DEBUG output file |
|
433 } |
|
434 } |
|
435 file=CreateFileA(debugfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, NULL, NULL); |
|
436 if (file!=INVALID_HANDLE_VALUE) |
|
437 { |
|
438 SetFilePointer(file, NULL, NULL, FILE_END); |
|
439 iDebugOutput = file; |
|
440 } |
|
441 } |
|
442 return file; |
|
443 } |
|
444 |
|
445 const TInt MaxOutputMsg = 599; |
|
446 |
|
447 void Wins::EarlyLogging(const char* aMessage1,const char* aMessage2) |
|
448 { |
|
449 char message[MaxOutputMsg+3]; |
|
450 TInt len = min(strlen(aMessage1), MaxOutputMsg); |
|
451 memcpy(message,aMessage1,len); |
|
452 if(aMessage2) |
|
453 { |
|
454 TInt len2 = min((TInt)strlen(aMessage2), MaxOutputMsg-len); |
|
455 memcpy(message+len,aMessage2,len2); |
|
456 len+=len2; |
|
457 } |
|
458 message[len++] = '\r'; |
|
459 message[len++] = '\n'; |
|
460 message[len] = 0; |
|
461 |
|
462 if (iLogToFile) |
|
463 { |
|
464 DWORD bytes; |
|
465 WriteFile(DebugOutput(), message, len, &bytes, NULL); |
|
466 } |
|
467 if (iLogToDebugger) |
|
468 { |
|
469 OutputDebugStringA(message); |
|
470 } |
|
471 } |
|
472 |
|
473 void Wins::DebugPrint(const TDesC8& aDes) |
|
474 // |
|
475 // Send the string to the debug output (Win32 debug trace) and trace file |
|
476 // |
|
477 { |
|
478 char message[MaxOutputMsg+1]; |
|
479 TInt len = aDes.Length(); |
|
480 const char* ptr = (const char*)aDes.Ptr(); |
|
481 if (iLogTimeStamp) |
|
482 { |
|
483 strcpy(message," "); |
|
484 _ultoa(NKern::TickCount() * iTimer.Period(), message + 10, 10); |
|
485 int n = strlen(message); |
|
486 len = min(len, MaxOutputMsg - n - 2); |
|
487 char* msg = message + n; |
|
488 msg[0] = msg[-1]; |
|
489 msg[-1] = n < 10+2 ? '0' : msg[-2]; |
|
490 msg[-2] = n < 10+3 ? '0' : msg[-3]; |
|
491 msg[-3] = '.'; |
|
492 if (n < 10+4) |
|
493 msg[-4] = '0'; |
|
494 ++msg; |
|
495 *msg++ = '\t'; |
|
496 strncpy(msg, ptr, len); |
|
497 msg[len] = 0; |
|
498 ptr = msg - 11; |
|
499 len += 11; |
|
500 } |
|
501 else |
|
502 { |
|
503 len = min(len, MaxOutputMsg); |
|
504 strncpy(message, ptr, len); |
|
505 message[len] = 0; |
|
506 ptr = message; |
|
507 } |
|
508 TInt irq = NKern::DisableAllInterrupts(); |
|
509 if (iLogToFile) |
|
510 { |
|
511 DWORD bytes; |
|
512 WriteFile(DebugOutput(), ptr, len, &bytes, NULL); |
|
513 } |
|
514 if (iLogToDebugger) |
|
515 { |
|
516 OutputDebugStringA(message); |
|
517 } |
|
518 |
|
519 NKern::RestoreInterrupts(irq); |
|
520 } |
|
521 |
|
522 const char* const KErrorTitles[] = |
|
523 { |
|
524 "Symbian OS Fatal Error", |
|
525 "Symbian OS Application Error" |
|
526 }; |
|
527 |
|
528 const TText8* const KErrorMsg[] = |
|
529 { |
|
530 _S8("An error has been detected in the Symbian OS emulator."), |
|
531 _S8("A call to User::Panic() has occured, indicating\n" |
|
532 "a programming fault in the running application.\n" |
|
533 "Please refer to the documentation for more details.") |
|
534 }; |
|
535 |
|
536 _LIT8(KProgram, "\n\nProgram\t"); |
|
537 _LIT8(KError, "\nError\t"); |
|
538 _LIT8(KIDFC, "an IDFC"); |
|
539 _LIT8(KEscaped, "an escaped thread"); |
|
540 _LIT8(KInterrupt, "an interrupt thread"); |
|
541 _LIT8(KNThread, "an NThread"); |
|
542 _LIT8(KColon, " : "); |
|
543 _LIT8(KDebugQuery, "\n\nDo you wish to Debug the error?\0"); |
|
544 |
|
545 TBool Wins::ErrorDialog(TError aType, const TDesC8& aPanic, TInt aVal) |
|
546 { |
|
547 // Must be called with interrupts enabled to allow thread running windows message loop to run |
|
548 |
|
549 TBuf8<512> message(KErrorMsg[aType]); |
|
550 message.Append(KProgram); |
|
551 TInt context = NKern::CurrentContext(); |
|
552 switch(context) |
|
553 { |
|
554 case NKern::EIDFC: |
|
555 message.Append(KIDFC); |
|
556 break; |
|
557 case NKern::EEscaped: |
|
558 message.Append(KEscaped); |
|
559 break; |
|
560 case NKern::EInterrupt: |
|
561 message.Append(KInterrupt); |
|
562 break; |
|
563 case NKern::EThread: |
|
564 DThread *thread = Kern::NThreadToDThread(NKern::CurrentThread()); |
|
565 if (thread) |
|
566 thread->TraceAppendFullName(message, ETrue); |
|
567 else |
|
568 message.Append(KNThread); |
|
569 break; |
|
570 } |
|
571 message.Append(KError); |
|
572 message.Append(aPanic); |
|
573 message.Append(KColon); |
|
574 message.AppendNum(aVal); |
|
575 #ifdef _DEBUG |
|
576 message.Append(KDebugQuery); |
|
577 UINT type = MB_YESNO | MB_DEFBUTTON2; |
|
578 #else |
|
579 UINT type = MB_OK; |
|
580 #endif |
|
581 type |= MB_SETFOREGROUND | MB_ICONERROR; |
|
582 message.Append('\0'); |
|
583 |
|
584 TInt r = MessageBoxA(iUi ? iUi->HWnd() : NULL, (LPCSTR)message.Ptr(), KErrorTitles[aType], type); |
|
585 return r == IDYES; |
|
586 } |
|
587 |
|
588 // UI installation |
|
589 |
|
590 EXPORT_C DWinsUiBase::DWinsUiBase() |
|
591 { |
|
592 TheVariant.InstallUi(*this); |
|
593 } |
|
594 |
|
595 |
|
596 TInt BinaryPowerInit(); |
|
597 |
|
598 DWinsPowerController* DWinsPowerController::New() |
|
599 { |
|
600 DWinsPowerController* self = new DWinsPowerController(); |
|
601 if (!self) |
|
602 return NULL; |
|
603 self->iStandbySem = CreateSemaphore(NULL, 0, 1, NULL); |
|
604 if (self->iStandbySem == NULL) |
|
605 return NULL; |
|
606 TInt r = BinaryPowerInit(); |
|
607 if (r != KErrNone) |
|
608 return NULL; |
|
609 self->Register(); |
|
610 return self; |
|
611 } |
|
612 |
|
613 void DWinsPowerController::CpuIdle() |
|
614 { |
|
615 Arch::TheAsic()->Idle(); |
|
616 } |
|
617 |
|
618 void DWinsPowerController::EnableWakeupEvents() |
|
619 { |
|
620 iWakeupSignal = EFalse; |
|
621 } |
|
622 |
|
623 void DWinsPowerController::DisableWakeupEvents() |
|
624 { |
|
625 } |
|
626 |
|
627 void DWinsPowerController::AbsoluteTimerExpired() |
|
628 { |
|
629 if (iTargetState == EPwStandby) |
|
630 DWinsPowerController::WakeupEvent(); |
|
631 } |
|
632 |
|
633 void DWinsPowerController::WakeupEvent() |
|
634 { |
|
635 if (iTargetState == EPwStandby) |
|
636 { |
|
637 iWakeupSignal = ETrue; |
|
638 DPowerController::WakeupEvent(); |
|
639 } |
|
640 } |
|
641 |
|
642 // called in Epoc thread |
|
643 void DWinsPowerController::PowerDown(TTimeK aWakeupTime) |
|
644 { |
|
645 if (iTargetState == EPwStandby) |
|
646 { |
|
647 UINT timeoutMs; |
|
648 if (aWakeupTime == 0) |
|
649 timeoutMs = INFINITE; |
|
650 else |
|
651 { |
|
652 TTimeK now = Kern::SystemTime(); |
|
653 if (now > aWakeupTime) |
|
654 timeoutMs = 0; |
|
655 else |
|
656 timeoutMs = (UINT)((aWakeupTime - now) / 1000); |
|
657 } |
|
658 TInt l = NKern::DisableAllInterrupts(); |
|
659 if (!iWakeupSignal && timeoutMs) |
|
660 { |
|
661 iStandby = ETrue; |
|
662 TheVariant.iTimer.Standby(); |
|
663 NKern::RestoreInterrupts(l); |
|
664 DWORD r = WaitForSingleObject(iStandbySem, timeoutMs); |
|
665 if (r == WAIT_TIMEOUT) |
|
666 { |
|
667 l = NKern::DisableAllInterrupts(); |
|
668 if (!iStandby) |
|
669 WaitForSingleObject(iStandbySem, INFINITE); |
|
670 else |
|
671 iStandby = EFalse; |
|
672 NKern::RestoreInterrupts(l); |
|
673 } |
|
674 TheVariant.iTimer.Wakeup(); |
|
675 } |
|
676 else |
|
677 NKern::RestoreInterrupts(l); |
|
678 |
|
679 } |
|
680 else |
|
681 Kern::Restart(0x80000000); |
|
682 } |
|
683 |
|
684 // called in the interrupt context |
|
685 void DWinsPowerController::AssertWakeupSignal() |
|
686 { |
|
687 iWakeupSignal = ETrue; |
|
688 if (iStandby) |
|
689 { |
|
690 iStandby = EFalse; |
|
691 ReleaseSemaphore(iStandbySem, 1, NULL); |
|
692 } |
|
693 } |
|
694 |
|
695 |
|
696 EXPORT_C void Wins::AssertWakeupSignal() |
|
697 { |
|
698 iPowerController->AssertWakeupSignal(); |
|
699 } |
|
700 |
|
701 EXPORT_C void Wins::WakeupEvent() |
|
702 { |
|
703 iPowerController->DWinsPowerController::WakeupEvent(); |
|
704 } |
|
705 |
|
706 // MMC emulation support |
|
707 |
|
708 TBool Wins::MediaDoorOpen; |
|
709 TInt Wins::CurrentPBusDevice; |
|
710 TAny* Wins::MediaChangeCallbackParam; |
|
711 TMediaChangeCallBack Wins::MediaChangeCallBackPtr; |
|
712 |
|
713 |
|
714 EXPORT_C TBool* Wins::MediaDoorOpenPtr() |
|
715 // |
|
716 // For media change simulation |
|
717 // |
|
718 { |
|
719 |
|
720 return(&MediaDoorOpen); |
|
721 } |
|
722 |
|
723 EXPORT_C TInt* Wins::CurrentPBusDevicePtr() |
|
724 // |
|
725 // For media change simulation |
|
726 // |
|
727 { |
|
728 |
|
729 return(&CurrentPBusDevice); |
|
730 } |
|
731 |
|
732 EXPORT_C void Wins::SetMediaChangeCallBackPtr(TMediaChangeCallBack aPtr, TAny* aMediaChangeCallbackParam) |
|
733 // |
|
734 // For media change simulation |
|
735 // |
|
736 { |
|
737 MediaChangeCallbackParam=aMediaChangeCallbackParam; |
|
738 MediaChangeCallBackPtr=aPtr; |
|
739 } |
|
740 |
|
741 EXPORT_C void Wins::MediaChangeCallBack() |
|
742 // |
|
743 // Perform the simulated media change callback |
|
744 // |
|
745 { |
|
746 if(MediaChangeCallBackPtr) |
|
747 (*MediaChangeCallBackPtr)(MediaChangeCallbackParam); |
|
748 } |