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 }

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