os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/specific/variant.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
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 the License "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
// template\template_variant\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 <videodriver.h>
sl@0
    21
#include <drivers/xyin.h>
sl@0
    22
#include "template_power.h"
sl@0
    23
sl@0
    24
//These constants define Custom Restart Reasons in SuperPage::iHwStartupReason
sl@0
    25
const TUint KHtCustomRestartMax	  = 0xff;
sl@0
    26
const TUint KHtCustomRestartShift = 8;
sl@0
    27
const TUint KHtCustomRestartMask  = KHtCustomRestartMax << KHtCustomRestartShift; 
sl@0
    28
sl@0
    29
const TUint KHtRestartStartupModesMax = 0xf; // Variable, platform dependant 
sl@0
    30
const TUint KHtRestartStartupModesShift = 16; // Variable, platform dependant 
sl@0
    31
const TUint KHtRestartStartupModesMask = KHtRestartStartupModesMax << KHtRestartStartupModesShift;
sl@0
    32
sl@0
    33
void TemplateVariantFault(TInt aLine)
sl@0
    34
	{
sl@0
    35
	Kern::Fault("TemplateVariant",aLine);
sl@0
    36
	}
sl@0
    37
sl@0
    38
#define V_FAULT()	TemplateVariantFault(__LINE__)
sl@0
    39
sl@0
    40
// Debug output
sl@0
    41
#define XON								17
sl@0
    42
#define XOFF							19
sl@0
    43
#define DEBUG_XON_XOFF					0		// Non-zero if we want XON-XOFF handshaking
sl@0
    44
sl@0
    45
GLDEF_D Template TheVariant;
sl@0
    46
TUint32 Variant::iBaseAddress=0;
sl@0
    47
sl@0
    48
TUint32 Template::HandlerData[3];
sl@0
    49
SInterruptHandler Template::Handlers[ENumXInts];
sl@0
    50
sl@0
    51
extern void XIntDispatch(TAny*);
sl@0
    52
sl@0
    53
EXPORT_C Asic* VariantInitialise()
sl@0
    54
	{
sl@0
    55
	return &TheVariant;
sl@0
    56
	}
sl@0
    57
sl@0
    58
Template::Template()
sl@0
    59
	{
sl@0
    60
	iDebugInitialised=EFalse;
sl@0
    61
	}
sl@0
    62
sl@0
    63
//
sl@0
    64
// TO DO: (optional)
sl@0
    65
//
sl@0
    66
// Specify the RAM zone configuration.
sl@0
    67
//
sl@0
    68
// The lowest addressed zone must have the highest preference as the bootstrap 
sl@0
    69
// will always allocate from the lowest address up.  Once the kernel has initialised
sl@0
    70
// then the zone preferences will decide from which RAM zone memory is allocated.
sl@0
    71
//
sl@0
    72
// 	const TUint KVariantRamZoneCount = ?;
sl@0
    73
//	static const SRamZone KRamZoneConfig[KVariantRamZoneCount+1] = 
sl@0
    74
//				 			iBase      iSize   		iID	iPref	iFlags
sl@0
    75
//				{
sl@0
    76
//				__SRAM_ZONE(0x????????, 0x???????, 	?,	?, 		?), 
sl@0
    77
//				...
sl@0
    78
//				__SRAM_ZONE(0x????????, 0x???????, 	?, 	?, 		?),
sl@0
    79
//				__SRAM_ZONE_END, // end of zone list
sl@0
    80
//				};
sl@0
    81
//
sl@0
    82
sl@0
    83
TInt Template::RamZoneCallback(TRamZoneOp aOp, TAny* aId, const TAny* aMasks)
sl@0
    84
	{
sl@0
    85
	//
sl@0
    86
	// TO DO: (optional)
sl@0
    87
	//
sl@0
    88
	// Handle RAM zone operations requested by the kernel.
sl@0
    89
	//
sl@0
    90
	return TheVariant.DoRamZoneCallback(aOp, (TUint)aId, (const TUint*)aMasks);
sl@0
    91
	}
sl@0
    92
sl@0
    93
sl@0
    94
TInt Template::DoRamZoneCallback(TRamZoneOp aOp, TUint aId, const TUint* aMasks)
sl@0
    95
	{
sl@0
    96
	//
sl@0
    97
	// TO DO: (optional)
sl@0
    98
	//
sl@0
    99
	// Handle RAM zone operations requested by the kernel.
sl@0
   100
	//
sl@0
   101
	// Three types of operation need to be supported:
sl@0
   102
	//	ERamZoneOp_Init:		Update power state of the RAM zones after the
sl@0
   103
	//							kernel has initialised.
sl@0
   104
	//	ERamZoneOp_PowerUp:		A RAM zone changing from used to empty.
sl@0
   105
	//	ERamZoneOp_PowerDown:	A RAM zone changing from empty to used.
sl@0
   106
	//
sl@0
   107
 
sl@0
   108
	switch (aOp)
sl@0
   109
		{
sl@0
   110
		case ERamZoneOp_Init:	
sl@0
   111
			break;
sl@0
   112
		case ERamZoneOp_PowerUp:
sl@0
   113
			break;
sl@0
   114
		case ERamZoneOp_PowerDown:
sl@0
   115
			break;
sl@0
   116
		default:
sl@0
   117
			return KErrNotSupported;
sl@0
   118
		}
sl@0
   119
	return KErrNone;
sl@0
   120
	}
sl@0
   121
sl@0
   122
sl@0
   123
void Template::Init1()
sl@0
   124
	{
sl@0
   125
	__KTRACE_OPT(KBOOT,Kern::Printf("Template::Init1()"));
sl@0
   126
sl@0
   127
	//
sl@0
   128
	// TO DO: (mandatory)
sl@0
   129
	//
sl@0
   130
	// Configure Memory controller and Memrory Bus parameters (in addition to what was done in the Bootstrap)
sl@0
   131
	//
sl@0
   132
	__KTRACE_OPT(KBOOT,Kern::Printf("Memory Configuration done"));
sl@0
   133
sl@0
   134
	//
sl@0
   135
	// TO DO: (optional)
sl@0
   136
	//
sl@0
   137
	// Inform the kernel of the RAM zone configuration via Epoc::SetRamZoneConfig().
sl@0
   138
	// For devices that wish to reduce power consumption of the RAM IC(s) the callback functions
sl@0
   139
	// RamZoneCallback() and DoRamZoneCallback() will need to be implemented and passed 
sl@0
   140
	// to Epoc::SetRamZoneConfig() as the parameter aCallback.
sl@0
   141
	// The kernel will assume that all RAM ICs are fully intialised and ready for use from boot.
sl@0
   142
	//
sl@0
   143
sl@0
   144
	//
sl@0
   145
	// TO DO: (optional)
sl@0
   146
	//
sl@0
   147
	// Initialise other critical hardware functions such as I/O interfaces, etc, not done by Bootstrap
sl@0
   148
	//
sl@0
   149
	// if CPU is Sleep-capable, and requires some preparation to be put in that state (code provided in Bootstrap),
sl@0
   150
	// the address of the idle code is writen at this location by the Bootstrap
sl@0
   151
	// e.g.
sl@0
   152
	// iIdleFunction=*(TLinAddr*)((TUint8*)&Kern::SuperPage()+0x1000);
sl@0
   153
	//
sl@0
   154
	TemplateAssp::Init1();
sl@0
   155
	}
sl@0
   156
sl@0
   157
void Template::Init3()
sl@0
   158
	{
sl@0
   159
	__KTRACE_OPT(KBOOT,Kern::Printf("Template::Init3()"));
sl@0
   160
sl@0
   161
	TemplateAssp::Init3();
sl@0
   162
sl@0
   163
	Variant::Init3();
sl@0
   164
	//
sl@0
   165
	// TO DO: (optional)
sl@0
   166
	//
sl@0
   167
	// Initialise other accessor classes, if required
sl@0
   168
	//
sl@0
   169
sl@0
   170
	InitInterrupts();
sl@0
   171
	}
sl@0
   172
sl@0
   173
void Variant::Init3()
sl@0
   174
//
sl@0
   175
// Phase 3 initialisation
sl@0
   176
//
sl@0
   177
    {
sl@0
   178
	__KTRACE_OPT(KHARDWARE, Kern::Printf(">Variant::Init3"));
sl@0
   179
sl@0
   180
	//
sl@0
   181
	// TO DO: (optional)
sl@0
   182
	//
sl@0
   183
	// Initialise any Variant class data members here, map in Variant and external hardware addresses
sl@0
   184
	//
sl@0
   185
	DPlatChunkHw* pC=NULL;
sl@0
   186
	TInt r=DPlatChunkHw::New(pC,KHwVariantPhysBase,0x2000,EMapAttrSupRw|EMapAttrFullyBlocking);
sl@0
   187
    __ASSERT_ALWAYS(r==KErrNone,V_FAULT());
sl@0
   188
	iBaseAddress=pC->LinearAddress();
sl@0
   189
	}
sl@0
   190
sl@0
   191
EXPORT_C TUint Variant::BaseLinAddress()
sl@0
   192
	{
sl@0
   193
	return((TUint)iBaseAddress);
sl@0
   194
	}
sl@0
   195
sl@0
   196
EXPORT_C void Variant::MarkDebugPortOff()
sl@0
   197
	{
sl@0
   198
	TheVariant.iDebugInitialised=EFalse;
sl@0
   199
	}
sl@0
   200
sl@0
   201
EXPORT_C void Variant::UartInit()
sl@0
   202
	{
sl@0
   203
	NKern::Lock();
sl@0
   204
	if (!TheVariant.iDebugInitialised)
sl@0
   205
		{
sl@0
   206
		//
sl@0
   207
		// TO DO: (mandatory)
sl@0
   208
		//
sl@0
   209
		// Reset and initialise the UART used to output debug strings
sl@0
   210
		//
sl@0
   211
		TheVariant.iDebugInitialised=ETrue;
sl@0
   212
		}
sl@0
   213
	NKern::Unlock();
sl@0
   214
	}
sl@0
   215
sl@0
   216
void Template::DebugInit()
sl@0
   217
	{
sl@0
   218
	//
sl@0
   219
	// TO DO: (mandatory)
sl@0
   220
	//
sl@0
   221
	// Initialise the UART used for outputting Debug Strings (no Interrupts), as in the following EXAMPLE ONLY:
sl@0
   222
	//
sl@0
   223
	Variant::UartInit();
sl@0
   224
	TTemplate::BootWaitMilliSeconds(10);	// wait loop to ensure that the port is fully initialised and output buffer empty
sl@0
   225
	}
sl@0
   226
sl@0
   227
void Template::DebugOutput(TUint aLetter)
sl@0
   228
//
sl@0
   229
// Output a character to the debug port
sl@0
   230
//
sl@0
   231
    {
sl@0
   232
	if (!iDebugInitialised)
sl@0
   233
		{
sl@0
   234
		DebugInit();
sl@0
   235
		}
sl@0
   236
		//
sl@0
   237
		// TO DO: (mandatory)
sl@0
   238
		//
sl@0
   239
		// Write the character aLetter to the UART output register and wait until sent (do NOT use interrupts!)
sl@0
   240
		//
sl@0
   241
    }
sl@0
   242
sl@0
   243
void Template::Idle()
sl@0
   244
//
sl@0
   245
// The NULL thread idle loop
sl@0
   246
//
sl@0
   247
	{
sl@0
   248
	// Idle the CPU, suppressing the system tick if possible
sl@0
   249
sl@0
   250
	//
sl@0
   251
	// TO DO: (optional)
sl@0
   252
	//
sl@0
   253
	// Idle Tick supression: 
sl@0
   254
	// 1- obtain the number of idle Ticks before the next NTimer expiration (NTimerQ::IdleTime())
sl@0
   255
	// 2- if the number of Ticks is large enough (criteria to be defined) reset the Hardware Timer
sl@0
   256
	//    to only interrupt again when the corresponding time has expired.
sl@0
   257
	//   2.1- the calculation of the new value to program the Hardware Timer with should take in 
sl@0
   258
	//		  consideration the rounding value (NTimerQ::iRounding)
sl@0
   259
	//  3- call the low level Sleep function (e'g. Bootstrap: address in iIdleFunction)
sl@0
   260
	//  4- on coming back from Idle need to read the Hardware Timer and determine if woken up due to 
sl@0
   261
	//     timer expiration (system time for new match<=current system time<system time for new match-tick period)
sl@0
   262
	//     or some other Interrupt.
sl@0
   263
	//	 4.1- if timer expiration, adjust System Time by adding the number of Ticks suppressed to NTimerQ::iMsCount
sl@0
   264
	//   4.2- if other interrupt, calculate the number of Ticks skipped until woken up and adjust the System Time as
sl@0
   265
	//		  above
sl@0
   266
	//
sl@0
   267
	// Support for different Sleep Modes:
sl@0
   268
	// Often the Sleep mode a platform can go to depends on how many resources such as clocks/voltages can be 
sl@0
   269
	// turned Off or lowered to a suitable level. If different Sleep modes are supported this code may need 
sl@0
   270
	// to be able to find out what power resources are On or Off or used to what level. This could be achieved by
sl@0
   271
	// enquiring the Resource Manager (see \template_variant\inc\template_power.h).
sl@0
   272
	// Then a decision could be made to what Sleep level we go to.
sl@0
   273
	//
sl@0
   274
	// Example calls:
sl@0
   275
	// Obtain the number of Idle Ticks before the next NTimer expiration
sl@0
   276
	// TInt aTicksLeft = NTimerQ::IdleTime();
sl@0
   277
	// ... 
sl@0
   278
	// Find out the deepest Sleep mode available for current resource usage and sleeping time
sl@0
   279
	// TemplateResourceManager* aManager = TTemplatePowerController::ResourceManager();
sl@0
   280
	// TemplateResourceManager::TSleepModes aMode = aManager -> MapSleepMode(aTicksLeft*MsTickPeriod());
sl@0
   281
	// ...
sl@0
   282
	// Find out the state of some particular resources
sl@0
   283
	// TBool aResourceState = aManager -> GetResourceState(TemplateResourceManager::AsynchBinResourceUsedByZOnly);
sl@0
   284
	// TUint aResourceLevel = aManager -> GetResourceLevel(TemplateResourceManager::SynchMlResourceUsedByXOnly);
sl@0
   285
	// ...
sl@0
   286
	}
sl@0
   287
sl@0
   288
TInt Template::VariantHal(TInt aFunction, TAny* a1, TAny* a2)
sl@0
   289
	{
sl@0
   290
	TInt r=KErrNone;
sl@0
   291
	switch(aFunction)
sl@0
   292
		{
sl@0
   293
		case EVariantHalVariantInfo:
sl@0
   294
			{
sl@0
   295
			TVariantInfoV01Buf infoBuf;
sl@0
   296
			TVariantInfoV01& info=infoBuf();
sl@0
   297
			info.iRomVersion=Epoc::RomHeader().iVersion;
sl@0
   298
sl@0
   299
			//
sl@0
   300
			// TO DO: (mandatory)
sl@0
   301
			//
sl@0
   302
			// Fill in the TVariantInfoV01 info structure
sl@0
   303
			//	info.iMachineUniqueId=;
sl@0
   304
			//	info.iLedCapabilities=;
sl@0
   305
			//	info.iProcessorClockInKHz=;
sl@0
   306
			//	info.iSpeedFactor=;
sl@0
   307
			//
sl@0
   308
			Kern::InfoCopy(*(TDes8*)a1,infoBuf);
sl@0
   309
			break;
sl@0
   310
			}
sl@0
   311
		case EVariantHalDebugPortSet:
sl@0
   312
			{
sl@0
   313
			//
sl@0
   314
			// TO DO: (mandatory)
sl@0
   315
			//
sl@0
   316
			// Write the iDebugPort field of the SuperPage, as in the following EXAMPLE ONLY:
sl@0
   317
			//
sl@0
   318
			TUint32 thePort = (TUint32)a1;
sl@0
   319
			switch(thePort)
sl@0
   320
				{
sl@0
   321
				case 1:
sl@0
   322
				case 2:
sl@0
   323
				case 3:
sl@0
   324
					TheVariant.iDebugInitialised=EFalse;
sl@0
   325
				case (TUint32)KNullDebugPort:
sl@0
   326
					Kern::SuperPage().iDebugPort = thePort;
sl@0
   327
					break;
sl@0
   328
				default:
sl@0
   329
					r=KErrNotSupported;
sl@0
   330
				}
sl@0
   331
			break;
sl@0
   332
			}
sl@0
   333
		case EVariantHalDebugPortGet:
sl@0
   334
			{
sl@0
   335
			//
sl@0
   336
			// TO DO: (mandatory)
sl@0
   337
			//
sl@0
   338
			// Obtain the Linear address of the Uart used for outputting Debug strings as in the following EXAMPLE ONLY:
sl@0
   339
			//
sl@0
   340
sl@0
   341
			TUint32 thePort = TTemplate::DebugPortAddr();
sl@0
   342
			kumemput32(a1, &thePort, sizeof(TUint32));
sl@0
   343
			break;
sl@0
   344
			}
sl@0
   345
		case EVariantHalSwitches:
sl@0
   346
			{
sl@0
   347
			//
sl@0
   348
			// TO DO: (optional)
sl@0
   349
			//
sl@0
   350
			// Read the state of any switches, as in the following EXAMPLE ONLY:
sl@0
   351
			//
sl@0
   352
			TUint32 x = Variant::Switches();
sl@0
   353
			kumemput32(a1, &x, sizeof(x));
sl@0
   354
			break;
sl@0
   355
			}
sl@0
   356
		case EVariantHalLedMaskSet:
sl@0
   357
			{
sl@0
   358
			//
sl@0
   359
			// TO DO: (optional)
sl@0
   360
			//
sl@0
   361
			// Set the state of any on-board LEDs, e.g:
sl@0
   362
			// TUint32 aLedMask=(TUint32)a1;
sl@0
   363
			// Variant::ModifyLedState(~aLedMask,aLedMask);
sl@0
   364
			//
sl@0
   365
			break;
sl@0
   366
			}
sl@0
   367
		case EVariantHalLedMaskGet:
sl@0
   368
			{
sl@0
   369
			//
sl@0
   370
			// TO DO: (optional)
sl@0
   371
			//
sl@0
   372
			// Read the state of any on-board LEDs, e.g:
sl@0
   373
			// TUint32 x = Variant::LedState();
sl@0
   374
			// kumemput32(a1, &x, sizeof(x));
sl@0
   375
			//
sl@0
   376
			break;
sl@0
   377
			}
sl@0
   378
sl@0
   379
		case EVariantHalCustomRestartReason:
sl@0
   380
			{
sl@0
   381
			//Restart reason is stored in super page
sl@0
   382
			TInt x = (Kern::SuperPage().iHwStartupReason & KHtCustomRestartMask) >> KHtCustomRestartShift ;
sl@0
   383
			kumemput32(a1, &x, sizeof(TInt));
sl@0
   384
			break;
sl@0
   385
			}
sl@0
   386
sl@0
   387
		case EVariantHalCustomRestart:
sl@0
   388
			{
sl@0
   389
			if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EVariantHalCustomRestart")))
sl@0
   390
				return KErrPermissionDenied;
sl@0
   391
			if ((TUint)a1 > KHtCustomRestartMax)
sl@0
   392
				return KErrArgument;
sl@0
   393
			Kern::Restart((TInt)a1 << KHtCustomRestartShift);
sl@0
   394
			}
sl@0
   395
			break;
sl@0
   396
sl@0
   397
		case EVariantHalCaseState:
sl@0
   398
			{
sl@0
   399
			//
sl@0
   400
			// TO DO: (optional)
sl@0
   401
			//
sl@0
   402
			// Read the state of the case, e.g:
sl@0
   403
			// TUint32 x = Variant::CaseState();
sl@0
   404
			// kumemput32(a1, &x, sizeof(x));
sl@0
   405
			//
sl@0
   406
			break;
sl@0
   407
			}
sl@0
   408
sl@0
   409
		case EVariantHalPersistStartupMode:
sl@0
   410
			{
sl@0
   411
			if (!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn")))
sl@0
   412
				return KErrPermissionDenied;
sl@0
   413
sl@0
   414
			if ((TUint)a1 > KHtRestartStartupModesMax ) // Restart startup mode max value
sl@0
   415
				return KErrArgument;
sl@0
   416
			//
sl@0
   417
			// TO DO: (optional)
sl@0
   418
			//
sl@0
   419
			// Store the restart reason locally,
sl@0
   420
			// which will eventually be picked up by
sl@0
   421
			// the power controller, e.g:
sl@0
   422
			// iCustomRestartReason = (TUint)a1;
sl@0
   423
			break;
sl@0
   424
			}
sl@0
   425
sl@0
   426
sl@0
   427
		case EVariantHalGetPersistedStartupMode:
sl@0
   428
			{
sl@0
   429
			//
sl@0
   430
			// TO DO: (optional)
sl@0
   431
			//
sl@0
   432
			// Read the restart startup mode, e.g:
sl@0
   433
			// TInt startup = (Kern::SuperPage().iHwStartupReason & KHtRestartStartupModesMask) >> KHtRestartStartupModesShift;
sl@0
   434
			// kumemput32(a1, &startup, sizeof(TInt));
sl@0
   435
			break; 			
sl@0
   436
			}
sl@0
   437
sl@0
   438
		case EVariantHalGetMaximumCustomRestartReasons:
sl@0
   439
			{
sl@0
   440
			//
sl@0
   441
			// TO DO: (optional)
sl@0
   442
			//
sl@0
   443
			// Read the maximum custom restart reason, e.g:
sl@0
   444
			// kumemput32(a1, &KHtCustomRestartMax, sizeof(TUint));
sl@0
   445
			break;
sl@0
   446
			}
sl@0
   447
sl@0
   448
sl@0
   449
		case EVariantHalGetMaximumRestartStartupModes:
sl@0
   450
			{
sl@0
   451
			//
sl@0
   452
			// TO DO: (optional)
sl@0
   453
			//
sl@0
   454
			// Read the maximum restart startup mode, e.g:
sl@0
   455
			// kumemput32(a1, &KHtRestartStartupModesMax, sizeof(TUint));
sl@0
   456
			break;
sl@0
   457
			}
sl@0
   458
sl@0
   459
     	case EVariantHalProfilingDefaultInterruptBase:
sl@0
   460
			{
sl@0
   461
			//
sl@0
   462
            // TO DO: (optional)
sl@0
   463
            //
sl@0
   464
            //Set the default interrupt number for the sampling profiler.   
sl@0
   465
            //TInt interruptNumber = KIntCpuProfilingDefaultInterruptBase;
sl@0
   466
			//kumemput(a1,&interruptNumber,sizeof(interruptNumber));
sl@0
   467
			break;
sl@0
   468
			}
sl@0
   469
sl@0
   470
		default:
sl@0
   471
			r=KErrNotSupported;
sl@0
   472
			break;
sl@0
   473
		}
sl@0
   474
	return r;
sl@0
   475
	}
sl@0
   476
sl@0
   477
TPtr8 Template::MachineConfiguration()
sl@0
   478
	{
sl@0
   479
	return TPtr8((TUint8*)&Kern::MachineConfig(),sizeof(TActualMachineConfig),sizeof(TActualMachineConfig));
sl@0
   480
	}
sl@0
   481
sl@0
   482
TInt Template::VideoRamSize()
sl@0
   483
	{
sl@0
   484
	//
sl@0
   485
	// TO DO: (mandatory)
sl@0
   486
	//
sl@0
   487
	// Return the size of the area of RAM used to store the Video Buffer, as in the following EXAMPLE ONLY:
sl@0
   488
	//
sl@0
   489
	return 0x28000;
sl@0
   490
	}
sl@0
   491
sl@0
   492
EXPORT_C void Variant::PowerReset()
sl@0
   493
	{
sl@0
   494
	//
sl@0
   495
	// TO DO: (optional)
sl@0
   496
	//
sl@0
   497
	// Reset all power supplies
sl@0
   498
	//
sl@0
   499
	}
sl@0
   500
sl@0
   501
EXPORT_C TUint Variant::Switches()
sl@0
   502
	{
sl@0
   503
	//
sl@0
   504
	// TO DO: (optional)
sl@0
   505
	//
sl@0
   506
	// Read the state of on-board switches
sl@0
   507
	//
sl@0
   508
	return 0;		// EXAMPLE ONLY
sl@0
   509
	}
sl@0
   510
sl@0
   511
/******************************************************************************
sl@0
   512
 * Interrupt handling/dispatch
sl@0
   513
 ******************************************************************************/
sl@0
   514
TInt Template::InterruptBind(TInt anId, TIsr anIsr, TAny* aPtr)
sl@0
   515
	{
sl@0
   516
	TUint id=anId&0x7fffffff;	// mask off second-level interrupt mask
sl@0
   517
	if (id>=ENumXInts)
sl@0
   518
		return KErrArgument;
sl@0
   519
	TInt r=KErrNone;
sl@0
   520
	SInterruptHandler& h=Handlers[id];
sl@0
   521
	TInt irq=NKern::DisableAllInterrupts();
sl@0
   522
	if (h.iIsr!=Spurious)
sl@0
   523
		r=KErrInUse;
sl@0
   524
	else
sl@0
   525
		{
sl@0
   526
		h.iIsr=anIsr;
sl@0
   527
		h.iPtr=aPtr;
sl@0
   528
		}
sl@0
   529
	NKern::RestoreInterrupts(irq);
sl@0
   530
	return r;
sl@0
   531
	}
sl@0
   532
sl@0
   533
TInt Template::InterruptUnbind(TInt anId)
sl@0
   534
	{
sl@0
   535
	TUint id=anId&0x7fffffff;	// mask off second-level interrupt mask
sl@0
   536
	if (id>=ENumXInts)
sl@0
   537
		return KErrArgument;
sl@0
   538
	InterruptDisable(anId);
sl@0
   539
	InterruptClear(anId);
sl@0
   540
	TInt r=KErrNone;
sl@0
   541
	SInterruptHandler& h=Handlers[id];
sl@0
   542
	TInt irq=NKern::DisableAllInterrupts();
sl@0
   543
	if (h.iIsr!=Spurious)
sl@0
   544
		{
sl@0
   545
		h.iIsr=Spurious;
sl@0
   546
		h.iPtr=(TAny*)id;
sl@0
   547
		}
sl@0
   548
	NKern::RestoreInterrupts(irq);
sl@0
   549
	return r;
sl@0
   550
	}
sl@0
   551
sl@0
   552
TInt Template::InterruptEnable(TInt anId)
sl@0
   553
	{
sl@0
   554
	TUint id=anId&0x7fffffff;	// mask off second-level interrupt mask
sl@0
   555
	if (id>=ENumXInts)
sl@0
   556
		return KErrArgument;
sl@0
   557
	TInt r=KErrNone;
sl@0
   558
	SInterruptHandler& h=Handlers[id];
sl@0
   559
	TInt irq=NKern::DisableAllInterrupts();
sl@0
   560
	if (h.iIsr==Spurious)
sl@0
   561
		r=KErrNotReady;
sl@0
   562
	else
sl@0
   563
		{
sl@0
   564
		//
sl@0
   565
		// TO DO: (mandatory)
sl@0
   566
		//
sl@0
   567
		// Enable the hardware interrupt in the source, e.g.
sl@0
   568
		// Variant::EnableInt(anId);
sl@0
   569
		//
sl@0
   570
		}
sl@0
   571
	NKern::RestoreInterrupts(irq);
sl@0
   572
	return r;
sl@0
   573
	}
sl@0
   574
sl@0
   575
TInt Template::InterruptDisable(TInt anId)
sl@0
   576
	{
sl@0
   577
	TUint id=anId&0x7fffffff;	// mask off second-level interrupt mask
sl@0
   578
	if (id>=ENumXInts)
sl@0
   579
		return KErrArgument;
sl@0
   580
	//
sl@0
   581
	// TO DO: (mandatory)
sl@0
   582
	//
sl@0
   583
	// Disable the hardware interrupt in the source, e.g.
sl@0
   584
	// Variant::DisableInt(anId);
sl@0
   585
	//
sl@0
   586
	return KErrNone;
sl@0
   587
	}
sl@0
   588
sl@0
   589
TInt Template::InterruptClear(TInt anId)
sl@0
   590
	{
sl@0
   591
	TUint id=anId&0x7fffffff;
sl@0
   592
	if (id>=ENumXInts)
sl@0
   593
		return KErrArgument;
sl@0
   594
	//
sl@0
   595
	// TO DO: (mandatory)
sl@0
   596
	//
sl@0
   597
	// Clear the hardware interrupt in the source, e.g.
sl@0
   598
	// Variant::ClearInt(anId);
sl@0
   599
	//
sl@0
   600
	return KErrNone;
sl@0
   601
	}
sl@0
   602
sl@0
   603
void Template::InitInterrupts()
sl@0
   604
	{
sl@0
   605
	// Set up the variant interrupt dispatcher
sl@0
   606
sl@0
   607
	// all interrupts initially unbound
sl@0
   608
	TInt i;
sl@0
   609
	for (i=0; i<(TInt)ENumXInts; i++)
sl@0
   610
		{
sl@0
   611
		Handlers[i].iPtr=(TAny*)i;
sl@0
   612
		Handlers[i].iIsr=Spurious;
sl@0
   613
		}
sl@0
   614
sl@0
   615
	// Set up data for 2nd level interrupt dispatcher
sl@0
   616
	HandlerData[0]=Variant::BaseLinAddress();	// Linear Base address of 2nd level Int Controller
sl@0
   617
	HandlerData[1]=(TUint32)&Handlers[0];		// Pointer to handler array
sl@0
   618
	HandlerData[2]=0;							// 
sl@0
   619
	
sl@0
   620
	//
sl@0
   621
	// TO DO: (mandatory)
sl@0
   622
	//
sl@0
   623
	// set up ASSP expansion interrupt to generate interrupts whenever a 2nd level interrupt occurrs
sl@0
   624
	// 
sl@0
   625
sl@0
   626
	// bind Template ASSP expansion interrupt input to our interrupt dispatcher
sl@0
   627
	TInt r=Interrupt::Bind(KIntIdExpansion, XIntDispatch, HandlerData);
sl@0
   628
	__ASSERT_ALWAYS(r==KErrNone,V_FAULT());
sl@0
   629
	Interrupt::Enable(KIntIdExpansion);				// enable expansion interrupt
sl@0
   630
	}
sl@0
   631
sl@0
   632
void Template::Spurious(TAny* aId)
sl@0
   633
	{
sl@0
   634
	TUint32 id=((TUint32)aId)|0x80000000u;
sl@0
   635
	Kern::Fault("SpuriousInt",id);
sl@0
   636
	}
sl@0
   637
sl@0
   638
sl@0
   639
// USB Client controller
sl@0
   640
sl@0
   641
TBool Template::UsbClientConnectorDetectable()
sl@0
   642
	{
sl@0
   643
	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbClientConnectorDetectable"));
sl@0
   644
sl@0
   645
	// TO DO: The return value should reflect the actual situation.
sl@0
   646
	return ETrue;
sl@0
   647
	}
sl@0
   648
sl@0
   649
sl@0
   650
TBool Template::UsbClientConnectorInserted()
sl@0
   651
 	{
sl@0
   652
	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbClientConnectorInserted"));
sl@0
   653
sl@0
   654
	// TO DO: Query cable status here. The return value should reflect the actual current state.
sl@0
   655
	return ETrue;
sl@0
   656
	}
sl@0
   657
sl@0
   658
sl@0
   659
TInt Template::RegisterUsbClientConnectorCallback(TInt (*aCallback)(TAny*), TAny* aPtr)
sl@0
   660
	{
sl@0
   661
	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::RegisterUsbClientConnectorCallback"));
sl@0
   662
sl@0
   663
	iUsbClientConnectorCallback = aCallback;
sl@0
   664
	iUsbClientConnectorCallbackArg = aPtr;
sl@0
   665
sl@0
   666
	// TO DO: Register and enable the interrupt(s) for detecting USB cable insertion/removal here.
sl@0
   667
	// (Register UsbClientConnectorIsr.)
sl@0
   668
sl@0
   669
	// TO DO: The return value should reflect the actual situation.
sl@0
   670
	return KErrNone;
sl@0
   671
	}
sl@0
   672
sl@0
   673
sl@0
   674
void Template::UnregisterUsbClientConnectorCallback()
sl@0
   675
	{
sl@0
   676
	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UnregisterUsbClientConnectorCallback"));
sl@0
   677
sl@0
   678
	// TO DO: Disable and unbind the interrupt(s) for detecting USB cable insertion/removal here.
sl@0
   679
sl@0
   680
	iUsbClientConnectorCallback = NULL;
sl@0
   681
	iUsbClientConnectorCallbackArg = NULL;
sl@0
   682
	}
sl@0
   683
sl@0
   684
sl@0
   685
TBool Template::UsbSoftwareConnectable()
sl@0
   686
	{
sl@0
   687
	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbSoftwareConnectable"));
sl@0
   688
sl@0
   689
	// TO DO: The return value should reflect the actual situation.
sl@0
   690
	return ETrue;
sl@0
   691
	}
sl@0
   692
sl@0
   693
sl@0
   694
TInt Template::UsbConnect()
sl@0
   695
	{
sl@0
   696
	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbConnect"));
sl@0
   697
sl@0
   698
	// TO DO: Do here whatever is necessary for the UDC to appear on the bus (and thus to the host).
sl@0
   699
sl@0
   700
	return KErrNone;
sl@0
   701
	}
sl@0
   702
sl@0
   703
sl@0
   704
TInt Template::UsbDisconnect()
sl@0
   705
	{
sl@0
   706
	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbDisconnect"));
sl@0
   707
sl@0
   708
	// TO DO: Do here whatever is necessary for the UDC to appear disconnected from the bus (and thus from the
sl@0
   709
	// host).
sl@0
   710
sl@0
   711
	return KErrNone;
sl@0
   712
	}
sl@0
   713
sl@0
   714
sl@0
   715
void Template::UsbClientConnectorIsr(TAny *aPtr)
sl@0
   716
//
sl@0
   717
// Services the USB cable interrupt.
sl@0
   718
//
sl@0
   719
	{
sl@0
   720
	__KTRACE_OPT(KHARDWARE, Kern::Printf("Template::UsbClientConnectorIsr()"));
sl@0
   721
sl@0
   722
	Template* tm = static_cast<Template*>(aPtr);
sl@0
   723
sl@0
   724
	// TO DO: Service interrupt here: determmine cause, clear condition flag (if applicable), etc.
sl@0
   725
sl@0
   726
	if (tm->UsbClientConnectorInserted())
sl@0
   727
		{
sl@0
   728
		__KTRACE_OPT(KHARDWARE, Kern::Printf(" > USB cable now inserted."));
sl@0
   729
		}
sl@0
   730
	else
sl@0
   731
		{
sl@0
   732
		__KTRACE_OPT(KHARDWARE, Kern::Printf(" > USB cable now removed."));
sl@0
   733
		}
sl@0
   734
sl@0
   735
	// Important: Inform the USB stack.
sl@0
   736
	if (tm->iUsbClientConnectorCallback)
sl@0
   737
		{
sl@0
   738
		(*tm->iUsbClientConnectorCallback)(tm->iUsbClientConnectorCallbackArg);
sl@0
   739
		}
sl@0
   740
	}
sl@0
   741
sl@0
   742
sl@0
   743
//---eof