1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/boardsupport/emulator/emulatorbsp/specific/variant.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,748 @@
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 "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 +// wins\specific\variant.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include "variant.h"
1.22 +#include "mconf.h"
1.23 +#include <kernel/kern_priv.h>
1.24 +#include <stdlib.h>
1.25 +#include <property.h>
1.26 +#include <emulator.h>
1.27 +
1.28 +const TInt KDefaultRam = 63; // 63MB default internal RAM
1.29 +const TInt KUnlimitedRam = 0x400; // 1GB ~= unlimited memory
1.30 +const TInt KDefaultRamDrive = 0x400000; // 4MB default RAM drive limit
1.31 +
1.32 +_LIT(KLitWins,"Wins");
1.33 +
1.34 +GLDEF_D Wins TheVariant;
1.35 +
1.36 +GLDEF_D TActualMachineConfig TheConfig;
1.37 +
1.38 +EXPORT_C Asic* VariantInitialise(TBool aRunExe)
1.39 + {
1.40 + return TheVariant.Init(aRunExe) == KErrNone ? &TheVariant : NULL;
1.41 + }
1.42 +
1.43 +void AsicInitialise()
1.44 + {
1.45 + }
1.46 +
1.47 +class DWinsPowerController : public DPowerController
1.48 + {
1.49 +public: // from DPowerComtroller
1.50 + void CpuIdle();
1.51 + void EnableWakeupEvents();
1.52 + void AbsoluteTimerExpired();
1.53 + void DisableWakeupEvents();
1.54 + void PowerDown(TTimeK aWakeupTime);
1.55 +public:
1.56 + static DWinsPowerController* New();
1.57 + void AssertWakeupSignal();
1.58 + void WakeupEvent();
1.59 +private:
1.60 + HANDLE iStandbySem;
1.61 + TUint iStandby;
1.62 + TBool iWakeupSignal;
1.63 + };
1.64 +
1.65 +Wins::Wins()
1.66 + :iUi(0), iRealCpuSpeed(0), iCpuSpeed(0),
1.67 + iDebugOutput(INVALID_HANDLE_VALUE), iLogTimeStamp(ETrue),
1.68 + iPurgedImages(EFalse), iPowerController(0), iLogToDebugger(EFalse),
1.69 + iLogToFile(ETrue)
1.70 + {}
1.71 +
1.72 +TInt Wins::Init(TBool aRunExe)
1.73 + {
1.74 + TInt r = InitProperties(aRunExe);
1.75 + if (r == KErrNone)
1.76 + {
1.77 + iProperties.GetInt("LogTimeStamp",iLogTimeStamp);
1.78 + TInt logThreadId=ETrue;
1.79 + iProperties.GetInt("LogThreadId",logThreadId);
1.80 + TInt cpu=NThread::ECpuSingle;
1.81 + iProperties.GetInt("HostCPU",cpu);
1.82 + NThread::SetProperties(logThreadId,cpu);
1.83 + iProperties.GetInt("LogToDebugger",iLogToDebugger);
1.84 + iProperties.GetInt("LogToFile",iLogToFile);
1.85 +
1.86 + TInt mask;
1.87 + Kern::SuperPage().iDebugMask[0] = DebugMask(); // get int or text mask value
1.88 + // check to see if DebugMask0 was used instead of DebugMask
1.89 + if ( (iProperties.GetInt("DebugMask", mask) != KErrNone) &&
1.90 + (iProperties.GetInt("DebugMask0", mask) == KErrNone) )
1.91 + Kern::SuperPage().iDebugMask[0] = ((iProperties.GetInt("DebugMask0", mask) == KErrNone) ? mask : 0);
1.92 +
1.93 + // only int entries are supported for DebugMasks 1-7
1.94 + Kern::SuperPage().iDebugMask[1] = ((iProperties.GetInt("DebugMask1", mask) == KErrNone) ? mask : 0);
1.95 + Kern::SuperPage().iDebugMask[2] = ((iProperties.GetInt("DebugMask2", mask) == KErrNone) ? mask : 0);
1.96 + Kern::SuperPage().iDebugMask[3] = ((iProperties.GetInt("DebugMask3", mask) == KErrNone) ? mask : 0);
1.97 + Kern::SuperPage().iDebugMask[4] = ((iProperties.GetInt("DebugMask4", mask) == KErrNone) ? mask : 0);
1.98 + Kern::SuperPage().iDebugMask[5] = ((iProperties.GetInt("DebugMask5", mask) == KErrNone) ? mask : 0);
1.99 + Kern::SuperPage().iDebugMask[6] = ((iProperties.GetInt("DebugMask6", mask) == KErrNone) ? mask : 0);
1.100 + Kern::SuperPage().iDebugMask[7] = ((iProperties.GetInt("DebugMask7", mask) == KErrNone) ? mask : 0);
1.101 +
1.102 + // initial values for fast trace...
1.103 + Kern::SuperPage().iInitialBTraceFilter[0] = ((iProperties.GetInt("BTrace0", mask) == KErrNone) ? mask : 0);
1.104 + Kern::SuperPage().iInitialBTraceFilter[1] = ((iProperties.GetInt("BTrace1", mask) == KErrNone) ? mask : 0);
1.105 + Kern::SuperPage().iInitialBTraceFilter[2] = ((iProperties.GetInt("BTrace2", mask) == KErrNone) ? mask : 0);
1.106 + Kern::SuperPage().iInitialBTraceFilter[3] = ((iProperties.GetInt("BTrace3", mask) == KErrNone) ? mask : 0);
1.107 + Kern::SuperPage().iInitialBTraceFilter[4] = ((iProperties.GetInt("BTrace4", mask) == KErrNone) ? mask : 0);
1.108 + Kern::SuperPage().iInitialBTraceFilter[5] = ((iProperties.GetInt("BTrace5", mask) == KErrNone) ? mask : 0);
1.109 + Kern::SuperPage().iInitialBTraceFilter[6] = ((iProperties.GetInt("BTrace6", mask) == KErrNone) ? mask : 0);
1.110 + Kern::SuperPage().iInitialBTraceFilter[7] = ((iProperties.GetInt("BTrace7", mask) == KErrNone) ? mask : 0);
1.111 + Kern::SuperPage().iInitialBTraceBuffer = ((iProperties.GetInt("BTraceBuffer", mask) == KErrNone) ? mask : 0);
1.112 + Kern::SuperPage().iInitialBTraceMode = ((iProperties.GetInt("BTraceMode", mask) == KErrNone) ? mask : 0);
1.113 +
1.114 + Kern::SuperPage().SetKernelConfigFlags(KernelConfigFlags());
1.115 +
1.116 + SCapabilitySet caps;
1.117 + DisabledCapabilities(caps);
1.118 + memcpy(&Kern::SuperPage().iDisabledCapabilities,&caps,sizeof(caps));
1.119 + }
1.120 + CalibrateCpuSpeed();
1.121 + return r;
1.122 + }
1.123 +
1.124 +inline void Wins::InstallUi(DWinsUiBase& aUi)
1.125 + {iUi = &aUi;}
1.126 +
1.127 +void Wins::Init1()
1.128 + {
1.129 + __KTRACE_OPT(KBOOT,Kern::Printf("Wins::Init1()"));
1.130 +
1.131 + TInt tickperiod = WinsTimer::EDefaultPeriod;
1.132 + iProperties.GetInt("TimerResolution",tickperiod);
1.133 + iTimer.Init(tickperiod);
1.134 + TUint speed;
1.135 + if (iProperties.GetInt("CPUSpeed", (TInt&)speed) == KErrNone)
1.136 + SetCpuSpeed(speed);
1.137 + }
1.138 +
1.139 +static TInt emulatorHal(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
1.140 + {
1.141 + return ((Wins*)aPtr)->EmulatorHal(aFunction, a1, a2);
1.142 + }
1.143 +
1.144 +void Wins::Init3()
1.145 +//
1.146 +// Initialise timer tick and add emulator hal function
1.147 +//
1.148 + {
1.149 + __KTRACE_OPT(KBOOT,Kern::Printf("Wins::Init3()"));
1.150 +
1.151 + Kern::AddHalEntry(EHalGroupEmulator,&emulatorHal,this);
1.152 +
1.153 + iPowerController = DWinsPowerController::New();
1.154 + if (iPowerController == 0)
1.155 + __PM_PANIC("Can't create 'DWinsPowerController'");
1.156 +
1.157 + iTimer.Enable();
1.158 + }
1.159 +
1.160 +void Wins::AddressInfo(SAddressInfo& aInfo)
1.161 + {
1.162 + TInt megabytes = KDefaultRam;
1.163 + iProperties.GetInt("MegabytesOfFreeMemory", megabytes);
1.164 + if (megabytes == 0)
1.165 + megabytes = KUnlimitedRam;
1.166 + aInfo.iTotalRamSize = megabytes << 20;
1.167 +//
1.168 + TInt ramdisk = KDefaultRamDrive;
1.169 + iProperties.GetInt("RamDriveMaxSize", ramdisk);
1.170 + aInfo.iRamDriveMaxSize = ramdisk;
1.171 + }
1.172 +
1.173 +void Wins::PurgeImages()
1.174 +//
1.175 +// Use the idle thread to clean up remnants of the emulator from the image path
1.176 +//
1.177 + {
1.178 + char path[KMaxFileName+1];
1.179 +
1.180 + const char* imgPath=0;
1.181 + iProperties.GetString("EmulatorImagePath", imgPath);
1.182 + strcpy(path, imgPath);
1.183 + char* name = path +strlen(path);
1.184 + strcpy(name,"*");
1.185 +
1.186 + Emulator::Lock();
1.187 +
1.188 + WIN32_FIND_DATAA fdata;
1.189 + HANDLE finder = FindFirstFileA(path, &fdata);
1.190 + if (finder != INVALID_HANDLE_VALUE)
1.191 + {
1.192 + do
1.193 + {
1.194 + if ((fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
1.195 + {
1.196 + strcpy(name, fdata.cFileName);
1.197 + DeleteFileA(path);
1.198 + }
1.199 + } while (FindNextFileA(finder, &fdata));
1.200 + FindClose(finder);
1.201 + }
1.202 +
1.203 + Emulator::Unlock();
1.204 + }
1.205 +
1.206 +void Wins::Idle()
1.207 +//
1.208 +// Use the win32 NKern idle function
1.209 +//
1.210 + {
1.211 + iTimer.SetIdleThread();
1.212 + if (!iPurgedImages)
1.213 + {
1.214 + PurgeImages();
1.215 + iPurgedImages = ETrue;
1.216 + }
1.217 + NThread::Idle();
1.218 + }
1.219 +
1.220 +TInt Wins::MsTickPeriod()
1.221 +//
1.222 +// Provide the 'millisecond' timer tick period in microseconds
1.223 +//
1.224 + {
1.225 + return 1000 * iTimer.Period();
1.226 + }
1.227 +
1.228 +TInt Wins::SystemTimeInSecondsFrom2000(TInt& aTime)
1.229 + {
1.230 + aTime = iTimer.SystemTime();
1.231 + __KTRACE_OPT(KHARDWARE,Kern::Printf("RTC READ: %d",aTime));
1.232 + return KErrNone;
1.233 + }
1.234 +
1.235 +TInt Wins::SetSystemTimeInSecondsFrom2000(TInt aTime)
1.236 +//
1.237 +// Set the emulator time. We must not change the Win32 time so
1.238 +// we just adjust the offset value to account for the difference
1.239 +//
1.240 + {
1.241 + __KTRACE_OPT(KHARDWARE,Kern::Printf("Set RTC: %d",aTime));
1.242 + iTimer.SetSystemTime(aTime);
1.243 + return KErrNone;
1.244 + }
1.245 +
1.246 +TInt Wins::VariantHal(TInt aFunction, TAny* a1, TAny* /*a2*/)
1.247 + {
1.248 + TInt r=KErrNone;
1.249 + switch(aFunction)
1.250 + {
1.251 + case EVariantHalVariantInfo:
1.252 + {
1.253 + TVariantInfoV01Buf infoBuf;
1.254 + TVariantInfoV01& info=infoBuf();
1.255 +
1.256 +// info.iRomVersion=TVersion(KRomMajorVersionNumber,KRomMinorVersionNumber,KRomBuildVersionNumber);
1.257 + info.iMachineUniqueId=0;
1.258 + info.iLedCapabilities=0x0;
1.259 + info.iProcessorClockInKHz=iCpuSpeed ? iCpuSpeed*1000 : 1;
1.260 + info.iSpeedFactor=0;
1.261 + if (iUi)
1.262 + iUi->Info(info);
1.263 +
1.264 + Kern::InfoCopy(*(TDes8*)a1,infoBuf);
1.265 + break;
1.266 + }
1.267 +
1.268 + case EVariantHalCustomRestartReason:
1.269 + {
1.270 + //This will take value from c:\data\epoc.ini.
1.271 + TInt x = Property::GetInt("CustomRestartReason");
1.272 + kumemput32(a1, &x, sizeof(TInt));
1.273 + }
1.274 + break;
1.275 +
1.276 + case EVariantHalCustomRestart:
1.277 + {
1.278 + if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EVariantHalCustomRestart")))
1.279 + return KErrPermissionDenied;
1.280 + //This will only shut down epoc as Custom Restart Reason is not supported on wins.
1.281 + Kern::Restart((TInt)a1);
1.282 + break;
1.283 + }
1.284 +
1.285 + default:
1.286 + r=KErrNotSupported;
1.287 + break;
1.288 + }
1.289 + return r;
1.290 + }
1.291 +
1.292 +TPtr8 Wins::MachineConfiguration()
1.293 + {
1.294 + return TPckg<TActualMachineConfig>(TheConfig);
1.295 + }
1.296 +
1.297 +void Wins::CalibrateCpuSpeed()
1.298 +//
1.299 +// calculate approx. CPU speed in MHz, 0 if we can't tell
1.300 +//
1.301 + {
1.302 + TInt cycleCount =200*1000*20; //take 20ms at 20MHz
1.303 +
1.304 + // This loop will double the cyclecount until the difference is non-zero.
1.305 + FOREVER
1.306 + {
1.307 + if (cycleCount > (KMaxTUint / 2))
1.308 + {
1.309 + break;
1.310 + }
1.311 +
1.312 + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
1.313 + LARGE_INTEGER start;
1.314 + if (QueryPerformanceCounter(&start))
1.315 + {
1.316 + __asm mov eax, cycleCount
1.317 + noploop:
1.318 + __asm dec eax
1.319 + __asm dec eax
1.320 + __asm dec eax
1.321 + __asm dec eax
1.322 + __asm dec eax
1.323 + __asm dec eax
1.324 + __asm dec eax
1.325 + __asm dec eax
1.326 + __asm dec eax
1.327 + __asm dec eax
1.328 + __asm dec eax
1.329 + __asm dec eax
1.330 + __asm dec eax
1.331 + __asm dec eax
1.332 + __asm dec eax
1.333 + __asm dec eax
1.334 + __asm dec eax
1.335 + __asm dec eax
1.336 + __asm dec eax
1.337 + __asm dec eax
1.338 + __asm dec eax
1.339 + __asm dec eax
1.340 + __asm dec eax
1.341 + __asm dec eax
1.342 + __asm dec eax
1.343 + __asm dec eax
1.344 + __asm dec eax
1.345 + __asm dec eax
1.346 + __asm dec eax
1.347 + __asm dec eax
1.348 + __asm dec eax
1.349 + __asm dec eax
1.350 + __asm dec eax
1.351 + __asm dec eax
1.352 + __asm dec eax
1.353 + __asm dec eax
1.354 + __asm dec eax
1.355 + __asm dec eax
1.356 + __asm dec eax
1.357 + __asm dec eax
1.358 + __asm dec eax
1.359 + __asm dec eax
1.360 + __asm dec eax
1.361 + __asm dec eax
1.362 + __asm dec eax
1.363 + __asm dec eax
1.364 + __asm dec eax
1.365 + __asm dec eax
1.366 + __asm sub eax, 2
1.367 + __asm jnz noploop
1.368 + //
1.369 + LARGE_INTEGER end;
1.370 + QueryPerformanceCounter(&end);
1.371 + LARGE_INTEGER f;
1.372 + QueryPerformanceFrequency(&f);
1.373 +
1.374 + TInt64 diff = (end.QuadPart - start.QuadPart);
1.375 + if(diff!=0)
1.376 + {
1.377 + TInt64 hz = (TInt64(cycleCount) / 1000000) * (f.QuadPart / diff);
1.378 + iRealCpuSpeed = (TUint)(hz);
1.379 + break;
1.380 + }
1.381 + }
1.382 + cycleCount *= 2; // Double the count!!
1.383 + }
1.384 +
1.385 + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
1.386 + }
1.387 +
1.388 +TInt Wins::SetCpuSpeed(TUint aSpeed)
1.389 + {
1.390 + if (iRealCpuSpeed == 0)
1.391 + return KErrNotSupported; // don't know the real CPUSpeed
1.392 +
1.393 + if (IsDebuggerPresent())
1.394 + return KErrGeneral; // nobbling not avaliable when debugging
1.395 +
1.396 + if (aSpeed == 0)
1.397 + aSpeed = iRealCpuSpeed; // reset to maximum
1.398 + else if (aSpeed > iRealCpuSpeed)
1.399 + aSpeed = iRealCpuSpeed;
1.400 + else if (aSpeed * 20u < iRealCpuSpeed)
1.401 + aSpeed = (iRealCpuSpeed + 19u) / 20u;
1.402 +
1.403 + __KTRACE_OPT(KHARDWARE,Kern::Printf("Set CPUSpeed: %d",aSpeed));
1.404 + iCpuSpeed = aSpeed;
1.405 +
1.406 + // calculate CPU time to nobble in parts-per-million
1.407 + TUint nobble = ((iRealCpuSpeed - aSpeed) * 1000000u) / iRealCpuSpeed;
1.408 + iTimer.Nobble(nobble);
1.409 + return KErrNone;
1.410 + }
1.411 +
1.412 +HANDLE Wins::DebugOutput()
1.413 +//
1.414 +// Return a handle to the trace file, creating the file if required.
1.415 +//
1.416 +// The log file name can be specified by a property or environment
1.417 +// variable called 'EmulatorLog', otherwise it defaults to
1.418 +// 'epocwind.out' in the temporary directory.
1.419 +//
1.420 + {
1.421 + HANDLE file = iDebugOutput;
1.422 + if (file == INVALID_HANDLE_VALUE)
1.423 + {
1.424 + CHAR debugfile[MAX_PATH];
1.425 + const char* logpath;
1.426 + if (iProperties.GetString("EmulatorLog",logpath)==KErrNone)
1.427 + strcpy(debugfile,logpath);
1.428 + else
1.429 + {
1.430 + DWORD len = GetEnvironmentVariableA("EmulatorLog", debugfile, MAX_PATH);
1.431 + debugfile[len]=0;
1.432 + if (len == 0)
1.433 + {
1.434 + len=GetTempPathA(MAX_PATH,debugfile);
1.435 + strcpy(debugfile+len,"epocwind.out"); // EPOC WINS DEBUG output file
1.436 + }
1.437 + }
1.438 + file=CreateFileA(debugfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, NULL, NULL);
1.439 + if (file!=INVALID_HANDLE_VALUE)
1.440 + {
1.441 + SetFilePointer(file, NULL, NULL, FILE_END);
1.442 + iDebugOutput = file;
1.443 + }
1.444 + }
1.445 + return file;
1.446 + }
1.447 +
1.448 +const TInt MaxOutputMsg = 599;
1.449 +
1.450 +void Wins::EarlyLogging(const char* aMessage1,const char* aMessage2)
1.451 + {
1.452 + char message[MaxOutputMsg+3];
1.453 + TInt len = min(strlen(aMessage1), MaxOutputMsg);
1.454 + memcpy(message,aMessage1,len);
1.455 + if(aMessage2)
1.456 + {
1.457 + TInt len2 = min((TInt)strlen(aMessage2), MaxOutputMsg-len);
1.458 + memcpy(message+len,aMessage2,len2);
1.459 + len+=len2;
1.460 + }
1.461 + message[len++] = '\r';
1.462 + message[len++] = '\n';
1.463 + message[len] = 0;
1.464 +
1.465 + if (iLogToFile)
1.466 + {
1.467 + DWORD bytes;
1.468 + WriteFile(DebugOutput(), message, len, &bytes, NULL);
1.469 + }
1.470 + if (iLogToDebugger)
1.471 + {
1.472 + OutputDebugStringA(message);
1.473 + }
1.474 + }
1.475 +
1.476 +void Wins::DebugPrint(const TDesC8& aDes)
1.477 +//
1.478 +// Send the string to the debug output (Win32 debug trace) and trace file
1.479 +//
1.480 + {
1.481 + char message[MaxOutputMsg+1];
1.482 + TInt len = aDes.Length();
1.483 + const char* ptr = (const char*)aDes.Ptr();
1.484 + if (iLogTimeStamp)
1.485 + {
1.486 + strcpy(message," ");
1.487 + _ultoa(NKern::TickCount() * iTimer.Period(), message + 10, 10);
1.488 + int n = strlen(message);
1.489 + len = min(len, MaxOutputMsg - n - 2);
1.490 + char* msg = message + n;
1.491 + msg[0] = msg[-1];
1.492 + msg[-1] = n < 10+2 ? '0' : msg[-2];
1.493 + msg[-2] = n < 10+3 ? '0' : msg[-3];
1.494 + msg[-3] = '.';
1.495 + if (n < 10+4)
1.496 + msg[-4] = '0';
1.497 + ++msg;
1.498 + *msg++ = '\t';
1.499 + strncpy(msg, ptr, len);
1.500 + msg[len] = 0;
1.501 + ptr = msg - 11;
1.502 + len += 11;
1.503 + }
1.504 + else
1.505 + {
1.506 + len = min(len, MaxOutputMsg);
1.507 + strncpy(message, ptr, len);
1.508 + message[len] = 0;
1.509 + ptr = message;
1.510 + }
1.511 + TInt irq = NKern::DisableAllInterrupts();
1.512 + if (iLogToFile)
1.513 + {
1.514 + DWORD bytes;
1.515 + WriteFile(DebugOutput(), ptr, len, &bytes, NULL);
1.516 + }
1.517 + if (iLogToDebugger)
1.518 + {
1.519 + OutputDebugStringA(message);
1.520 + }
1.521 +
1.522 + NKern::RestoreInterrupts(irq);
1.523 + }
1.524 +
1.525 +const char* const KErrorTitles[] =
1.526 + {
1.527 + "Symbian OS Fatal Error",
1.528 + "Symbian OS Application Error"
1.529 + };
1.530 +
1.531 +const TText8* const KErrorMsg[] =
1.532 + {
1.533 + _S8("An error has been detected in the Symbian OS emulator."),
1.534 + _S8("A call to User::Panic() has occured, indicating\n"
1.535 + "a programming fault in the running application.\n"
1.536 + "Please refer to the documentation for more details.")
1.537 + };
1.538 +
1.539 +_LIT8(KProgram, "\n\nProgram\t");
1.540 +_LIT8(KError, "\nError\t");
1.541 +_LIT8(KIDFC, "an IDFC");
1.542 +_LIT8(KEscaped, "an escaped thread");
1.543 +_LIT8(KInterrupt, "an interrupt thread");
1.544 +_LIT8(KNThread, "an NThread");
1.545 +_LIT8(KColon, " : ");
1.546 +_LIT8(KDebugQuery, "\n\nDo you wish to Debug the error?\0");
1.547 +
1.548 +TBool Wins::ErrorDialog(TError aType, const TDesC8& aPanic, TInt aVal)
1.549 + {
1.550 + // Must be called with interrupts enabled to allow thread running windows message loop to run
1.551 +
1.552 + TBuf8<512> message(KErrorMsg[aType]);
1.553 + message.Append(KProgram);
1.554 + TInt context = NKern::CurrentContext();
1.555 + switch(context)
1.556 + {
1.557 + case NKern::EIDFC:
1.558 + message.Append(KIDFC);
1.559 + break;
1.560 + case NKern::EEscaped:
1.561 + message.Append(KEscaped);
1.562 + break;
1.563 + case NKern::EInterrupt:
1.564 + message.Append(KInterrupt);
1.565 + break;
1.566 + case NKern::EThread:
1.567 + DThread *thread = Kern::NThreadToDThread(NKern::CurrentThread());
1.568 + if (thread)
1.569 + thread->TraceAppendFullName(message, ETrue);
1.570 + else
1.571 + message.Append(KNThread);
1.572 + break;
1.573 + }
1.574 + message.Append(KError);
1.575 + message.Append(aPanic);
1.576 + message.Append(KColon);
1.577 + message.AppendNum(aVal);
1.578 +#ifdef _DEBUG
1.579 + message.Append(KDebugQuery);
1.580 + UINT type = MB_YESNO | MB_DEFBUTTON2;
1.581 +#else
1.582 + UINT type = MB_OK;
1.583 +#endif
1.584 + type |= MB_SETFOREGROUND | MB_ICONERROR;
1.585 + message.Append('\0');
1.586 +
1.587 + TInt r = MessageBoxA(iUi ? iUi->HWnd() : NULL, (LPCSTR)message.Ptr(), KErrorTitles[aType], type);
1.588 + return r == IDYES;
1.589 + }
1.590 +
1.591 +// UI installation
1.592 +
1.593 +EXPORT_C DWinsUiBase::DWinsUiBase()
1.594 + {
1.595 + TheVariant.InstallUi(*this);
1.596 + }
1.597 +
1.598 +
1.599 +TInt BinaryPowerInit();
1.600 +
1.601 +DWinsPowerController* DWinsPowerController::New()
1.602 + {
1.603 + DWinsPowerController* self = new DWinsPowerController();
1.604 + if (!self)
1.605 + return NULL;
1.606 + self->iStandbySem = CreateSemaphore(NULL, 0, 1, NULL);
1.607 + if (self->iStandbySem == NULL)
1.608 + return NULL;
1.609 + TInt r = BinaryPowerInit();
1.610 + if (r != KErrNone)
1.611 + return NULL;
1.612 + self->Register();
1.613 + return self;
1.614 + }
1.615 +
1.616 +void DWinsPowerController::CpuIdle()
1.617 + {
1.618 + Arch::TheAsic()->Idle();
1.619 + }
1.620 +
1.621 +void DWinsPowerController::EnableWakeupEvents()
1.622 + {
1.623 + iWakeupSignal = EFalse;
1.624 + }
1.625 +
1.626 +void DWinsPowerController::DisableWakeupEvents()
1.627 + {
1.628 + }
1.629 +
1.630 +void DWinsPowerController::AbsoluteTimerExpired()
1.631 + {
1.632 + if (iTargetState == EPwStandby)
1.633 + DWinsPowerController::WakeupEvent();
1.634 + }
1.635 +
1.636 +void DWinsPowerController::WakeupEvent()
1.637 + {
1.638 + if (iTargetState == EPwStandby)
1.639 + {
1.640 + iWakeupSignal = ETrue;
1.641 + DPowerController::WakeupEvent();
1.642 + }
1.643 + }
1.644 +
1.645 +// called in Epoc thread
1.646 +void DWinsPowerController::PowerDown(TTimeK aWakeupTime)
1.647 + {
1.648 + if (iTargetState == EPwStandby)
1.649 + {
1.650 + UINT timeoutMs;
1.651 + if (aWakeupTime == 0)
1.652 + timeoutMs = INFINITE;
1.653 + else
1.654 + {
1.655 + TTimeK now = Kern::SystemTime();
1.656 + if (now > aWakeupTime)
1.657 + timeoutMs = 0;
1.658 + else
1.659 + timeoutMs = (UINT)((aWakeupTime - now) / 1000);
1.660 + }
1.661 + TInt l = NKern::DisableAllInterrupts();
1.662 + if (!iWakeupSignal && timeoutMs)
1.663 + {
1.664 + iStandby = ETrue;
1.665 + TheVariant.iTimer.Standby();
1.666 + NKern::RestoreInterrupts(l);
1.667 + DWORD r = WaitForSingleObject(iStandbySem, timeoutMs);
1.668 + if (r == WAIT_TIMEOUT)
1.669 + {
1.670 + l = NKern::DisableAllInterrupts();
1.671 + if (!iStandby)
1.672 + WaitForSingleObject(iStandbySem, INFINITE);
1.673 + else
1.674 + iStandby = EFalse;
1.675 + NKern::RestoreInterrupts(l);
1.676 + }
1.677 + TheVariant.iTimer.Wakeup();
1.678 + }
1.679 + else
1.680 + NKern::RestoreInterrupts(l);
1.681 +
1.682 + }
1.683 + else
1.684 + Kern::Restart(0x80000000);
1.685 + }
1.686 +
1.687 +// called in the interrupt context
1.688 +void DWinsPowerController::AssertWakeupSignal()
1.689 + {
1.690 + iWakeupSignal = ETrue;
1.691 + if (iStandby)
1.692 + {
1.693 + iStandby = EFalse;
1.694 + ReleaseSemaphore(iStandbySem, 1, NULL);
1.695 + }
1.696 + }
1.697 +
1.698 +
1.699 +EXPORT_C void Wins::AssertWakeupSignal()
1.700 + {
1.701 + iPowerController->AssertWakeupSignal();
1.702 + }
1.703 +
1.704 +EXPORT_C void Wins::WakeupEvent()
1.705 + {
1.706 + iPowerController->DWinsPowerController::WakeupEvent();
1.707 + }
1.708 +
1.709 +// MMC emulation support
1.710 +
1.711 +TBool Wins::MediaDoorOpen;
1.712 +TInt Wins::CurrentPBusDevice;
1.713 +TAny* Wins::MediaChangeCallbackParam;
1.714 +TMediaChangeCallBack Wins::MediaChangeCallBackPtr;
1.715 +
1.716 +
1.717 +EXPORT_C TBool* Wins::MediaDoorOpenPtr()
1.718 +//
1.719 +// For media change simulation
1.720 +//
1.721 + {
1.722 +
1.723 + return(&MediaDoorOpen);
1.724 + }
1.725 +
1.726 +EXPORT_C TInt* Wins::CurrentPBusDevicePtr()
1.727 +//
1.728 +// For media change simulation
1.729 +//
1.730 + {
1.731 +
1.732 + return(&CurrentPBusDevice);
1.733 + }
1.734 +
1.735 +EXPORT_C void Wins::SetMediaChangeCallBackPtr(TMediaChangeCallBack aPtr, TAny* aMediaChangeCallbackParam)
1.736 +//
1.737 +// For media change simulation
1.738 +//
1.739 + {
1.740 + MediaChangeCallbackParam=aMediaChangeCallbackParam;
1.741 + MediaChangeCallBackPtr=aPtr;
1.742 + }
1.743 +
1.744 +EXPORT_C void Wins::MediaChangeCallBack()
1.745 +//
1.746 +// Perform the simulated media change callback
1.747 +//
1.748 + {
1.749 + if(MediaChangeCallBackPtr)
1.750 + (*MediaChangeCallBackPtr)(MediaChangeCallbackParam);
1.751 + }