30 TUint32 NKern::IdleGenerationCount() |
26 TUint32 NKern::IdleGenerationCount() |
31 { |
27 { |
32 return TheScheduler.iIdleGenerationCount; |
28 return TheScheduler.iIdleGenerationCount; |
33 } |
29 } |
34 |
30 |
35 void NKern::Idle() |
31 void NKern::DoIdle() |
36 { |
32 { |
37 TScheduler& s = TheScheduler; |
33 TScheduler& s = TheScheduler; |
38 TSubScheduler& ss = SubScheduler(); // OK since idle thread is locked to CPU |
34 TSubScheduler& ss = SubScheduler(); // OK since idle thread is locked to CPU |
39 TUint32 m = ss.iCpuMask; |
35 TUint32 m = ss.iCpuMask; |
40 |
36 |
55 NKern::Lock(); |
51 NKern::Lock(); |
56 NKern::Unlock(); // process idle DFCs here |
52 NKern::Unlock(); // process idle DFCs here |
57 return; |
53 return; |
58 } |
54 } |
59 } |
55 } |
|
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 |
60 s.iIdleSpinLock.UnlockOnly(); // leave interrupts disabled |
65 s.iIdleSpinLock.UnlockOnly(); // leave interrupts disabled |
|
66 |
61 NKIdle(0); |
67 NKIdle(0); |
|
68 |
62 } |
69 } |
63 |
70 |
64 TUint32 ContextId() |
71 TUint32 ContextId() |
65 { |
72 { |
66 switch(NKern::CurrentContext()) |
73 switch(NKern::CurrentContext()) |
312 |
319 |
313 |
320 |
314 void NKern::Init0(TAny* a) |
321 void NKern::Init0(TAny* a) |
315 { |
322 { |
316 __KTRACE_OPT(KBOOT,DEBUGPRINT("VIB=%08x", a)); |
323 __KTRACE_OPT(KBOOT,DEBUGPRINT("VIB=%08x", a)); |
317 VIB = (SVariantInterfaceBlock*)a; |
324 SVariantInterfaceBlock* v = (SVariantInterfaceBlock*)a; |
318 __NK_ASSERT_ALWAYS(VIB && VIB->iVer==0 && VIB->iSize==sizeof(SVariantInterfaceBlock)); |
325 TheScheduler.iVIB = v; |
319 __KTRACE_OPT(KBOOT,DEBUGPRINT("iVer=%d iSize=%d", VIB->iVer, VIB->iSize)); |
326 __NK_ASSERT_ALWAYS(v && v->iVer==0 && v->iSize==sizeof(SVariantInterfaceBlock)); |
320 __KTRACE_OPT(KBOOT,DEBUGPRINT("iMaxCpuClock=%08x %08x", I64HIGH(VIB->iMaxCpuClock), I64LOW(VIB->iMaxCpuClock))); |
327 __KTRACE_OPT(KBOOT,DEBUGPRINT("iVer=%d iSize=%d", v->iVer, v->iSize)); |
321 __KTRACE_OPT(KBOOT,DEBUGPRINT("iTimestampFreq=%u", VIB->iTimestampFreq)); |
328 __KTRACE_OPT(KBOOT,DEBUGPRINT("iMaxCpuClock=%08x %08x", I64HIGH(v->iMaxCpuClock), I64LOW(v->iMaxCpuClock))); |
322 __KTRACE_OPT(KBOOT,DEBUGPRINT("iMaxTimerClock=%u", VIB->iMaxTimerClock)); |
329 __KTRACE_OPT(KBOOT,DEBUGPRINT("iTimestampFreq=%u", v->iTimestampFreq)); |
|
330 __KTRACE_OPT(KBOOT,DEBUGPRINT("iMaxTimerClock=%u", v->iMaxTimerClock)); |
323 TInt i; |
331 TInt i; |
324 for (i=0; i<KMaxCpus; ++i) |
332 for (i=0; i<KMaxCpus; ++i) |
325 { |
333 { |
326 TSubScheduler& ss = TheSubSchedulers[i]; |
334 TSubScheduler& ss = TheSubSchedulers[i]; |
327 ss.i_TimerMultF = (TAny*)KMaxTUint32; |
335 ss.iSSX.iCpuFreqRI.Set(v->iCpuFreqR[i]); |
328 ss.i_TimerMultI = (TAny*)0x01000000u; |
336 ss.iSSX.iTimerFreqRI.Set(v->iTimerFreqR[i]); |
329 ss.i_CpuMult = (TAny*)KMaxTUint32; |
337 |
330 VIB->iTimerMult[i] = (volatile STimerMult*)&ss.i_TimerMultF; |
338 ss.iSSX.iTimestampOffset.i64 = 0; |
331 VIB->iCpuMult[i] = (volatile TUint32*)&ss.i_CpuMult; |
339 v->iCpuFreqR[i] = 0; |
332 } |
340 v->iTimerFreqR[i] = 0; |
333 TheScheduler.i_TimerMax = (TAny*)(VIB->iMaxTimerClock / 128); |
341 } |
|
342 TheScheduler.iSX.iTimerMax = (v->iMaxTimerClock / 128); |
334 InitFpu(); |
343 InitFpu(); |
335 InterruptInit0(); |
344 InterruptInit0(); |
336 } |
345 } |
337 |
346 |
338 EXPORT_C TUint32 NKern::CpuTimeMeasFreq() |
347 EXPORT_C TUint32 NKern::CpuTimeMeasFreq() |
349 @pre aMicroseconds should be nonnegative |
358 @pre aMicroseconds should be nonnegative |
350 @pre any context |
359 @pre any context |
351 */ |
360 */ |
352 EXPORT_C TInt NKern::TimesliceTicks(TUint32 aMicroseconds) |
361 EXPORT_C TInt NKern::TimesliceTicks(TUint32 aMicroseconds) |
353 { |
362 { |
354 TUint32 mf32 = (TUint32)TheScheduler.i_TimerMax; |
363 TUint32 mf32 = (TUint32)TheScheduler.iSX.iTimerMax; |
355 TUint64 mf(mf32); |
364 TUint64 mf(mf32); |
356 TUint64 ticks = mf*TUint64(aMicroseconds) + UI64LIT(999999); |
365 TUint64 ticks = mf*TUint64(aMicroseconds) + UI64LIT(999999); |
357 ticks /= UI64LIT(1000000); |
366 ticks /= UI64LIT(1000000); |
358 if (ticks > TUint64(TInt(KMaxTInt))) |
367 if (ticks > TUint64(TInt(KMaxTInt))) |
359 return KMaxTInt; |
368 return KMaxTInt; |
360 else |
369 else |
361 return (TInt)ticks; |
370 return (TInt)ticks; |
362 } |
371 } |
363 |
372 |
|
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 } |