kernel/eka/nkernsmp/x86/ncutils.cpp
branchRCL_3
changeset 44 3e88ff8f41d5
parent 43 c1f20ce4abcf
equal deleted inserted replaced
43:c1f20ce4abcf 44:3e88ff8f41d5
    15 // 
    15 // 
    16 //
    16 //
    17 
    17 
    18 #include <x86.h>
    18 #include <x86.h>
    19 
    19 
       
    20 extern "C" {
       
    21 extern SVariantInterfaceBlock* VIB;
       
    22 }
       
    23 
    20 //#define __DBG_MON_FAULT__
    24 //#define __DBG_MON_FAULT__
    21 //#define __RAM_LOADED_CODE__
    25 //#define __RAM_LOADED_CODE__
    22 //#define __EARLY_DEBUG__
    26 //#define __EARLY_DEBUG__
    23 void InitFpu();
    27 void InitFpu();
    24 
    28 
    26 TUint32 NKern::IdleGenerationCount()
    30 TUint32 NKern::IdleGenerationCount()
    27 	{
    31 	{
    28 	return TheScheduler.iIdleGenerationCount;
    32 	return TheScheduler.iIdleGenerationCount;
    29 	}
    33 	}
    30 
    34 
    31 void NKern::DoIdle()
    35 void NKern::Idle()
    32 	{
    36 	{
    33 	TScheduler& s = TheScheduler;
    37 	TScheduler& s = TheScheduler;
    34 	TSubScheduler& ss = SubScheduler();	// OK since idle thread is locked to CPU
    38 	TSubScheduler& ss = SubScheduler();	// OK since idle thread is locked to CPU
    35 	TUint32 m = ss.iCpuMask;
    39 	TUint32 m = ss.iCpuMask;
    36 
    40 
    51 			NKern::Lock();
    55 			NKern::Lock();
    52 			NKern::Unlock();	// process idle DFCs here
    56 			NKern::Unlock();	// process idle DFCs here
    53 			return;
    57 			return;
    54 			}
    58 			}
    55 		}
    59 		}
    56 	if (ss.iCurrentThread->iSavedSP)
       
    57 		{
       
    58 		// rescheduled between entry to NKern::Idle() and here
       
    59 		// go round again to see if any more threads to pull from other CPUs
       
    60 		__e32_atomic_ior_ord32(&s.iCpusNotIdle, m);	// we aren't idle after all
       
    61 		s.iIdleSpinLock.UnlockIrq();
       
    62 		return;
       
    63 		}
       
    64 
       
    65 	s.iIdleSpinLock.UnlockOnly();	// leave interrupts disabled
    60 	s.iIdleSpinLock.UnlockOnly();	// leave interrupts disabled
    66 
       
    67 	NKIdle(0);
    61 	NKIdle(0);
    68 	
       
    69 	}
    62 	}
    70 
    63 
    71 TUint32 ContextId()
    64 TUint32 ContextId()
    72 	{
    65 	{
    73 	switch(NKern::CurrentContext())
    66 	switch(NKern::CurrentContext())
   319 
   312 
   320 
   313 
   321 void NKern::Init0(TAny* a)
   314 void NKern::Init0(TAny* a)
   322 	{
   315 	{
   323 	__KTRACE_OPT(KBOOT,DEBUGPRINT("VIB=%08x", a));
   316 	__KTRACE_OPT(KBOOT,DEBUGPRINT("VIB=%08x", a));
   324 	SVariantInterfaceBlock* v = (SVariantInterfaceBlock*)a;
   317 	VIB = (SVariantInterfaceBlock*)a;
   325 	TheScheduler.iVIB = v;
   318 	__NK_ASSERT_ALWAYS(VIB && VIB->iVer==0 && VIB->iSize==sizeof(SVariantInterfaceBlock));
   326 	__NK_ASSERT_ALWAYS(v && v->iVer==0 && v->iSize==sizeof(SVariantInterfaceBlock));
   319 	__KTRACE_OPT(KBOOT,DEBUGPRINT("iVer=%d iSize=%d", VIB->iVer, VIB->iSize));
   327 	__KTRACE_OPT(KBOOT,DEBUGPRINT("iVer=%d iSize=%d", v->iVer, v->iSize));
   320 	__KTRACE_OPT(KBOOT,DEBUGPRINT("iMaxCpuClock=%08x %08x", I64HIGH(VIB->iMaxCpuClock), I64LOW(VIB->iMaxCpuClock)));
   328 	__KTRACE_OPT(KBOOT,DEBUGPRINT("iMaxCpuClock=%08x %08x", I64HIGH(v->iMaxCpuClock), I64LOW(v->iMaxCpuClock)));
   321 	__KTRACE_OPT(KBOOT,DEBUGPRINT("iTimestampFreq=%u", VIB->iTimestampFreq));
   329 	__KTRACE_OPT(KBOOT,DEBUGPRINT("iTimestampFreq=%u", v->iTimestampFreq));
   322 	__KTRACE_OPT(KBOOT,DEBUGPRINT("iMaxTimerClock=%u", VIB->iMaxTimerClock));
   330 	__KTRACE_OPT(KBOOT,DEBUGPRINT("iMaxTimerClock=%u", v->iMaxTimerClock));
       
   331 	TInt i;
   323 	TInt i;
   332 	for (i=0; i<KMaxCpus; ++i)
   324 	for (i=0; i<KMaxCpus; ++i)
   333 		{
   325 		{
   334 		TSubScheduler& ss = TheSubSchedulers[i];
   326 		TSubScheduler& ss = TheSubSchedulers[i];
   335 		ss.iSSX.iCpuFreqRI.Set(v->iCpuFreqR[i]);
   327 		ss.i_TimerMultF = (TAny*)KMaxTUint32;
   336 		ss.iSSX.iTimerFreqRI.Set(v->iTimerFreqR[i]);
   328 		ss.i_TimerMultI = (TAny*)0x01000000u;
   337 
   329 		ss.i_CpuMult = (TAny*)KMaxTUint32;
   338 		ss.iSSX.iTimestampOffset.i64 = 0;
   330 		VIB->iTimerMult[i] = (volatile STimerMult*)&ss.i_TimerMultF;
   339 		v->iCpuFreqR[i] = 0;
   331 		VIB->iCpuMult[i] = (volatile TUint32*)&ss.i_CpuMult;
   340 		v->iTimerFreqR[i] = 0;
   332 		}
   341 		}
   333 	TheScheduler.i_TimerMax = (TAny*)(VIB->iMaxTimerClock / 128);
   342 	TheScheduler.iSX.iTimerMax = (v->iMaxTimerClock / 128);
       
   343 	InitFpu();
   334 	InitFpu();
   344 	InterruptInit0();
   335 	InterruptInit0();
   345 	}
   336 	}
   346 
   337 
   347 EXPORT_C TUint32 NKern::CpuTimeMeasFreq()
   338 EXPORT_C TUint32 NKern::CpuTimeMeasFreq()
   358  	@pre aMicroseconds should be nonnegative
   349  	@pre aMicroseconds should be nonnegative
   359 	@pre any context
   350 	@pre any context
   360  */
   351  */
   361 EXPORT_C TInt NKern::TimesliceTicks(TUint32 aMicroseconds)
   352 EXPORT_C TInt NKern::TimesliceTicks(TUint32 aMicroseconds)
   362 	{
   353 	{
   363 	TUint32 mf32 = (TUint32)TheScheduler.iSX.iTimerMax;
   354 	TUint32 mf32 = (TUint32)TheScheduler.i_TimerMax;
   364 	TUint64 mf(mf32);
   355 	TUint64 mf(mf32);
   365 	TUint64 ticks = mf*TUint64(aMicroseconds) + UI64LIT(999999);
   356 	TUint64 ticks = mf*TUint64(aMicroseconds) + UI64LIT(999999);
   366 	ticks /= UI64LIT(1000000);
   357 	ticks /= UI64LIT(1000000);
   367 	if (ticks > TUint64(TInt(KMaxTInt)))
   358 	if (ticks > TUint64(TInt(KMaxTInt)))
   368 		return KMaxTInt;
   359 		return KMaxTInt;
   369 	else
   360 	else
   370 		return (TInt)ticks;
   361 		return (TInt)ticks;
   371 	}
   362 	}
   372 
   363 
   373 TBool TSubScheduler::Detached()
       
   374 	{
       
   375 	return FALSE;
       
   376 	}
       
   377 
       
   378 TBool TScheduler::CoreControlSupported()
       
   379 	{
       
   380 	return FALSE;
       
   381 	}
       
   382 
       
   383 void TScheduler::CCInitiatePowerUp(TUint32 /*aCores*/)
       
   384 	{
       
   385 	}
       
   386 
       
   387 void TScheduler::CCIndirectPowerDown(TAny*)
       
   388 	{
       
   389 	}
       
   390 
       
   391 void TScheduler::DoFrequencyChanged(TAny*)
       
   392 	{
       
   393 	}