test: ia64/initkr.c File Reference

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().