00052                    :
00053 
00054     This function gains 
control after 
the system has been bootstrapped and
00055     before 
the system has been initialized. Its function 
is to initialize
00056     
the kernel data structures, initialize 
the idle thread and process objects,
00057     initialize 
the processor 
control block, call 
the executive initialization
00058     routine, and then 
return to 
the system startup routine. This routine 
is
00059     also called to initialize 
the processor specific structures when a 
new
00060     processor 
is brought on line.
00061 
00062 Arguments:
00063 
00064     Process - Supplies a pointer to a 
control object of 
type process 
for
00065         
the specified processor.
00066 
00067     Thread - Supplies a pointer to a dispatcher object of 
type thread 
for
00068         
the specified processor.
00069 
00070     IdleStack - Supplies a pointer 
the base of 
the real kernel stack 
for
00071         idle thread on 
the specified processor.
00072 
00073     Prcb - Supplies a pointer to a processor 
control block 
for the specified
00074         processor.
00075 
00076     Number - Supplies 
the number of 
the processor that 
is being
00077         initialized.
00078 
00079     LoaderBlock - Supplies a pointer to 
the loader parameter block.
00080 
00081 Return Value:
00082 
00083     None.
00084 
00085 --*/
00086 
00087 {
00088 
00089     LONG 
Index;
00090     KIRQL OldIrql;
00091     
PRESTART_BLOCK RestartBlock;
00092 
00093     
00094     
00095     
00096 
00097     
HalInitializeProcessor(Number);
00098 
00099     
00100     
00101     
00102 
00103     
KeLoaderBlock = LoaderBlock;
00104 
00105     
00106     
00107     
00108 
00109     Prcb->MinorVersion = 
PRCB_MINOR_VERSION;
00110     Prcb->MajorVersion = 
PRCB_MAJOR_VERSION;
00111     Prcb->BuildType = 0;
00112 
00113 
#if DBG
00114 
00115     Prcb->BuildType |= PRCB_BUILD_DEBUG;
00116 
00117 
#endif
00118 
00119 
#if defined(NT_UP)
00120 
00121     Prcb->BuildType |= PRCB_BUILD_UNIPROCESSOR;
00122 
00123 
#endif
00124 
00125     Prcb->CurrentThread = Thread;
00126     Prcb->NextThread = (
PKTHREAD)
NULL;
00127     Prcb->IdleThread = Thread;
00128     Prcb->Number = Number;
00129     Prcb->SetMember = 1 << Number;
00130     Prcb->PcrPage = LoaderBlock->u.Mips.PcrPage;
00131 
00132 
#if !defined(NT_UP)
00133 
00134     Prcb->TargetSet = 0;
00135     Prcb->WorkerRoutine = 
NULL;
00136     Prcb->RequestSummary = 0;
00137     Prcb->IpiFrozen = 0;
00138 
00139 
#if NT_INST
00140 
00141     Prcb->IpiCounts = &KiIpiCounts[Number];
00142 
00143 
#endif
00144 
00145 
#endif
00146 
00147     Prcb->MaximumDpcQueueDepth = 
KiMaximumDpcQueueDepth;
00148     Prcb->MinimumDpcRate = 
KiMinimumDpcRate;
00149     Prcb->AdjustDpcThreshold = 
KiAdjustDpcThreshold;
00150 
00151     
00152     
00153     
00154 
00155     InitializeListHead(&Prcb->DpcListHead);
00156     
KeInitializeSpinLock(&Prcb->DpcLock);
00157 
00158     
00159     
00160     
00161 
00162     
KiProcessorBlock[Number] = Prcb;
00163 
00164     
00165     
00166     
00167     
00168 
00169     
KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_MIPS;
00170     
KeFeatureBits = 0;
00171     
if (
KeProcessorLevel == 0 ||
00172         
KeProcessorLevel > (
USHORT)(PCR->ProcessorId >> 8)) {
00173         
KeProcessorLevel = (
USHORT)(PCR->ProcessorId >> 8);
00174     }
00175 
00176     
if (
KeProcessorRevision == 0 ||
00177         
KeProcessorRevision > (
USHORT)(PCR->ProcessorId & 0xff)) {
00178         
KeProcessorRevision = (
USHORT)(PCR->ProcessorId & 0xff);
00179     }
00180 
00181     
00182     
00183     
00184 
00185     PCR->DataBusError = 
KeBusError;
00186     PCR->InstructionBusError = 
KeBusError;
00187 
00188     
00189     
00190     
00191 
00192     PCR->InitialStack = IdleStack;
00193     PCR->StackLimit = (PVOID)((ULONG)IdleStack - KERNEL_STACK_SIZE);
00194 
00195     
00196     
00197     
00198     
00199     
00200     
00201     
00202     
00203     
00204 
00205     
if (Number == 0) {
00206 
00207         
00208         
00209         
00210 
00211         KxUnexpectedInterrupt.DispatchAddress = 
KiUnexpectedInterrupt;
00212 
00213         
00214         
00215         
00216         
00217         
00218 
00219         
for (
Index = 0; 
Index < DISPATCH_LENGTH; 
Index += 1) {
00220             KxUnexpectedInterrupt.DispatchCode[
Index] = KiInterruptTemplate[
Index];
00221         }
00222 
00223         
00224         
00225         
00226 
00227         
KiDmaIoCoherency = 0;
00228 
00229         
00230         
00231         
00232 
00233         
KeInitializeSpinLock(&KiContextSwapLock);
00234 
00235         
00236         
00237         
00238         
00239 
00240         HalSweepDcache();
00241     }
00242 
00243     
for (
Index = 0; 
Index < MAXIMUM_VECTOR; 
Index += 1) {
00244         PCR->InterruptRoutine[
Index] =
00245                     (PKINTERRUPT_ROUTINE)(&KxUnexpectedInterrupt.DispatchCode);
00246     }
00247 
00248     
00249     
00250     
00251 
00252     PCR->ProfileCount = 0;
00253     PCR->ProfileInterval = 0x200000;
00254 
00255     
00256     
00257     
00258 
00259     PCR->InterruptRoutine[0] = 
KiPassiveRelease;
00260     PCR->InterruptRoutine[
APC_LEVEL] = 
KiApcInterrupt;
00261     PCR->InterruptRoutine[
DISPATCH_LEVEL] = 
KiDispatchInterrupt;
00262     PCR->ReservedVectors = (1 << 
PASSIVE_LEVEL) | (1 << 
APC_LEVEL) |
00263                                         (1 << 
DISPATCH_LEVEL) | (1 << 
IPI_LEVEL);
00264 
00265     
00266     
00267     
00268     
00269 
00270     PCR->CurrentIrql = 
APC_LEVEL;
00271     PCR->SetMember = 1 << Number;
00272     PCR->NotMember = ~PCR->SetMember;
00273     PCR->Number = Number;
00274 
00275     
00276     
00277     
00278     
00279 
00280     PCR->StallScaleFactor = 50;
00281 
00282     
00283     
00284     
00285 
00286     Thread->ApcState.Process = Process;
00287 
00288     
00289     
00290     
00291 
00292     
SetMember(Number, KeActiveProcessors);
00293 
00294     
00295     
00296     
00297     
00298 
00299     
if ((Number + 1) > 
KeNumberProcessors) {
00300         
KeNumberProcessors = Number + 1;
00301     }
00302 
00303     
00304     
00305     
00306     
00307 
00308     
if (Number == 0) {
00309 
00310         
00311         
00312         
00313 
00314         Prcb->RestartBlock = SYSTEM_BLOCK->RestartBlock;
00315 
00316         
00317         
00318         
00319 
00320         
if (
KdInitSystem(LoaderBlock, FALSE) == 
FALSE) {
00321             
KeBugCheck(PHASE0_INITIALIZATION_FAILED);
00322         }
00323 
00324         
00325         
00326         
00327 
00328         
for (
Index = 1; 
Index < 
MAXIMUM_PROCESSORS; 
Index += 1) {
00329             
KiProcessorBlock[
Index] = (PKPRCB)
NULL;
00330         }
00331 
00332         
00333         
00334         
00335 
00336         
KiInitSystem();
00337 
00338         
00339         
00340         
00341         
00342         
00343         
00344         
00345 
00346         
KeInitializeProcess(Process,
00347                             (KPRIORITY)0,
00348                             (KAFFINITY)(0xffffffff),
00349                             (PULONG)(PDE_BASE + ((PDE_BASE >> PDI_SHIFT - 2) & 0xffc)),
00350                             FALSE);
00351 
00352         Process->ThreadQuantum = MAXCHAR;
00353 
00354     }
00355 
00356     
00357     
00358     
00359     
00360     
00361     
00362     
00363     
00364     
00365     
00366     
00367 
00368     
KeInitializeThread(Thread, (PVOID)((ULONG)IdleStack - PAGE_SIZE),
00369                        (PKSYSTEM_ROUTINE)NULL, (PKSTART_ROUTINE)NULL,
00370                        (PVOID)NULL, (PCONTEXT)NULL, (PVOID)NULL, Process);
00371 
00372     Thread->InitialStack = IdleStack;
00373     Thread->StackBase = IdleStack;
00374     Thread->StackLimit = (PVOID)((ULONG)IdleStack - KERNEL_STACK_SIZE);
00375     Thread->NextProcessor = Number;
00376     Thread->Priority = HIGH_PRIORITY;
00377     Thread->State = 
Running;
00378     Thread->Affinity = (KAFFINITY)(1 << Number);
00379     Thread->WaitIrql = 
DISPATCH_LEVEL;
00380 
00381     
00382     
00383     
00384     
00385 
00386     
if (Number == 0) {
00387         
SetMember(Number, Process->ActiveProcessors);
00388     }
00389 
00390     
00391     
00392     
00393 
00394     
try {
00395         
ExpInitializeExecutive(Number, LoaderBlock);
00396 
00397     } except (EXCEPTION_EXECUTE_HANDLER) {
00398         
KeBugCheck (PHASE0_EXCEPTION);
00399     }
00400 
00401     
00402     
00403     
00404     
00405     
00406     
00407 
00408     
if (Number == 0) {
00409         
KiTimeIncrementReciprocal = 
KiComputeReciprocal((LONG)KeMaximumIncrement,
00410                                                         &KiTimeIncrementShiftCount);
00411 
00412         Prcb->MaximumDpcQueueDepth = 
KiMaximumDpcQueueDepth;
00413         Prcb->MinimumDpcRate = 
KiMinimumDpcRate;
00414         Prcb->AdjustDpcThreshold = 
KiAdjustDpcThreshold;
00415     }
00416 
00417     
00418     
00419     
00420     
00421     
00422     
00423     
00424     
00425 
00426     
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
00427     
KeSetPriorityThread(Thread, (KPRIORITY)0);
00428     Thread->Priority = LOW_REALTIME_PRIORITY;
00429 
00430     
00431     
00432     
00433 
00434     
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
00435 
00436     
00437     
00438     
00439     
00440     
00441     
00442     
00443 
00444 
#if !defined(NT_UP)
00445 
00446     RestartBlock = Prcb->RestartBlock;
00447     
if (RestartBlock != 
NULL) {
00448         RestartBlock->
BootStatus.
BootFinished = 1;
00449     }
00450 
00451     
00452     
00453     
00454     
00455 
00456     
if (Number != 0) {
00457         
SetMember(Number, KiIdleSummary);
00458     }
00459 
00460 
#endif
00461 
00462     
return;
00463 }
}