+ #if USE_MP
+ int i;
+ #endif
+
+ #if USE_MP
+ // Start APs
+ for( i = 0; i < giNumCPUs; i ++ )
+ {
+ int tid;
+ if(i) gaCPUs[i].Current = NULL;
+
+ // Create Idle Task
+ if( (tid = Proc_Clone(0, 0)) == 0)
+ {
+ for(;;) HALT(); // Just yeilds
+ }
+ gaCPUs[i].IdleThread = Threads_GetThread(tid);
+ gaCPUs[i].IdleThread->ThreadName = "Idle Thread";
+ Threads_SetTickets( gaCPUs[i].IdleThread, 0 ); // Never called randomly
+ gaCPUs[i].IdleThread->Quantum = 1; // 1 slice quantum
+
+
+ // Start the AP
+ if( i != giProc_BootProcessorID ) {
+ MP_StartAP( i );
+ }
+ }
+
+ // BSP still should run the current task
+ gaCPUs[0].Current = &gThreadZero;
+
+ // Start interrupts and wait for APs to come up
+ Log("Waiting for APs to come up\n");
+ __asm__ __volatile__ ("sti");
+ while( giNumInitingCPUs ) __asm__ __volatile__ ("hlt");
+ #else
+ // Create Idle Task
+ if(Proc_Clone(0, 0) == 0)
+ {
+ gpIdleThread = Proc_GetCurThread();
+ gpIdleThread->ThreadName = "Idle Thread";
+ gpIdleThread->NumTickets = 0; // Never called randomly
+ gpIdleThread->Quantum = 1; // 1 slice quantum
+ for(;;) HALT(); // Just yeilds
+ }
+
+ // Set current task
+ gCurrentThread = &gThreadZero;
+