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)

Variables

KSPIN_LOCK KiTbBroadcastLock
KSPIN_LOCK KiMasterRidLock
KSPIN_LOCK KiCacheFlushLock
ULONG_PTR KiUserSharedDataPage
ULONG_PTR KiKernelPcrPage = 0i64


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 78 of file ia64/initkr.c.

References APC_LEVEL, DBG_STATUS_CONTROL_C, DISPATCH_LEVEL, DMA_READ_DCACHE_INVALIDATE, DMA_WRITE_DCACHE_SNOOP, EXCEPTION_EXECUTE_HANDLER, ExpInitializeExecutive(), FALSE, HalInitializeProcessor(), HIGH_LEVEL, Index, KdInitSystem(), KdPollBreakIn(), KeActiveProcessors, KeBugCheck(), KeFeatureBits, KeInitializeProcess(), KeInitializeSpinLock(), KeInitializeThread(), KeLoaderBlock, KeLowerIrql(), KeMaximumIncrement, KeNumberProcessors, KeProcessorArchitecture, KeProcessorLevel, KeProcessorRevision, KeRaiseIrql(), KeSetPriorityThread(), KiAdjustDpcThreshold, KiApcInterrupt(), KiCacheFlushLock, KiComputeReciprocal(), KiContextSwapLock, KiDispatchInterrupt(), KiDmaIoCoherency, KiIdleSummary, KiInitSystem(), KiMasterRidLock, KiMaximumDpcQueueDepth, KiMinimumDpcRate, KiPassiveRelease(), KiProcessorBlock, KiTbBroadcastLock, KiTimeIncrementReciprocal, KiTimeIncrementShiftCount, KiUnexpectedInterrupt(), KiUserSharedDataPage, MAXIMUM_PROCESSORS, NULL, PAGE_SIZE, PASSIVE_LEVEL, PKSTART_ROUTINE, PKSYSTEM_ROUTINE, PoInitializePrcb(), PRCB_MAJOR_VERSION, PRCB_MINOR_VERSION, PsNtosImageBase, RtlImageDirectoryEntryToData(), Running, SetMember, Size, TRUE, and VOID().

00089 : 00090 00091 This function gains control after the system has been bootstrapped and 00092 before the system has been initialized. Its function is to initialize 00093 the kernel data structures, initialize the idle thread and process objects, 00094 initialize the processor control block, call the executive initialization 00095 routine, and then return to the system startup routine. This routine is 00096 also called to initialize the processor specific structures when a new 00097 processor is brought on line. 00098 00099 Arguments: 00100 00101 Process - Supplies a pointer to a control object of type process for 00102 the specified processor. 00103 00104 Thread - Supplies a pointer to a dispatcher object of type thread for 00105 the specified processor. 00106 00107 IdleStack - Supplies a pointer the base of the real kernel stack for 00108 idle thread on the specified processor. 00109 00110 Prcb - Supplies a pointer to a processor control block for the specified 00111 processor. 00112 00113 Number - Supplies the number of the processor that is being 00114 initialized. 00115 00116 LoaderBlock - Supplies a pointer to the loader parameter block. 00117 00118 Return Value: 00119 00120 None. 00121 00122 --*/ 00123 00124 { 00125 00126 LONG Index; 00127 KIRQL OldIrql; 00128 ULONG_PTR DirectoryTableBase[2]; 00129 00130 // 00131 // Perform platform dependent processor initialization. 00132 // 00133 00134 HalInitializeProcessor(Number, LoaderBlock); 00135 00136 // 00137 // Save the address of the loader parameter block. 00138 // 00139 00140 KeLoaderBlock = LoaderBlock; 00141 00142 // 00143 // Initialize the processor block. 00144 // 00145 00146 Prcb->MinorVersion = PRCB_MINOR_VERSION; 00147 Prcb->MajorVersion = PRCB_MAJOR_VERSION; 00148 Prcb->BuildType = 0; 00149 00150 #if DBG 00151 00152 Prcb->BuildType |= PRCB_BUILD_DEBUG; 00153 00154 #endif 00155 00156 #if defined(NT_UP) 00157 00158 Prcb->BuildType |= PRCB_BUILD_UNIPROCESSOR; 00159 00160 #endif 00161 00162 Prcb->CurrentThread = Thread; 00163 Prcb->NextThread = (PKTHREAD)NULL; 00164 Prcb->IdleThread = Thread; 00165 Prcb->Number = Number; 00166 Prcb->SetMember = 1 << Number; 00167 Prcb->PcrPage = LoaderBlock->u.Ia64.PcrPage; 00168 00169 #if !defined(NT_UP) 00170 00171 Prcb->TargetSet = 0; 00172 Prcb->WorkerRoutine = NULL; 00173 Prcb->RequestSummary = 0; 00174 Prcb->IpiFrozen = 0; 00175 00176 #if NT_INST 00177 00178 Prcb->IpiCounts = &KiIpiCounts[Number]; 00179 00180 #endif 00181 00182 #endif 00183 00184 Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth; 00185 Prcb->MinimumDpcRate = KiMinimumDpcRate; 00186 Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold; 00187 00188 // 00189 // Initialize DPC listhead and lock. 00190 // 00191 00192 InitializeListHead(&Prcb->DpcListHead); 00193 KeInitializeSpinLock(&Prcb->DpcLock); 00194 00195 // 00196 // Set address of processor block. 00197 // 00198 00199 KiProcessorBlock[Number] = Prcb; 00200 00201 // 00202 // Initialize processors PowerState 00203 // 00204 00205 PoInitializePrcb (Prcb); 00206 00207 // 00208 // Set global processor architecture, level and revision. The 00209 // latter two are the least common denominator on an MP system. 00210 // 00211 00212 KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_IA64; 00213 KeFeatureBits = 0; 00214 // *** TBD when processor info available 00215 // if ( KeProcessorLevel == 0 || 00216 // KeProcessorLevel > (USHORT)(PCR->ProcessorId >> 8) 00217 // ) { 00218 // KeProcessorLevel = (USHORT)(PCR->ProcessorId >> 8); 00219 // } 00220 // if ( KeProcessorRevision == 0 || 00221 // KeProcessorRevision > (USHORT)(PCR->ProcessorId & 0xFF) 00222 // ) { 00223 // KeProcessorRevision = (USHORT)(PCR->ProcessorId & 0xFF); 00224 // } 00225 00226 KeProcessorLevel = 1; 00227 KeProcessorRevision = 1; 00228 00229 // 00230 // Initialize the address of the bus error routines / machine check 00231 // 00232 // **** TBD 00233 00234 // 00235 // Initialize the idle thread initial kernel stack and limit address value. 00236 // 00237 00238 PCR->InitialStack = (ULONGLONG)IdleStack; 00239 PCR->InitialBStore = (ULONGLONG)IdleStack; 00240 PCR->StackLimit = (ULONGLONG)((ULONG_PTR)IdleStack - KERNEL_STACK_SIZE); 00241 PCR->BStoreLimit = (ULONGLONG)((ULONG_PTR)IdleStack + KERNEL_BSTORE_SIZE); 00242 00243 // 00244 // Initialize all interrupt vectors to transfer control to the unexpected 00245 // interrupt routine. 00246 // 00247 // N.B. This interrupt object is never actually "connected" to an interrupt 00248 // vector via KeConnectInterrupt. It is initialized and then connected 00249 // by simply storing the address of the dispatch code in the interrupt 00250 // vector. 00251 // 00252 00253 if (Number == 0) { 00254 00255 // 00256 // Initialize the context swap spinlock. 00257 // 00258 00259 KeInitializeSpinLock(&KiContextSwapLock); 00260 00261 // 00262 // Initialize the Tb Broadcast spinlock. 00263 // 00264 00265 KeInitializeSpinLock(&KiTbBroadcastLock); 00266 00267 // 00268 // Initialize the Master Rid spinlock. 00269 // 00270 00271 KeInitializeSpinLock(&KiMasterRidLock); 00272 00273 // 00274 // Initialize the cache flush spinlock. 00275 // 00276 00277 KeInitializeSpinLock(&KiCacheFlushLock); 00278 00279 // 00280 // Initial the address of the interrupt dispatch routine. 00281 // 00282 00283 KxUnexpectedInterrupt.DispatchAddress = KiUnexpectedInterrupt; 00284 00285 // 00286 // Copy the interrupt dispatch function descriptor into the interrupt 00287 // object. 00288 // 00289 00290 for (Index = 0; Index < DISPATCH_LENGTH; Index += 1) { 00291 KxUnexpectedInterrupt.DispatchCode[Index] = 00292 *(((PULONG)(KxUnexpectedInterrupt.DispatchAddress))+Index); 00293 } 00294 00295 // 00296 // Set the default DMA I/O coherency attributes. IA64 00297 // architecture dictates that the D-Cache is fully coherent. 00298 // 00299 00300 KiDmaIoCoherency = DMA_READ_DCACHE_INVALIDATE | DMA_WRITE_DCACHE_SNOOP; 00301 00302 // 00303 // Set KiSharedUserData for MP boot 00304 // 00305 00306 KiUserSharedDataPage = LoaderBlock->u.Ia64.PcrPage2; 00307 00308 } 00309 00310 // 00311 // Point to UnexpectedInterrupt function pointer 00312 // 00313 00314 for (Index = 0; Index < MAXIMUM_VECTOR; Index += 1) { 00315 PCR->InterruptRoutine[Index] = 00316 (PKINTERRUPT_ROUTINE)(&KxUnexpectedInterrupt.DispatchCode); 00317 } 00318 00319 // 00320 // Initialize the profile count and interval. 00321 // 00322 00323 PCR->ProfileCount = 0; 00324 PCR->ProfileInterval = 0x200000; 00325 00326 // 00327 // Initialize the passive release, APC, and DPC interrupt vectors. 00328 // 00329 00330 PCR->InterruptRoutine[0] = KiPassiveRelease; 00331 PCR->InterruptRoutine[APC_VECTOR] = KiApcInterrupt; 00332 PCR->InterruptRoutine[DISPATCH_VECTOR] = KiDispatchInterrupt; 00333 00334 // 00335 // N.B. Reserve levels, not vectors 00336 // 00337 00338 PCR->ReservedVectors = (1 << PASSIVE_LEVEL) | (1 << APC_LEVEL) | (1 << DISPATCH_LEVEL); 00339 00340 // 00341 // Initialize the set member for the current processor, set IRQL to 00342 // APC_LEVEL, and set the processor number. 00343 // 00344 00345 KeLowerIrql(APC_LEVEL); 00346 PCR->SetMember = 1 << Number; 00347 PCR->NotMember = ~PCR->SetMember; 00348 PCR->Number = Number; 00349 00350 // 00351 // Set the initial stall execution scale factor. This value will be 00352 // recomputed later by the HAL. 00353 // 00354 00355 PCR->StallScaleFactor = 50; 00356 00357 // 00358 // Set address of process object in thread object. 00359 // 00360 00361 Thread->ApcState.Process = Process; 00362 00363 00364 // 00365 // Set idle process id (region id) to STARTID 00366 // 00367 00368 Process->ProcessRegion.RegionId = START_PROCESS_RID; 00369 Process->ProcessRegion.SequenceNumber = START_SEQUENCE; 00370 Process->SessionRegion.RegionId = START_SESSION_RID; 00371 Process->SessionRegion.RegionId = START_SEQUENCE; 00372 00373 // 00374 // Set the appropriate member in the active processors set. 00375 // 00376 00377 SetMember(Number, KeActiveProcessors); 00378 00379 // 00380 // Set the number of processors based on the maximum of the current 00381 // number of processors and the current processor number. 00382 // 00383 00384 if ((Number + 1) > KeNumberProcessors) { 00385 KeNumberProcessors = (CCHAR)(Number + 1); 00386 } 00387 00388 // 00389 // If the initial processor is being initialized, then initialize the 00390 // per system data structures. 00391 // 00392 00393 if (Number == 0) { 00394 00395 Prcb->RestartBlock = NULL; 00396 00397 // 00398 // Initialize the kernel debugger. 00399 // 00400 00401 if (KdInitSystem(LoaderBlock, FALSE) == FALSE) { 00402 KeBugCheck(PHASE0_INITIALIZATION_FAILED); 00403 } 00404 00405 #if DBG 00406 00407 // 00408 // Allow a breakin to the kernel debugger if one is pending. 00409 // 00410 00411 if (KdPollBreakIn() != FALSE){ 00412 DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); 00413 } 00414 00415 #endif //DBG 00416 00417 // 00418 // Initialize processor block array. 00419 // 00420 00421 for (Index = 1; Index < MAXIMUM_PROCESSORS; Index += 1) { 00422 KiProcessorBlock[Index] = (PKPRCB)NULL; 00423 } 00424 00425 // 00426 // Perform architecture independent initialization. 00427 // 00428 00429 KiInitSystem(); 00430 00431 // 00432 // Initialize idle thread process object and then set: 00433 // 00434 // 1. all the quantum values to the maximum possible. 00435 // 2. the process in the balance set. 00436 // 3. the active processor mask to the specified processor. 00437 // 00438 00439 DirectoryTableBase[0] = 0; 00440 DirectoryTableBase[1] = 0; 00441 00442 KeInitializeProcess(Process, 00443 (KPRIORITY)0, 00444 (KAFFINITY)(0x7f), 00445 &DirectoryTableBase[0], 00446 FALSE); 00447 00448 Process->ThreadQuantum = MAXCHAR; 00449 00450 } 00451 00452 // 00453 // Initialize idle thread object and then set: 00454 // 00455 // 1. the initial kernel stack to the specified idle stack. 00456 // 2. the next processor number to the specified processor. 00457 // 3. the thread priority to the highest possible value. 00458 // 4. the state of the thread to running. 00459 // 5. the thread affinity to the specified processor. 00460 // 6. the specified processor member in the process active processors 00461 // set. 00462 // 00463 00464 KeInitializeThread(Thread, (PVOID)((ULONG_PTR)IdleStack - PAGE_SIZE), 00465 (PKSYSTEM_ROUTINE)KeBugCheck, 00466 (PKSTART_ROUTINE)NULL, 00467 (PVOID)NULL, (PCONTEXT)NULL, (PVOID)NULL, Process); 00468 00469 Thread->InitialStack = IdleStack; 00470 Thread->InitialBStore = IdleStack; 00471 Thread->StackBase = IdleStack; 00472 Thread->StackLimit = (PVOID)((ULONG_PTR)IdleStack - KERNEL_STACK_SIZE); 00473 Thread->BStoreLimit = (PVOID)((ULONG_PTR)IdleStack + KERNEL_BSTORE_SIZE); 00474 Thread->NextProcessor = Number; 00475 Thread->Priority = HIGH_PRIORITY; 00476 Thread->State = Running; 00477 Thread->Affinity = (KAFFINITY)(1 << Number); 00478 Thread->WaitIrql = DISPATCH_LEVEL; 00479 00480 // 00481 // If the current processor is 0, then set the appropriate bit in the 00482 // active summary of the idle process. 00483 // 00484 00485 if (Number == 0) { 00486 SetMember(Number, Process->ActiveProcessors); 00487 } 00488 00489 // 00490 // Execute the executive initialization. 00491 // 00492 00493 try { 00494 ExpInitializeExecutive(Number, LoaderBlock); 00495 00496 } except (EXCEPTION_EXECUTE_HANDLER) { 00497 KeBugCheck (PHASE0_EXCEPTION); 00498 } 00499 00500 #if 0 00501 if (Number == 0) { 00502 RUNTIME_FUNCTION LocalEntry; 00503 PRUNTIME_FUNCTION FunctionTable, FunctionEntry = NULL; 00504 ULONGLONG ControlPc; 00505 ULONG SizeOfExceptionTable; 00506 ULONG Size; 00507 LONG High; 00508 LONG Middle; 00509 LONG Low; 00510 extern VOID KiNormalSystemCall(VOID); 00511 00512 FunctionTable = (PRUNTIME_FUNCTION)RtlImageDirectoryEntryToData( 00513 (PVOID) PsNtosImageBase, 00514 TRUE, 00515 IMAGE_DIRECTORY_ENTRY_EXCEPTION, 00516 &SizeOfExceptionTable); 00517 00518 if (FunctionTable != NULL) { 00519 00520 Low = 0; 00521 High = (SizeOfExceptionTable / sizeof(RUNTIME_FUNCTION)) - 1; 00522 ControlPc = ((PPLABEL_DESCRIPTOR)KiNormalSystemCall)->EntryPoint - (ULONG_PTR)PsNtosImageBase; 00523 00524 while (High >= Low) { 00525 00526 Middle = (Low + High) >> 1; 00527 FunctionEntry = &FunctionTable[Middle]; 00528 00529 if (ControlPc < FunctionEntry->BeginAddress) { 00530 High = Middle - 1; 00531 } else if (ControlPc >= FunctionEntry->EndAddress) { 00532 Low = Middle + 1; 00533 } else { 00534 break; 00535 } 00536 } 00537 } 00538 00539 LocalEntry = *FunctionEntry; 00540 ControlPc = MM_EPC_VA - ((PPLABEL_DESCRIPTOR)KiNormalSystemCall)->EntryPoint; 00541 LocalEntry.BeginAddress += (ULONG)ControlPc; 00542 LocalEntry.EndAddress += (ULONG)ControlPc; 00543 Size = SizeOfExceptionTable - (ULONG)((ULONG_PTR)FunctionEntry - (ULONG_PTR)FunctionTable) - sizeof(RUNTIME_FUNCTION); 00544 00545 RtlMoveMemory((PVOID)FunctionEntry, (PVOID)(FunctionEntry+1), Size); 00546 FunctionEntry = (PRUNTIME_FUNCTION)((ULONG_PTR)FunctionTable + SizeOfExceptionTable - sizeof(RUNTIME_FUNCTION)); 00547 *FunctionEntry = LocalEntry; 00548 } 00549 #endif // 0 00550 00551 // 00552 // If the initial processor is being initialized, then compute the 00553 // timer table reciprocal value and reset the PRCB values for the 00554 // controllable DPC behavior in order to reflect any registry 00555 // overrides. 00556 // 00557 00558 if (Number == 0) { 00559 KiTimeIncrementReciprocal = KiComputeReciprocal((LONG)KeMaximumIncrement, 00560 &KiTimeIncrementShiftCount); 00561 00562 Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth; 00563 Prcb->MinimumDpcRate = KiMinimumDpcRate; 00564 Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold; 00565 } 00566 00567 // 00568 // Raise IRQL to dispatch level and set the priority of the idle thread 00569 // to zero. This will have the effect of immediately causing the phase 00570 // one initialization thread to get scheduled for execution. The idle 00571 // thread priority is then set to the lowest realtime priority. This is 00572 // necessary so that mutexes aquired at DPC level do not cause the active 00573 // matrix to get corrupted. 00574 // 00575 00576 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); 00577 KeSetPriorityThread(Thread, (KPRIORITY)0); 00578 Thread->Priority = LOW_REALTIME_PRIORITY; 00579 00580 // 00581 // Raise IRQL to the highest level. 00582 // 00583 00584 KeRaiseIrql(HIGH_LEVEL, &OldIrql); 00585 00586 #if !defined(NT_UP) 00587 00588 // 00589 // Indicate boot complete on secondary processor 00590 // 00591 00592 LoaderBlock->Prcb = 0; 00593 00594 // 00595 // If the current processor is not 0, then set the appropriate bit in 00596 // idle summary. 00597 // 00598 00599 if (Number != 0) { 00600 SetMember(Number, KiIdleSummary); 00601 } 00602 00603 #endif 00604 00605 return; 00606 } }


Variable Documentation

KSPIN_LOCK KiCacheFlushLock
 

Definition at line 60 of file ia64/initkr.c.

Referenced by KeSweepDcache(), KeSweepIcache(), and KiInitializeKernel().

ULONG_PTR KiKernelPcrPage = 0i64
 

Definition at line 74 of file ia64/initkr.c.

Referenced by KeStartAllProcessors().

KSPIN_LOCK KiMasterRidLock
 

Definition at line 53 of file ia64/initkr.c.

Referenced by KeDetachSessionSpace(), KiInitializeKernel(), KiSyncNewRegionId(), KiSyncNewRegionIdTarget(), and KiSyncSessionTarget().

KSPIN_LOCK KiTbBroadcastLock
 

Definition at line 46 of file ia64/initkr.c.

Referenced by KeFlushMultipleTb(), KeFlushSingleTb(), and KiInitializeKernel().

ULONG_PTR KiUserSharedDataPage
 

Definition at line 67 of file ia64/initkr.c.

Referenced by KeStartAllProcessors(), and KiInitializeKernel().


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