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 Copyright (c) 1993 Digital Equipment Corporation 00005 00006 Module Name: 00007 00008 allproc.c 00009 00010 Abstract: 00011 00012 This module allocates and initializes kernel resources required 00013 to start a new processor, and passes a complete processor state 00014 structure to the HAL to obtain a new processor. 00015 00016 Author: 00017 00018 David N. Cutler 29-Apr-1993 00019 Joe Notarangelo 30-Nov-1993 00020 00021 Environment: 00022 00023 Kernel mode only. 00024 00025 Revision History: 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) + 64) & (~64)) 00043 #define BLOCK1_SIZE ((3 * KERNEL_STACK_SIZE) + PAGE_SIZE) 00044 #define BLOCK2_SIZE (ROUND_UP(KPRCB) + ROUND_UP(ETHREAD) + 64) 00045 00046 // 00047 // Macros to compute whether an address is physically addressable. 00048 // 00049 00050 #if defined(_AXP64_) 00051 00052 #define IS_KSEG_ADDRESS(v) \ 00053 (((v) >= KSEG43_BASE) && \ 00054 ((v) < KSEG43_LIMIT) && \ 00055 (KSEG_PFN(v) < ((KSEG2_BASE - KSEG0_BASE) >> PAGE_SHIFT))) 00056 00057 #define KSEG_PFN(v) ((ULONG)(((v) - KSEG43_BASE) >> PAGE_SHIFT)) 00058 #define KSEG0_ADDRESS(v) (KSEG0_BASE | ((v) - KSEG43_BASE)) 00059 00060 #else 00061 00062 #define IS_KSEG_ADDRESS(v) (((v) >= KSEG0_BASE) && ((v) < KSEG2_BASE)) 00063 #define KSEG_PFN(v) ((ULONG)(((v) - KSEG0_BASE) >> PAGE_SHIFT)) 00064 #define KSEG0_ADDRESS(v) (v) 00065 00066 #endif 00067 00068 // 00069 // Define forward referenced prototypes. 00070 // 00071 00072 VOID 00073 KiStartProcessor ( 00074 IN PLOADER_PARAMETER_BLOCK Loaderblock 00075 ); 00076 00077 VOID 00078 KeStartAllProcessors( 00079 VOID 00080 ) 00081 00082 /*++ 00083 00084 Routine Description: 00085 00086 This function is called during phase 1 initialization on the master boot 00087 processor to start all of the other registered processors. 00088 00089 Arguments: 00090 00091 None. 00092 00093 Return Value: 00094 00095 None. 00096 00097 --*/ 00098 00099 { 00100 00101 ULONG_PTR MemoryBlock1; 00102 ULONG_PTR MemoryBlock2; 00103 ULONG Number; 00104 ULONG PcrPage; 00105 PKPRCB Prcb; 00106 KPROCESSOR_STATE ProcessorState; 00107 struct _RESTART_BLOCK *RestartBlock; 00108 BOOLEAN Started; 00109 LOGICAL SpecialPoolState; 00110 00111 #if !defined(NT_UP) 00112 00113 // 00114 // If the registered number of processors is greater than the maximum 00115 // number of processors supported, then only allow the maximum number 00116 // of supported processors. 00117 // 00118 00119 if (KeRegisteredProcessors > MAXIMUM_PROCESSORS) { 00120 KeRegisteredProcessors = MAXIMUM_PROCESSORS; 00121 } 00122 00123 // 00124 // Initialize the processor state that will be used to start each of 00125 // processors. Each processor starts in the system initialization code 00126 // with address of the loader parameter block as an argument. 00127 // 00128 00129 RtlZeroMemory(&ProcessorState, sizeof(KPROCESSOR_STATE)); 00130 ProcessorState.ContextFrame.IntA0 = (ULONGLONG)(LONG_PTR)KeLoaderBlock; 00131 ProcessorState.ContextFrame.Fir = (ULONGLONG)(LONG_PTR)KiStartProcessor; 00132 Number = 1; 00133 while (Number < KeRegisteredProcessors) { 00134 00135 // 00136 // Allocate a DPC stack, an idle thread kernel stack, a panic 00137 // stack, a PCR page, a processor block, and an executive thread 00138 // object. If the allocation fails or the allocation cannot be 00139 // made from unmapped nonpaged pool, then stop starting processors. 00140 // 00141 // Disable any special pooling that the user may have set in the 00142 // registry as the next couple of allocations must come from KSEG0. 00143 // 00144 00145 SpecialPoolState = MmSetSpecialPool(FALSE); 00146 MemoryBlock1 = (ULONG_PTR)ExAllocatePool(NonPagedPool, BLOCK1_SIZE); 00147 if (IS_KSEG_ADDRESS(MemoryBlock1) == FALSE) { 00148 MmSetSpecialPool(SpecialPoolState); 00149 if ((PVOID)MemoryBlock1 != NULL) { 00150 ExFreePool((PVOID)MemoryBlock1); 00151 } 00152 00153 break; 00154 } 00155 00156 MemoryBlock2 = (ULONG_PTR)ExAllocatePool(NonPagedPool, BLOCK2_SIZE); 00157 if (IS_KSEG_ADDRESS(MemoryBlock2) == FALSE) { 00158 MmSetSpecialPool(SpecialPoolState); 00159 ExFreePool((PVOID)MemoryBlock1); 00160 if ((PVOID)MemoryBlock2 != NULL) { 00161 ExFreePool((PVOID)MemoryBlock2); 00162 } 00163 00164 break; 00165 } 00166 00167 MmSetSpecialPool(SpecialPoolState); 00168 00169 // 00170 // Zero both blocks of allocated memory. 00171 // 00172 00173 RtlZeroMemory((PVOID)MemoryBlock1, BLOCK1_SIZE); 00174 RtlZeroMemory((PVOID)MemoryBlock2, BLOCK2_SIZE); 00175 00176 // 00177 // Set address of interrupt stack in loader parameter block. 00178 // 00179 00180 KeLoaderBlock->u.Alpha.PanicStack = 00181 KSEG0_ADDRESS(MemoryBlock1 + (1 * KERNEL_STACK_SIZE)); 00182 00183 // 00184 // Set address of idle thread kernel stack in loader parameter block. 00185 // 00186 00187 KeLoaderBlock->KernelStack = 00188 KSEG0_ADDRESS(MemoryBlock1 + (2 * KERNEL_STACK_SIZE)); 00189 00190 ProcessorState.ContextFrame.IntSp = 00191 (ULONGLONG)(LONG_PTR)KeLoaderBlock->KernelStack; 00192 00193 // 00194 // Set address of panic stack in loader parameter block. 00195 // 00196 00197 KeLoaderBlock->u.Alpha.DpcStack = 00198 KSEG0_ADDRESS(MemoryBlock1 + (3 * KERNEL_STACK_SIZE)); 00199 00200 // 00201 // Set the page frame of the PCR page in the loader parameter block. 00202 // 00203 00204 PcrPage = KSEG_PFN(MemoryBlock1 + (3 * KERNEL_STACK_SIZE)); 00205 KeLoaderBlock->u.Alpha.PcrPage = PcrPage; 00206 00207 // 00208 // Set the address of the processor block and executive thread in the 00209 // loader parameter block. 00210 // 00211 00212 KeLoaderBlock->Prcb = KSEG0_ADDRESS((MemoryBlock2 + 63) & ~63); 00213 KeLoaderBlock->Thread = KeLoaderBlock->Prcb + ROUND_UP(KPRCB); 00214 00215 // 00216 // Attempt to start the next processor. If attempt is successful, 00217 // then wait for the processor to get initialized. Otherwise, 00218 // deallocate the processor resources and terminate the loop. 00219 // 00220 00221 Started = HalStartNextProcessor(KeLoaderBlock, &ProcessorState); 00222 if (Started == FALSE) { 00223 ExFreePool((PVOID)MemoryBlock1); 00224 ExFreePool((PVOID)MemoryBlock2); 00225 break; 00226 00227 } else { 00228 00229 // 00230 // Wait until boot is finished on the target processor before 00231 // starting the next processor. Booting is considered to be 00232 // finished when a processor completes its initialization and 00233 // drops into the idle loop. 00234 // 00235 00236 Prcb = (PKPRCB)(KeLoaderBlock->Prcb); 00237 RestartBlock = Prcb->RestartBlock; 00238 while (RestartBlock->BootStatus.BootFinished == 0) { 00239 KiMb(); 00240 } 00241 } 00242 00243 Number += 1; 00244 } 00245 00246 #endif 00247 00248 // 00249 // Reset and synchronize the performance counters of all processors, by 00250 // applying a null adjustment to the interrupt time 00251 // 00252 00253 KiAdjustInterruptTime(0); 00254 return; 00255 } 00256 

Generated on Sat May 15 19:39:14 2004 for test by doxygen 1.3.7