test: alpha/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

ULONG | KiGetFeatureBits (VOID)
__inline ULONG | amask (IN ULONG Feature)
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 | CcMasterSpinLock
KSPIN_LOCK | CcVacbSpinLock
KSPIN_LOCK | MmPfnLock
KSPIN_LOCK | MmSystemSpaceLock

## Function Documentation

__inline ULONG amask | ( | IN ULONG | Feature | ) |

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

Referenced by KiGetFeatureBits().

    00057 {
    00058     return(__asm("amask %0, v0",Feature));
    00059 }

ULONG KiGetFeatureBits | ( | VOID |  | ) |

Definition at line 573 of file alpha/initkr.c.

References amask().

    00583 {
    00584
    00585     ULONG Features = 0;
    00586
    00587     //
    00588     // Check for byte instructions.
    00589     //
    00590
    00591     if (amask(1) == 0) {
    00592         Features |= KF_BYTE;
    00593     }
    00594
    00595     return Features;
    00596 }

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 65 of file alpha/initkr.c.

    00076                    :
    00077
    00078     This function gains control after the system has been bootstrapped and
    00079     before the system has been initialized. Its function is to initialize
    00080     the kernel data structures, initialize the idle thread and process objects,
    00081     initialize the processor control block, call the executive initialization
    00082     routine, and then return to the system startup routine. This routine is
    00083     also called to initialize the processor specific structures when a new
    00084     processor is brought on line.
    00085
    00086 Arguments:
    00087
    00088     Process - Supplies a pointer to a control object of type process for
    00089         the specified processor.
    00090
    00091     Thread - Supplies a pointer to a dispatcher object of type thread for
    00092         the specified processor.
    00093
    00094     IdleStack - Supplies a pointer the base of the real kernel stack for
    00095         idle thread on the specified processor.
    00096
    00097     Prcb - Supplies a pointer to a processor control block for the specified
    00098         processor.
    00099
    00100     Number - Supplies the number of the processor that is being
    00101         initialized.
    00102
    00103     LoaderBlock - Supplies a pointer to the loader parameter block.
    00104
    00105 Return Value:
    00106
    00107     None.
    00108
    00109 --*/
    00110
    00111 {
    00112
    00113     UCHAR DataByte;
    00114     ULONG DataLong;
    00115     LONG Index;
    00116     KIRQL OldIrql;
    00117     PKPCR Pcr = PCR;
    00118     struct _RESTART_BLOCK *RestartBlock;
    00119
    00120     //
    00121     // Save the address of the loader parameter block.
    00122     //
    00123
    00124     KeLoaderBlock = LoaderBlock;
    00125
    00126     //
    00127     // Set the appropriate member in the active processors set.
    00128     //
    00129
    00130     SetMember(Number, KeActiveProcessors);
    00131
    00132     //
    00133     // Set the number of processors based on the maximum of the current
    00134     // number of processors and the current processor number.
    00135     //
    00136
    00137     if ((Number + 1) > KeNumberProcessors) {
    00138         KeNumberProcessors = Number + 1;
    00139     }
    00140
    00141     //
    00142     // Set the maximum address space number to the minimum of all maximum
    00143     // address space numbers passed via the loader block.
    00144     //
    00145
    00146     if (Number == 0) {
    00147         KiMaximumAsn = LoaderBlock->u.Alpha.MaximumAddressSpaceNumber;
    00148
    00149     } else if (KiMaximumAsn > LoaderBlock->u.Alpha.MaximumAddressSpaceNumber) {
    00150         KiMaximumAsn = LoaderBlock->u.Alpha.MaximumAddressSpaceNumber;
    00151     }
    00152
    00153     //
    00154     // Initialize the passive release, APC, and DPC interrupt vectors.
    00155     //
    00156
    00157     Pcr->InterruptRoutine[0] = KiPassiveRelease;
    00158     Pcr->InterruptRoutine[APC_LEVEL] = KiApcInterrupt;
    00159     Pcr->InterruptRoutine[DISPATCH_LEVEL] = KiDispatchInterrupt;
    00160     Pcr->ReservedVectors =
    00161         (1 << PASSIVE_LEVEL) | (1 << APC_LEVEL) | (1 << DISPATCH_LEVEL);
    00162
    00163     //
    00164     // Initialize the processor id fields in the PCR.
    00165     //
    00166
    00167     Pcr->Number = Number;
    00168     Pcr->SetMember = 1 << Number;
    00169     Pcr->NotMember = ~Pcr->SetMember;
    00170
    00171     //
    00172     // Initialize the processor block.
    00173     //
    00174
    00175     Prcb->MinorVersion = PRCB_MINOR_VERSION;
    00176     Prcb->MajorVersion = PRCB_MAJOR_VERSION;
    00177     Prcb->BuildType = 0;
    00178
    00179 #if DBG
    00180
    00181     Prcb->BuildType |= PRCB_BUILD_DEBUG;
    00182
    00183 #endif
    00184
    00185 #ifdef NT_UP
    00186
    00187     Prcb->BuildType |= PRCB_BUILD_UNIPROCESSOR;
    00188
    00189 #endif
    00190
    00191     Prcb->CurrentThread = Thread;
    00192     Prcb->NextThread = (PKTHREAD)NULL;
    00193     Prcb->IdleThread = Thread;
    00194     Prcb->Number = Number;
    00195     Prcb->SetMember = 1 << Number;
    00196
    00197     KeInitializeDpc(&Prcb->QuantumEndDpc,
    00198                     (PKDEFERRED_ROUTINE)KiQuantumEnd,
    00199                     NIL);
    00200
    00201     //
    00202     // initialize the per processor lock queue entry for implemented locks.
    00203     //
    00204
    00205 #if !defined(NT_UP)
    00206
    00207     Prcb->LockQueue[LockQueueDispatcherLock].Next = NULL;
    00208     Prcb->LockQueue[LockQueueDispatcherLock].Lock = &KiDispatcherLock;
    00209     Prcb->LockQueue[LockQueueContextSwapLock].Next = NULL;
    00210     Prcb->LockQueue[LockQueueContextSwapLock].Lock = &KiContextSwapLock;
    00211     Prcb->LockQueue[LockQueuePfnLock].Next = NULL;
    00212     Prcb->LockQueue[LockQueuePfnLock].Lock = &MmPfnLock;
    00213     Prcb->LockQueue[LockQueueSystemSpaceLock].Next = NULL;
    00214     Prcb->LockQueue[LockQueueSystemSpaceLock].Lock = &MmSystemSpaceLock;
    00215     Prcb->LockQueue[LockQueueMasterLock].Next = NULL;
    00216     Prcb->LockQueue[LockQueueMasterLock].Lock = &CcMasterSpinLock;
    00217     Prcb->LockQueue[LockQueueVacbLock].Next = NULL;
    00218     Prcb->LockQueue[LockQueueVacbLock].Lock = &CcVacbSpinLock;
    00219
    00220 #endif
    00221
    00222     //
    00223     // Set address of PCR in PRCB.
    00224     //
    00225
    00226     Prcb->Pcr = Pcr;
    00227
    00228     //
    00229     // Initialize the interprocessor communication packet.
    00230     //
    00231
    00232 #if !defined(NT_UP)
    00233
    00234     Prcb->TargetSet = 0;
    00235     Prcb->WorkerRoutine = NULL;
    00236     Prcb->RequestSummary = 0;
    00237     Prcb->IpiFrozen = 0;
    00238
    00239 #if NT_INST
    00240
    00241     Prcb->IpiCounts = &KiIpiCounts[Number];
    00242
    00243 #endif //NT_INST
    00244
    00245 #endif //NT_UP
    00246
    00247     Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
    00248     Prcb->MinimumDpcRate = KiMinimumDpcRate;
    00249     Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
    00250
    00251     //
    00252     // Initialize DPC listhead and lock.
    00253     //
    00254
    00255     InitializeListHead(&Prcb->DpcListHead);
    00256     KeInitializeSpinLock(&Prcb->DpcLock);
    00257
    00258     //
    00259     // Set address of processor block.
    00260     //
    00261
    00262     KiProcessorBlock[Number] = Prcb;
    00263
    00264     //
    00265     // Set address of process object in thread object.
    00266     //
    00267
    00268     Thread->ApcState.Process = Process;
    00269
    00270     //
    00271     // Set the appropriate member in the active processors set.
    00272     //
    00273
    00274     SetMember( Number, KeActiveProcessors );
    00275
    00276     //
    00277     // Set the number of processors based on the maximum of the current
    00278     // number of processors and the current processor number.
    00279     //
    00280
    00281     if( (Number+1) > KeNumberProcessors ){
    00282         KeNumberProcessors = Number + 1;
    00283     }
    00284
    00285     //
    00286     // Initialize processors PowerState
    00287     //
    00288
    00289     PoInitializePrcb (Prcb);
    00290
    00291     //
    00292     // Set global processor architecture, level and revision.  The
    00293     // latter two are the least common denominator on an MP system.
    00294     //
    00295
    00296 #ifdef _AXP64_
    00297     KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_ALPHA64;
    00298 #else
    00299     KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_ALPHA;
    00300 #endif
    00301
    00302     if ((KeProcessorLevel == 0) ||
    00303         (KeProcessorLevel > (USHORT)Pcr->ProcessorType)) {
    00304         KeProcessorLevel = (USHORT)Pcr->ProcessorType;
    00305     }
    00306
    00307     if ((KeProcessorRevision == 0) ||
    00308         (KeProcessorRevision > (USHORT)Pcr->ProcessorRevision)) {
    00309         KeProcessorRevision = (USHORT)Pcr->ProcessorRevision;
    00310     }
    00311
    00312     //
    00313     // Initialize all interrupt vectors to transfer control to the unexpected
    00314     // interrupt routine.
    00315     //
    00316     // N.B. This interrupt object is never actually "connected" to an interrupt
    00317     //      vector via KeConnectInterrupt. It is initialized and then connected
    00318     //      by simply storing the address of the dispatch code in the interrupt
    00319     //      vector.
    00320     //
    00321
    00322     if (Number == 0) {
    00323
    00324         KeFeatureBits = KiGetFeatureBits();
    00325
    00326         //
    00327         // Initial the address of the interrupt dispatch routine.
    00328         //
    00329
    00330         KxUnexpectedInterrupt.DispatchAddress = KiUnexpectedInterrupt;
    00331
    00332         //
    00333         // Initialize the context swap spinlock.
    00334         //
    00335
    00336         KeInitializeSpinLock(&KiContextSwapLock);
    00337
    00338         //
    00339         // Copy the interrupt dispatch code template into the interrupt object
    00340         // and flush the dcache on all processors that the current thread can
    00341         // run on to ensure that the code is actually in memory.
    00342         //
    00343
    00344         for (Index = 0; Index < DISPATCH_LENGTH; Index += 1) {
    00345             KxUnexpectedInterrupt.DispatchCode[Index] = KiInterruptTemplate[Index];
    00346         }
    00347
    00348         //
    00349         // Sweep the instruction cache on the current processor.
    00350         //
    00351
    00352         KiImb();
    00353
    00354     } else {
    00355
    00356         //
    00357         // Mask off feature bits that are not supported on all processors.
    00358         //
    00359
    00360         KeFeatureBits &= KiGetFeatureBits();
    00361     }
    00362
    00363     //
    00364     // Update processor features
    00365     //
    00366
    00367     SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] =
    00368         (KeFeatureBits & KF_BYTE) ? TRUE : FALSE;
    00369
    00370     for (Index = DISPATCH_LEVEL+1; Index < MAXIMUM_VECTOR; Index += 1) {
    00371         Pcr->InterruptRoutine[Index] =  (PKINTERRUPT_ROUTINE)(&KxUnexpectedInterrupt.DispatchCode);
    00372     }
    00373
    00374     //
    00375     // Raise IRQL to APC level.
    00376     //
    00377
    00378     KeRaiseIrql(APC_LEVEL, &OldIrql);
    00379
    00380     //
    00381     // If the initial processor is being initialized, then initialize the
    00382     // per system data structures.
    00383     //
    00384
    00385     if (Number == 0) {
    00386
    00387         //
    00388         // Initialize the address of the restart block for the boot master.
    00389         //
    00390
    00391         Prcb->RestartBlock = SYSTEM_BLOCK->RestartBlock;
    00392
    00393         //
    00394         // Initialize the kernel debugger if enabled by the load options.
    00395         //
    00396
    00397         if (KdInitSystem(LoaderBlock, FALSE) == FALSE) {
    00398             KeBugCheck(PHASE0_INITIALIZATION_FAILED);
    00399         }
    00400
    00401 #if DBG
    00402
    00403         //
    00404         // Allow a breakin to the kernel debugger if one is pending.
    00405         //
    00406
    00407         if (KdPollBreakIn() != FALSE){
    00408             DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
    00409         }
    00410
    00411 #endif //DBG
    00412
    00413         //
    00414         // Initialize processor block array.
    00415         //
    00416
    00417         for (Index = 1; Index < MAXIMUM_PROCESSORS; Index += 1) {
    00418             KiProcessorBlock[Index] = (PKPRCB)NULL;
    00419         }
    00420
    00421         //
    00422         // Initialize default DMA coherency value for Alpha.
    00423         //
    00424
    00425         KiDmaIoCoherency = DMA_READ_DCACHE_INVALIDATE | DMA_WRITE_DCACHE_SNOOP;
    00426
    00427         //
    00428         // Perform architecture independent initialization.
    00429         //
    00430
    00431         KiInitSystem();
    00432
    00433         //
    00434         // Initialize idle thread process object and then set:
    00435         //
    00436         //      1. all the quantum values to the maximum possible.
    00437         //      2. the process in the balance set.
    00438         //      3. the active processor mask to the specified processor.
    00439         //
    00440
    00441         KeInitializeProcess(Process,
    00442                             (KPRIORITY)0,
    00443                             (KAFFINITY)(0xffffffff),
    00444                             (PULONG_PTR)PDE_SELFMAP,
    00445                             FALSE);
    00446
    00447         Process->ThreadQuantum = MAXCHAR;
    00448     }
    00449
    00450     //
    00451     // Initialize idle thread object and then set:
    00452     //
    00453     //      1. the initial kernel stack to the specified idle stack.
    00454     //      2. the next processor number to the specified processor.
    00455     //      3. the thread priority to the highest possible value.
    00456     //      4. the state of the thread to running.
    00457     //      5. the thread affinity to the specified processor.
    00458     //      6. the specified processor member in the process active processors
    00459     //          set.
    00460     //
    00461
    00462     KeInitializeThread(Thread,
    00463                        (PVOID)((ULONG_PTR)IdleStack - PAGE_SIZE),
    00464                        (PKSYSTEM_ROUTINE)NULL,
    00465                        (PKSTART_ROUTINE)NULL,
    00466                        (PVOID)NULL,
    00467                        (PCONTEXT)NULL,
    00468                        (PVOID)NULL,
    00469                        Process);
    00470
    00471     Thread->InitialStack = IdleStack;
    00472     Thread->StackBase = IdleStack;
    00473     Thread->StackLimit = (PVOID)((ULONG_PTR)IdleStack - KERNEL_STACK_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 the boot master then set the appropriate
    00482     // bit in the active summary of the idle process.
    00483     //
    00484
    00485     if (Number == 0) {
    00486         SetMember(Number, Process->ActiveProcessors);
    00487     }
    00488
    00489     //
    00490     // call the executive initialization routine.
    00491     //
    00492
    00493     try {
    00494         ExpInitializeExecutive(Number, LoaderBlock);
    00495
    00496     } except(KeBugCheckEx(PHASE0_EXCEPTION,
    00497                           (ULONG)GetExceptionCode(),
    00498                           (ULONG_PTR)GetExceptionInformation(),
    00499                           0,0), EXCEPTION_EXECUTE_HANDLER) {
    00500         ; // should never get here
    00501     }
    00502
    00503     //
    00504     // If the initial processor is being initialized, then compute the
    00505     // timer table reciprocal value and reset the PRCB values for
    00506     // the controllable DPC behavior in order to reflect any registry
    00507     // overrides.
    00508     //
    00509
    00510     if (Number == 0) {
    00511         KiTimeIncrementReciprocal = KiComputeReciprocal((LONG)KeMaximumIncrement,
    00512                                                         &KiTimeIncrementShiftCount);
    00513
    00514         Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
    00515         Prcb->MinimumDpcRate = KiMinimumDpcRate;
    00516         Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
    00517     }
    00518
    00519     //
    00520     // Try to enable automatic PAL code fixups on this processor.
    00521     // This must be done after the configuration values are read
    00522     // out of the registry in ExpInitializeExecutive.
    00523     //
    00524
    00525     KiDisableAlignmentExceptions();
    00526
    00527     //
    00528     //
    00529     // Raise IRQL to dispatch level and set the priority of the idle thread
    00530     // to zero. This will have the effect of immediately causing the phase
    00531     // one initialization thread to get scheduled for execution. The idle
    00532     // thread priority is then set to the lowest realtime priority.
    00533     //
    00534
    00535     KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
    00536     KeSetPriorityThread(Thread, (KPRIORITY)0);
    00537     Thread->Priority = LOW_REALTIME_PRIORITY;
    00538
    00539     //
    00540     // Raise IRQL to the highest level.
    00541     //
    00542
    00543     KeRaiseIrql(HIGH_LEVEL, &OldIrql);
    00544
    00545     //
    00546     // If a restart block exists for the current processor then set boot
    00547     // completed.
    00548     //
    00549
    00550 #if !defined(NT_UP)
    00551
    00552     RestartBlock = Prcb->RestartBlock;
    00553     if (RestartBlock != NULL) {
    00554         RestartBlock->BootStatus.BootFinished = 1;
    00555     }
    00556
    00557     //
    00558     // If the current processor is a secondary processor and a thread has
    00559     // not been selected for execution, then set the appropriate bit in the
    00560     // idle summary.
    00561     //
    00562
    00563     if ((Number != 0) && (Prcb->NextThread == NULL)) {
    00564         SetMember(Number, KiIdleSummary);
    00565     }
    00566
    00567 #endif //NT_UP
    00568
    00569     return;
    00570 }

## Variable Documentation

KSPIN_LOCK CcMasterSpinLock

| Definition at line 37 of file alpha/initkr.c.

KSPIN_LOCK CcVacbSpinLock

| Definition at line 38 of file alpha/initkr.c.

KSPIN_LOCK MmPfnLock

| Definition at line 39 of file alpha/initkr.c. Referenced by ExAllocatePool(), ExFreePool(), KiInitializeKernel(), and MiInitMachineDependent().

KSPIN_LOCK MmSystemSpaceLock

| Definition at line 40 of file alpha/initkr.c.