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 } |
|