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