test: allproc.c Source File

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

# allproc.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1990  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     allproc.c
    00008
    00009 Abstract:
    00010
    00011     This module allocates and intializes kernel resources required
    00012     to start a new processor, and passes a complete processor state
    00013     structure to the HAL to obtain a new processor.
    00014
    00015 Author:
    00016
    00017     Bernard Lint 31-Jul-96
    00018
    00019 Environment:
    00020
    00021     Kernel mode only.
    00022
    00023 Revision History:
    00024
    00025     Based on MIPS original (David N. Cutler 29-Apr-1993)
    00026
    00027 --*/
    00028
    00029
    00030 #include "ki.h"
    00031
    00032 #ifdef ALLOC_PRAGMA
    00033
    00034 #pragma alloc_text(INIT, KeStartAllProcessors)
    00035
    00036 #endif
    00037
    00038 //
    00039 // Define macro to round up to 64-byte boundary and define block sizes.
    00040 //
    00041
    00042 #define ROUND_UP(x) ((sizeof(x) + 63) & (~63))
    00043 #define BLOCK1_SIZE (2 * (KERNEL_BSTORE_SIZE + KERNEL_STACK_SIZE) + PAGE_SIZE)
    00044 #define BLOCK2_SIZE (ROUND_UP(KPRCB) + ROUND_UP(ETHREAD) + 64)
    00045
    00046 #if !defined(NT_UP)
    00047
    00048 //
    00049 // Define barrier wait static data.
    00050 //
    00051
    00052 ULONG KiBarrierWait = 0;
    00053
    00054 #endif
    00055
    00056 extern ULONG_PTR KiUserSharedDataPage;
    00057 extern ULONG_PTR KiKernelPcrPage;
    00058
    00059 //
    00060 // Define forward referenced prototypes.
    00061 //
    00062
    00063 VOID
    00064 KiCalibratePerformanceCounter(
    00065     VOID
    00066     );
    00067
    00068 VOID
    00069 KiCalibratePerformanceCounterTarget (
    00070     IN PULONG SignalDone,
    00071     IN PVOID Count,
    00072     IN PVOID Parameter2,
    00073     IN PVOID Parameter3
    00074     );
    00075
    00076 VOID
    00077 KiOSRendezvous (
    00078     VOID
    00079     );
    00080
    00081 VOID
    00082 KeStartAllProcessors(
    00083     VOID
    00084     )
    00085
    00086 /*++
    00087
    00088 Routine Description:
    00089
    00090     This function is called during phase 1 initialize on the master boot
    00091     processor to start all of the other registered processors.
    00092
    00093 Arguments:
    00094
    00095     None.
    00096
    00097 Return Value:
    00098
    00099     None.
    00100
    00101 --*/
    00102
    00103 {
    00104
    00105     ULONG_PTR MemoryBlock1;
    00106     ULONG_PTR MemoryBlock2;
    00107     ULONG_PTR MemoryBlock3;
    00108     ULONG_PTR PcrAddress;
    00109     ULONG Number;
    00110     PHYSICAL_ADDRESS PcrPage;
    00111     PKPRCB Prcb;
    00112     BOOLEAN Started;
    00113     KPROCESSOR_STATE ProcessorState;
    00114
    00115 #if !defined(NT_UP)
    00116
    00117     //
    00118     // If the registered number of processors is greater than the maximum
    00119     // number of processors supported, then only allow the maximum number
    00120     // of supported processors.
    00121     //
    00122
    00123     if (KeRegisteredProcessors > MAXIMUM_PROCESSORS) {
    00124         KeRegisteredProcessors = MAXIMUM_PROCESSORS;
    00125     }
    00126
    00127     //
    00128     // Set barrier that will prevent any other processor from entering the
    00129     // idle loop until all processors have been started.
    00130     //
    00131
    00132     KiBarrierWait = 1;
    00133
    00134     //
    00135     // Initialize the processor state that will be used to start each of
    00136     // processors. Each processor starts in the system initialization code
    00137     // with address of the loader parameter block as an argument.
    00138     //
    00139
    00140     Number = 1;
    00141     RtlZeroMemory(&ProcessorState, sizeof(KPROCESSOR_STATE));
    00142     ProcessorState.ContextFrame.StIIP = ((PPLABEL_DESCRIPTOR)KiOSRendezvous)->EntryPoint;
    00143     while (Number < KeRegisteredProcessors) {
    00144
    00145         // **** TBD check this for MP case
    00146
    00147         //
    00148         // Allocate a DPC stack, an idle thread kernel stack, a panic
    00149         // stack, a PCR page, a processor block, and an executive thread
    00150         // object. If the allocation fails or the allocation cannot be
    00151         // made from unmapped nonpaged pool, then stop starting processors.
    00152         //
    00153
    00154         MemoryBlock1 = (ULONG_PTR)ExAllocatePool(NonPagedPool, BLOCK1_SIZE);
    00155         if ((PVOID)MemoryBlock1 == NULL) {
    00156             break;
    00157         }
    00158
    00159         MemoryBlock2 = (ULONG_PTR)ExAllocatePool(NonPagedPool, BLOCK2_SIZE);
    00160         if ((PVOID)MemoryBlock2 == NULL) {
    00161             ExFreePool((PVOID)MemoryBlock1);
    00162             break;
    00163         }
    00164
    00165         //
    00166         // Zero both blocks of allocated memory.
    00167         //
    00168
    00169         RtlZeroMemory((PVOID)MemoryBlock1, BLOCK1_SIZE);
    00170         RtlZeroMemory((PVOID)MemoryBlock2, BLOCK2_SIZE);
    00171
    00172         //
    00173         // Set address of idle thread kernel stack in loader parameter block.
    00174         //
    00175
    00176         KeLoaderBlock->KernelStack = MemoryBlock1 + KERNEL_STACK_SIZE;
    00177
    00178         //
    00179         // Set address of panic stack in loader parameter block.
    00180         //
    00181
    00182         KeLoaderBlock->u.Ia64.PanicStack = MemoryBlock1 + KERNEL_BSTORE_SIZE +
    00183                                                (2 * KERNEL_STACK_SIZE);
    00184
    00185         //
    00186         // Set the address of the processor block and executive thread in the
    00187         // loader parameter block.
    00188         //
    00189
    00190         KeLoaderBlock->Prcb = MemoryBlock2;
    00191         KeLoaderBlock->Thread = KeLoaderBlock->Prcb + ROUND_UP(KPRCB);
    00192         ((PKPRCB)KeLoaderBlock->Prcb)->Number = (UCHAR)Number;
    00193
    00194         //
    00195         // Set the page frame of the PCR page in the loader parameter block.
    00196         //
    00197
    00198         PcrAddress = MemoryBlock1 + KERNEL_BSTORE_SIZE + (2*KERNEL_STACK_SIZE);
    00199         PcrPage = MmGetPhysicalAddress((PVOID)PcrAddress);
    00200         KeLoaderBlock->u.Ia64.PcrPage = PcrPage.QuadPart >> PAGE_SHIFT;
    00201         KeLoaderBlock->u.Ia64.PcrPage2 = KiUserSharedDataPage;
    00202         KiKernelPcrPage = KeLoaderBlock->u.Ia64.PcrPage;
    00203
    00204         //
    00205         // Attempt to start the next processor. If attempt is successful,
    00206         // then wait for the processor to get initialized. Otherwise,
    00207         // deallocate the processor resources and terminate the loop.
    00208         //
    00209
    00210         Started = HalStartNextProcessor(KeLoaderBlock, &ProcessorState);
    00211
    00212         if (Started) {
    00213
    00214             //
    00215             //  Wait for processor to initialize in kernel,
    00216             //  then loop for another
    00217             //
    00218
    00219             while (*((volatile ULONG_PTR *) &KeLoaderBlock->Prcb) != 0) {
    00220                 KeYieldProcessor();
    00221             }
    00222
    00223         } else {
    00224
    00225             ExFreePool((PVOID)MemoryBlock1);
    00226             ExFreePool((PVOID)MemoryBlock2);
    00227             break;
    00228
    00229         }
    00230
    00231         Number += 1;
    00232     }
    00233
    00234     //
    00235     // Allow all processor that were started to enter the idle loop and
    00236     // begin execution.
    00237     //
    00238
    00239     KiBarrierWait = 0;
    00240
    00241 #endif
    00242
    00243     //
    00244     // Reset and synchronize the performance counters of all processors.
    00245     //
    00246
    00247     KiAdjustInterruptTime (0);
    00248     return;
    00249 }