/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: implementation of class Syborg
*
*/
#include <syborg_priv.h>
#include <hal_data.h>
#ifdef __EMI_SUPPORT__
#include <emi.h>
#endif
//#define ASSP_DEBUG
#ifdef ASSP_DEBUG
#define __DEBUG_PRINT(format...) Kern::Printf(format)
#else
#define __DEBUG_PRINT(format...) __KTRACE_OPT(KBOOT,Kern::Printf(format))
#endif
Syborg* Syborg::Variant=NULL;
// !@!
#if 0
TPhysAddr Syborg::VideoRamPhys;
TPhysAddr Syborg::VideoRamPhysSecure; // Secure display memory
#endif
GLDEF_D Syborg TheVariant;
// Wait for interrupt idle routine
extern TInt SyborgWFIIdle();
DECLARE_STANDARD_ASSP()
EXPORT_C Asic* VariantInitialise()
{
return &TheVariant;
}
void Syborg::Idle()
{
// Use the basic Wait For Interrupt call to idle
TInt irq = NKern::DisableAllInterrupts();
#ifdef __EMI_SUPPORT__
EMI::EnterIdle();
#endif
SyborgWFIIdle();
#ifdef __EMI_SUPPORT__
EMI::LeaveIdle();
#endif
NKern::RestoreInterrupts(irq);
}
TUint32 Syborg::NanoWaitCalibration()
{
return 17; // 2 cycles approx 17ns at 125MHz
}
TInt Syborg::VariantHal(TInt aFunction, TAny* a1, TAny* a2)
{
__KTRACE_OPT(KHARDWARE,Kern::Printf("Syborg::VariantHal(%d, %0x, %0x)",aFunction,a1,a2));
switch(aFunction)
{
case EVariantHalVariantInfo:
{
TVariantInfoV01Buf infoBuf;
TVariantInfoV01& info = infoBuf();
TUint clock=0;
info.iRomVersion = Epoc::RomHeader().iVersion;
info.iMachineUniqueId = (TInt64(HALData::EMachineUid_OmapH4)<<32);
info.iLedCapabilities = (8<<16) + KLedMaskGreen1;
info.iProcessorClockInKHz = clock;
info.iSpeedFactor = clock/25;
Kern::InfoCopy(*(TDes8*)a1,infoBuf);
break;
}
case EVariantHalDebugPortSet:
{
TUint32 thePort = (TUint32)a1;
switch(thePort) // Accept UART(0-3)
{
case 0:
case 1:
case 2:
case 3:
{
TSyborg::MarkDebugPortOff(); // mark port is not initialised
Kern::SuperPage().iDebugPort = thePort; // update the super page
Syborg::DebugInit(); // init debug port
break;
}
case (TUint32)KNullDebugPort: // debug output supressed
{
TSyborg::MarkDebugPortOff(); // mark port is not initialised
Kern::SuperPage().iDebugPort = thePort; // update the super page
break;
}
default:
return KErrNotSupported;
}
break;
}
case EVariantHalDebugPortGet:
{
TUint32 thePort = Kern::SuperPage().iDebugPort;
kumemput32(a1, &thePort, sizeof(TUint32));
break;
}
case EVariantHalSwitches:
{
TUint32 x = 0; //Register32(KHwBaseSystemReg+KHoRoSystemSw);
kumemput32(a1, &x, sizeof(x));
break;
}
case EVariantHalLedMaskSet:
{
//SetRegister32(KHwBaseSystemReg+KHoRwSystemLed, (TUint32)a1 & 0xFF);
break;
}
case EVariantHalLedMaskGet:
{
TUint32 x = 0; //Register32(KHwBaseSystemReg+KHoRwSystemLed);
kumemput32(a1, &x, sizeof(x));
break;
}
case EVariantHalCustomRestartReason:
{
// Restart reason is stored in super page
TInt x = (Kern::SuperPage().iHwStartupReason); // & KmRestartCustomReasons) >> KsRestartCustomReasons;
kumemput32(a1, &x, sizeof(TInt));
break;
}
case EVariantHalCustomRestart:
{
__KERNEL_CAPABILITY_CHECK(
if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,
__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EVariantHalCustomRestart")))
return KErrPermissionDenied;
)
Kern::Restart(0);
break;
}
default:
{
return KErrNotSupported;
}
}
return KErrNone;
}
TPtr8 Syborg::MachineConfiguration()
{
return TPtr8((TUint8*)&Kern::MachineConfig(),40,40);
}
EXPORT_C Syborg::Syborg()
{
iDebugPortBase = TSyborg::DebugPortAddr(); // initialised in bootstrap
}
EXPORT_C TMachineStartupType Syborg::StartupReason()
{
TUint s = Kern::SuperPage().iHwStartupReason;
__DEBUG_PRINT("Syborg::StartupReason CPU page value 0x%08X", s);
return EStartupColdReset;
}
EXPORT_C void Syborg::Init1()
{
__DEBUG_PRINT("Syborg::Init1()");
// Enable the CLCD in the System registers
SyborgInterrupt::Init1();
}
EXPORT_C void Syborg::Init3()
{
NTimerQ& m = *(NTimerQ*)NTimerQ::TimerAddress();
m.iRounding = -5;
TInt r = Interrupt::Bind(EIntTimer1,SyborgInterrupt::MsTimerTick,&m);
if (r != KErrNone)
{
Kern::Fault("BindMsTick",r);
}
TSyborg::Init3();
TSyborg::ClearTimerInt(KHwBaseCounterTimer);
r = Interrupt::Enable(EIntTimer1);
if (r != KErrNone)
{
Kern::Fault("EnbMsTick",r);
}
TSyborg::SetTimerLoad(KHwBaseCounterTimer, K1000HzTickMatchLoad);
// TSyborg::SetTimerLoad(KHwBaseCounterTimer, 1000000);
TSyborg::SetTimerMode(KHwBaseCounterTimer, TSyborg::ETimerModePeriodic);
TSyborg::EnableTimerInterrupt(KHwBaseCounterTimer);
TSyborg::EnableTimer(KHwBaseCounterTimer, TSyborg::EEnable);
SyborgInterrupt::Init3();
// !@!
#if 0
// Allocate physical RAM for video
TInt vSize = TSyborg::VideoRamSize();
r = Epoc::AllocPhysicalRam(vSize,Syborg::VideoRamPhys);
if (r != KErrNone)
{
Kern::Fault("AllocVideoRam",r);
}
// Allocate physical RAM for secure display
r = Epoc::AllocPhysicalRam(vSize,Syborg::VideoRamPhysSecure);
if (r != KErrNone)
{
Kern::Fault("AllocVideoRam 2",r);
}
#endif
__DEBUG_PRINT("Finished Syborg::Init3()");
}
EXPORT_C void Syborg::DebugInit()
{
iDebugPortBase = TSyborg::DebugPortAddr();
if(iDebugPortBase != (TUint32)KNullDebugPort) // supress debug output
{
TUint8 res = ReadReg(iDebugPortBase, 0);
}
}
//
// Output a character to the debug port
//
EXPORT_C void Syborg::DebugOutput(TUint aLetter)
{
if(!iDebugPortBase)
{
DebugInit();
}
if(iDebugPortBase != (TUint32)KNullDebugPort) // supress debug output
{
WriteReg(iDebugPortBase,1,aLetter);
}
}
EXPORT_C TInt Syborg::MsTickPeriod()
{
return 1000;
}
EXPORT_C TInt Syborg::SystemTimeInSecondsFrom2000(TInt& aTime)
{
__KTRACE_OPT(KHARDWARE,Kern::Printf("RTC READ: %d",aTime));
return KErrNone;
}
EXPORT_C TInt Syborg::SetSystemTimeInSecondsFrom2000(TInt aTime)
{
__KTRACE_OPT(KHARDWARE,Kern::Printf("Set RTC: %d",aTime)); // do this here to allow the value to be loaded...
return KErrNone;
}