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 David N. Cutler 29-Apr-1993 00018 00019 Environment: 00020 00021 Kernel mode only. 00022 00023 Revision History: 00024 00025 --*/ 00026 00027 00028 #include "ki.h" 00029 00030 #ifdef ALLOC_PRAGMA 00031 00032 #pragma alloc_text(INIT, KeStartAllProcessors) 00033 00034 #endif 00035 00036 // 00037 // Define macro to round up to 64-byte boundary and define block sizes. 00038 // 00039 00040 #define ROUND_UP(x) ((sizeof(x) + 63) & (~63)) 00041 #define BLOCK1_SIZE ((3 * KERNEL_STACK_SIZE) + PAGE_SIZE) 00042 #define BLOCK2_SIZE (ROUND_UP(KPRCB) + ROUND_UP(ETHREAD) + 64) 00043 00044 // 00045 // Define barrier wait static data. 00046 // 00047 00048 #if !defined(NT_UP) 00049 00050 ULONG KiBarrierWait = 0; 00051 00052 #endif 00053 00054 // 00055 // Define forward referenced prototypes. 00056 // 00057 00058 VOID 00059 KiInitializeSystem ( 00060 IN PLOADER_PARAMETER_BLOCK Loaderblock 00061 ); 00062 00063 VOID 00064 KeStartAllProcessors( 00065 VOID 00066 ) 00067 00068 /*++ 00069 00070 Routine Description: 00071 00072 This function is called during phase 1 initialize on the master boot 00073 processor to start all of the other registered processors. 00074 00075 Arguments: 00076 00077 None. 00078 00079 Return Value: 00080 00081 None. 00082 00083 --*/ 00084 00085 { 00086 00087 ULONG MemoryBlock1; 00088 ULONG MemoryBlock2; 00089 ULONG Number; 00090 ULONG PcrAddress; 00091 ULONG PcrPage; 00092 PKPRCB Prcb; 00093 KPROCESSOR_STATE ProcessorState; 00094 PRESTART_BLOCK RestartBlock; 00095 BOOLEAN Started; 00096 00097 #if !defined(NT_UP) 00098 00099 // 00100 // If the registered number of processors is greater than the maximum 00101 // number of processors supported, then only allow the maximum number 00102 // of supported processors. 00103 // 00104 00105 if (KeRegisteredProcessors > MAXIMUM_PROCESSORS) { 00106 KeRegisteredProcessors = MAXIMUM_PROCESSORS; 00107 } 00108 00109 // 00110 // Set barrier that will prevent any other processor from entering the 00111 // idle loop until all processors have been started. 00112 // 00113 00114 KiBarrierWait = 1; 00115 00116 // 00117 // Initialize the processor state that will be used to start each of 00118 // processors. Each processor starts in the system initialization code 00119 // with address of the loader parameter block as an argument. 00120 // 00121 00122 Number = 1; 00123 RtlZeroMemory(&ProcessorState, sizeof(KPROCESSOR_STATE)); 00124 ProcessorState.ContextFrame.IntA0 = (ULONG)KeLoaderBlock; 00125 ProcessorState.ContextFrame.Fir = (ULONG)KiInitializeSystem; 00126 while (Number < KeRegisteredProcessors) { 00127 00128 // 00129 // Allocate a DPC stack, an idle thread kernel stack, a panic 00130 // stack, a PCR page, a processor block, and an executive thread 00131 // object. If the allocation fails or the allocation cannot be 00132 // made from unmapped nonpaged pool, then stop starting processors. 00133 // 00134 00135 MemoryBlock1 = (ULONG)ExAllocatePool(NonPagedPool, BLOCK1_SIZE); 00136 if (((PVOID)MemoryBlock1 == NULL) || 00137 ((MemoryBlock1 & 0xc0000000) != KSEG0_BASE)) { 00138 if ((PVOID)MemoryBlock1 != NULL) { 00139 ExFreePool((PVOID)MemoryBlock1); 00140 } 00141 00142 break; 00143 } 00144 00145 MemoryBlock2 = (ULONG)ExAllocatePool(NonPagedPool, BLOCK2_SIZE); 00146 if (((PVOID)MemoryBlock2 == NULL) || 00147 ((MemoryBlock2 & 0xc0000000) != KSEG0_BASE)) { 00148 ExFreePool((PVOID)MemoryBlock1); 00149 if ((PVOID)MemoryBlock2 != NULL) { 00150 ExFreePool((PVOID)MemoryBlock2); 00151 } 00152 00153 break; 00154 } 00155 00156 // 00157 // Zero both blocks of allocated memory. 00158 // 00159 00160 RtlZeroMemory((PVOID)MemoryBlock1, BLOCK1_SIZE); 00161 RtlZeroMemory((PVOID)MemoryBlock2, BLOCK2_SIZE); 00162 00163 // 00164 // Set address of interrupt stack in loader parameter block. 00165 // 00166 00167 KeLoaderBlock->u.Mips.InterruptStack = MemoryBlock1 + (1 * KERNEL_STACK_SIZE); 00168 00169 // 00170 // Set address of idle thread kernel stack in loader parameter block. 00171 // 00172 00173 KeLoaderBlock->KernelStack = MemoryBlock1 + (2 * KERNEL_STACK_SIZE); 00174 00175 // 00176 // Set address of panic stack in loader parameter block. 00177 // 00178 00179 KeLoaderBlock->u.Mips.PanicStack = MemoryBlock1 + (3 * KERNEL_STACK_SIZE); 00180 00181 // 00182 // Change the color of the PCR page to match the new mapping and 00183 // set the page frame of the PCR page in the loader parameter block. 00184 // 00185 00186 PcrAddress = MemoryBlock1 + (3 * KERNEL_STACK_SIZE); 00187 PcrPage = (PcrAddress ^ KSEG0_BASE) >> PAGE_SHIFT; 00188 HalChangeColorPage((PVOID)KIPCR, (PVOID)PcrAddress, PcrPage); 00189 KeLoaderBlock->u.Mips.PcrPage = PcrPage; 00190 00191 // 00192 // Set the address of the processor block and executive thread in the 00193 // loader parameter block. 00194 // 00195 00196 KeLoaderBlock->Prcb = (MemoryBlock2 + 63) & ~63; 00197 KeLoaderBlock->Thread = KeLoaderBlock->Prcb + ROUND_UP(KPRCB); 00198 00199 // 00200 // Attempt to start the next processor. If attempt is successful, 00201 // then wait for the processor to get initialized. Otherwise, 00202 // deallocate the processor resources and terminate the loop. 00203 // 00204 00205 Started = HalStartNextProcessor(KeLoaderBlock, &ProcessorState); 00206 if (Started == FALSE) { 00207 HalChangeColorPage((PVOID)PcrAddress, (PVOID)KIPCR, PcrPage); 00208 ExFreePool((PVOID)MemoryBlock1); 00209 ExFreePool((PVOID)MemoryBlock2); 00210 break; 00211 00212 } else { 00213 00214 // 00215 // Wait until boot is finished on the target processor before 00216 // starting the next processor. Booting is considered to be 00217 // finished when a processor completes its initialization and 00218 // drops into the idle loop. 00219 // 00220 00221 Prcb = (PKPRCB)(KeLoaderBlock->Prcb); 00222 RestartBlock = Prcb->RestartBlock; 00223 while (RestartBlock->BootStatus.BootFinished == 0) { 00224 } 00225 } 00226 00227 Number += 1; 00228 } 00229 00230 // 00231 // Allow all processor that were started to enter the idle loop and 00232 // begin execution. 00233 // 00234 00235 KiBarrierWait = 0; 00236 00237 #endif 00238 00239 // 00240 // Reset and synchronize the performance counters of all processors, by 00241 // applying a null adjustment to the interrupt time 00242 // 00243 00244 KiAdjustInterruptTime (0); 00245 return; 00246 }

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