Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

initkr.c File Reference

#include "ki.h"

Go to the source code of this file.

Functions

VOID KiInitializeKernel (IN PKPROCESS Process, IN PKTHREAD Thread, IN PVOID IdleStack, IN PKPRCB Prcb, IN CCHAR Number, IN PLOADER_PARAMETER_BLOCK LoaderBlock)


Function Documentation

VOID KiInitializeKernel IN PKPROCESS  Process,
IN PKTHREAD  Thread,
IN PVOID  IdleStack,
IN PKPRCB  Prcb,
IN CCHAR  Number,
IN PLOADER_PARAMETER_BLOCK  LoaderBlock
 

Definition at line 41 of file mips/initkr.c.

References APC_LEVEL, _BOOT_STATUS::BootFinished, _RESTART_BLOCK::BootStatus, DISPATCH_LEVEL, EXCEPTION_EXECUTE_HANDLER, ExpInitializeExecutive(), FALSE, HalInitializeProcessor(), HIGH_LEVEL, Index, IPI_LEVEL, KdInitSystem(), KeActiveProcessors, KeBugCheck(), KeBusError(), KeFeatureBits, KeInitializeProcess(), KeInitializeSpinLock(), KeInitializeThread(), KeLoaderBlock, KeMaximumIncrement, KeNumberProcessors, KeProcessorArchitecture, KeProcessorLevel, KeProcessorRevision, KeRaiseIrql(), KeSetPriorityThread(), KiAdjustDpcThreshold, KiApcInterrupt(), KiComputeReciprocal(), KiContextSwapLock, KiDispatchInterrupt(), KiDmaIoCoherency, KiIdleSummary, KiInitSystem(), KiMaximumDpcQueueDepth, KiMinimumDpcRate, KiPassiveRelease(), KiProcessorBlock, KiTimeIncrementReciprocal, KiTimeIncrementShiftCount, KiUnexpectedInterrupt(), MAXIMUM_PROCESSORS, NULL, PAGE_SIZE, PASSIVE_LEVEL, PDI_SHIFT, PKSTART_ROUTINE, PKSYSTEM_ROUTINE, PRCB_MAJOR_VERSION, PRCB_MINOR_VERSION, Running, SetMember, and USHORT.

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 // Perform platform dependent processor initialization. 00095 // 00096 00097 HalInitializeProcessor(Number); 00098 00099 // 00100 // Save the address of the loader parameter block. 00101 // 00102 00103 KeLoaderBlock = LoaderBlock; 00104 00105 // 00106 // Initialize the processor block. 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 // Initialize DPC listhead and lock. 00153 // 00154 00155 InitializeListHead(&Prcb->DpcListHead); 00156 KeInitializeSpinLock(&Prcb->DpcLock); 00157 00158 // 00159 // Set address of processor block. 00160 // 00161 00162 KiProcessorBlock[Number] = Prcb; 00163 00164 // 00165 // Set global processor architecture, level and revision. The 00166 // latter two are the least common denominator on an MP system. 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 // Initialize the address of the bus error routines. 00183 // 00184 00185 PCR->DataBusError = KeBusError; 00186 PCR->InstructionBusError = KeBusError; 00187 00188 // 00189 // Initialize the idle thread initial kernel stack and limit address value. 00190 // 00191 00192 PCR->InitialStack = IdleStack; 00193 PCR->StackLimit = (PVOID)((ULONG)IdleStack - KERNEL_STACK_SIZE); 00194 00195 // 00196 // Initialize all interrupt vectors to transfer control to the unexpected 00197 // interrupt routine. 00198 // 00199 // N.B. This interrupt object is never actually "connected" to an interrupt 00200 // vector via KeConnectInterrupt. It is initialized and then connected 00201 // by simply storing the address of the dispatch code in the interrupt 00202 // vector. 00203 // 00204 00205 if (Number == 0) { 00206 00207 // 00208 // Initial the address of the interrupt dispatch routine. 00209 // 00210 00211 KxUnexpectedInterrupt.DispatchAddress = KiUnexpectedInterrupt; 00212 00213 // 00214 // Copy the interrupt dispatch code template into the interrupt object 00215 // and flush the dcache on all processors that the current thread can 00216 // run on to ensure that the code is actually in memory. 00217 // 00218 00219 for (Index = 0; Index < DISPATCH_LENGTH; Index += 1) { 00220 KxUnexpectedInterrupt.DispatchCode[Index] = KiInterruptTemplate[Index]; 00221 } 00222 00223 // 00224 // Set the default DMA I/O coherency attributes. 00225 // 00226 00227 KiDmaIoCoherency = 0; 00228 00229 // 00230 // Initialize the context swap spinlock. 00231 // 00232 00233 KeInitializeSpinLock(&KiContextSwapLock); 00234 00235 // 00236 // Sweep the data cache to make sure the dispatch code is flushed 00237 // to memory on the current processor. 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 // Initialize the profile count and interval. 00250 // 00251 00252 PCR->ProfileCount = 0; 00253 PCR->ProfileInterval = 0x200000; 00254 00255 // 00256 // Initialize the passive release, APC, and DPC interrupt vectors. 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 // Initialize the set member for the current processor, set IRQL to 00267 // APC_LEVEL, and set the processor number. 00268 // 00269 00270 PCR->CurrentIrql = APC_LEVEL; 00271 PCR->SetMember = 1 << Number; 00272 PCR->NotMember = ~PCR->SetMember; 00273 PCR->Number = Number; 00274 00275 // 00276 // Set the initial stall execution scale factor. This value will be 00277 // recomputed later by the HAL. 00278 // 00279 00280 PCR->StallScaleFactor = 50; 00281 00282 // 00283 // Set address of process object in thread object. 00284 // 00285 00286 Thread->ApcState.Process = Process; 00287 00288 // 00289 // Set the appropriate member in the active processors set. 00290 // 00291 00292 SetMember(Number, KeActiveProcessors); 00293 00294 // 00295 // Set the number of processors based on the maximum of the current 00296 // number of processors and the current processor number. 00297 // 00298 00299 if ((Number + 1) > KeNumberProcessors) { 00300 KeNumberProcessors = Number + 1; 00301 } 00302 00303 // 00304 // If the initial processor is being initialized, then initialize the 00305 // per system data structures. 00306 // 00307 00308 if (Number == 0) { 00309 00310 // 00311 // Initialize the address of the restart block for the boot master. 00312 // 00313 00314 Prcb->RestartBlock = SYSTEM_BLOCK->RestartBlock; 00315 00316 // 00317 // Initialize the kernel debugger. 00318 // 00319 00320 if (KdInitSystem(LoaderBlock, FALSE) == FALSE) { 00321 KeBugCheck(PHASE0_INITIALIZATION_FAILED); 00322 } 00323 00324 // 00325 // Initialize processor block array. 00326 // 00327 00328 for (Index = 1; Index < MAXIMUM_PROCESSORS; Index += 1) { 00329 KiProcessorBlock[Index] = (PKPRCB)NULL; 00330 } 00331 00332 // 00333 // Perform architecture independent initialization. 00334 // 00335 00336 KiInitSystem(); 00337 00338 // 00339 // Initialize idle thread process object and then set: 00340 // 00341 // 1. all the quantum values to the maximum possible. 00342 // 2. the process in the balance set. 00343 // 3. the active processor mask to the specified processor. 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 // Initialize idle thread object and then set: 00358 // 00359 // 1. the initial kernel stack to the specified idle stack. 00360 // 2. the next processor number to the specified processor. 00361 // 3. the thread priority to the highest possible value. 00362 // 4. the state of the thread to running. 00363 // 5. the thread affinity to the specified processor. 00364 // 6. the specified processor member in the process active processors 00365 // set. 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 // If the current processor is 0, then set the appropriate bit in the 00383 // active summary of the idle process. 00384 // 00385 00386 if (Number == 0) { 00387 SetMember(Number, Process->ActiveProcessors); 00388 } 00389 00390 // 00391 // Execute the executive initialization. 00392 // 00393 00394 try { 00395 ExpInitializeExecutive(Number, LoaderBlock); 00396 00397 } except (EXCEPTION_EXECUTE_HANDLER) { 00398 KeBugCheck (PHASE0_EXCEPTION); 00399 } 00400 00401 // 00402 // If the initial processor is being initialized, then compute the 00403 // timer table reciprocal value and reset the PRCB values for the 00404 // controllable DPC behavior in order to reflect any registry 00405 // overrides. 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 // Raise IRQL to dispatch level and set the priority of the idle thread 00419 // to zero. This will have the effect of immediately causing the phase 00420 // one initialization thread to get scheduled for execution. The idle 00421 // thread priority is then set to the lowest realtime priority. This is 00422 // necessary so that mutexes aquired at DPC level do not cause the active 00423 // matrix to get corrupted. 00424 // 00425 00426 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); 00427 KeSetPriorityThread(Thread, (KPRIORITY)0); 00428 Thread->Priority = LOW_REALTIME_PRIORITY; 00429 00430 // 00431 // Raise IRQL to the highest level. 00432 // 00433 00434 KeRaiseIrql(HIGH_LEVEL, &OldIrql); 00435 00436 // 00437 // If a restart block exists for the current process, then set boot 00438 // completed. 00439 // 00440 // N.B. Firmware on uniprocessor machines configured for MP operation 00441 // can have a restart block address of NULL. 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 // If the current processor is not 0, then set the appropriate bit in 00453 // idle summary. 00454 // 00455 00456 if (Number != 0) { 00457 SetMember(Number, KiIdleSummary); 00458 } 00459 00460 #endif 00461 00462 return; 00463 } }


Generated on Sat May 15 19:44:12 2004 for test by doxygen 1.3.7