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

allproc.c File Reference

#include "ki.h"

Go to the source code of this file.

Functions

VOID KiCloneDescriptor (IN PKDESCRIPTOR pSrcDescriptorInfo, IN PKDESCRIPTOR pDestDescriptorInfo)
VOID KiCloneSelector (IN ULONG SrcSelector, IN PKGDTENTRY pNGDT, IN PKDESCRIPTOR pDestDescriptor)
VOID KeStartAllProcessors (VOID)

Variables

ULONG KeRegisteredProcessors
ULONG KiBarrierWait = 0


Function Documentation

VOID KeStartAllProcessors VOID   ) 
 

Definition at line 75 of file i386/allproc.c.

References ExAllocatePoolWithTag, ExFreePool(), FALSE, HalStartNextProcessor(), KeLoaderBlock, KeNumberProcessors, KeRegisteredProcessors, _LOADER_PARAMETER_BLOCK::KernelStack, KiAdjustInterruptTime(), KiBarrierWait, KiCloneDescriptor(), KiCloneSelector(), KiInitializePcr(), KiProcessorBlock, KiSystemStartup(), KTHREAD, MAXIMUM_PROCESSORS, MmCreateKernelStack(), MmDeleteKernelStack(), NonPagedPool, NULL, PKPROCESS, PKTHREAD, _LOADER_PARAMETER_BLOCK::Prcb, and _LOADER_PARAMETER_BLOCK::Thread.

00080 : 00081 00082 Called by p0 during phase 1 of bootup. This function implements 00083 the x86 specific code to contact the hal for each system processor. 00084 00085 Arguments: 00086 00087 Return Value: 00088 00089 All available processors are sent to KiSystemStartup. 00090 00091 --*/ 00092 { 00093 KPROCESSOR_STATE ProcessorState; 00094 KDESCRIPTOR Descriptor; 00095 KDESCRIPTOR TSSDesc, DFTSSDesc, NMITSSDesc, PCRDesc; 00096 PKGDTENTRY pGDT; 00097 PVOID pStack; 00098 PVOID pDpcStack; 00099 ULONG DFStack; 00100 PUCHAR pThreadObject; 00101 PULONG pTopOfStack; 00102 ULONG NewProcessorNumber; 00103 BOOLEAN NewProcessor; 00104 PKPROCESS Process; 00105 PKTHREAD Thread; 00106 PKTSS pTSS; 00107 PLIST_ENTRY NextEntry; 00108 LONG NumberProcessors; 00109 00110 // 00111 // If the registered number of processors is greater than the maximum 00112 // number of processors supported, then only allow the maximum number 00113 // of supported processors. 00114 // 00115 00116 if (KeRegisteredProcessors > MAXIMUM_PROCESSORS) { 00117 KeRegisteredProcessors = MAXIMUM_PROCESSORS; 00118 } 00119 00120 // 00121 // Set barrier that will prevent any other processor from entering the 00122 // idle loop until all processors have been started. 00123 // 00124 00125 KiBarrierWait = 1; 00126 00127 00128 while ((ULONG)KeNumberProcessors < KeRegisteredProcessors) { 00129 // 00130 // Build up a processor state for new processor 00131 // 00132 00133 RtlZeroMemory ((PVOID) &ProcessorState, sizeof ProcessorState); 00134 00135 00136 // 00137 // Give the new processor its own GDT 00138 // 00139 00140 _asm { 00141 sgdt Descriptor.Limit 00142 } 00143 00144 KiCloneDescriptor (&Descriptor, 00145 &ProcessorState.SpecialRegisters.Gdtr); 00146 00147 pGDT = (PKGDTENTRY) ProcessorState.SpecialRegisters.Gdtr.Base; 00148 00149 00150 // 00151 // Give new processor its own IDT 00152 // 00153 00154 _asm { 00155 sidt Descriptor.Limit 00156 } 00157 KiCloneDescriptor (&Descriptor, 00158 &ProcessorState.SpecialRegisters.Idtr); 00159 00160 00161 // 00162 // Give new processor its own TSS and PCR 00163 // 00164 00165 KiCloneSelector (KGDT_TSS, pGDT, &TSSDesc); 00166 KiCloneSelector (KGDT_R0_PCR, pGDT, &PCRDesc); 00167 00168 // 00169 // Allocate double-fault TSS & stack, and NMI TSS 00170 // 00171 00172 KiCloneSelector (KGDT_DF_TSS, pGDT, &DFTSSDesc); 00173 DFStack = (ULONG)ExAllocatePoolWithTag(NonPagedPool, DOUBLE_FAULT_STACK_SIZE, ' eK'); 00174 pTSS = (PKTSS)DFTSSDesc.Base; 00175 pTSS->Esp0 = DFStack + DOUBLE_FAULT_STACK_SIZE; 00176 pTSS->NotUsed2[5] = DFStack + DOUBLE_FAULT_STACK_SIZE; 00177 00178 KiCloneSelector (KGDT_NMI_TSS, pGDT, &NMITSSDesc); 00179 pTSS = (PKTSS)NMITSSDesc.Base; 00180 pTSS->Esp0 = DFStack + DOUBLE_FAULT_STACK_SIZE; 00181 pTSS->NotUsed2[5] = DFStack + DOUBLE_FAULT_STACK_SIZE; 00182 00183 00184 // 00185 // Set other SpecialRegisters in processor state 00186 // 00187 00188 _asm { 00189 mov eax, cr0 00190 and eax, NOT (CR0_AM or CR0_WP) 00191 mov ProcessorState.SpecialRegisters.Cr0, eax 00192 mov eax, cr3 00193 mov ProcessorState.SpecialRegisters.Cr3, eax 00194 00195 pushfd 00196 pop ProcessorState.ContextFrame.EFlags 00197 and ProcessorState.ContextFrame.EFlags, NOT EFLAGS_INTERRUPT_MASK 00198 } 00199 00200 ProcessorState.SpecialRegisters.Tr = KGDT_TSS; 00201 pGDT[KGDT_TSS>>3].HighWord.Bytes.Flags1 = 0x89; 00202 00203 #if defined(_X86PAE_) 00204 ProcessorState.SpecialRegisters.Cr4 = CR4_PAE; 00205 #endif 00206 00207 // 00208 // Allocate a DPC stack, idle thread stack and ThreadObject for 00209 // the new processor. 00210 // 00211 00212 pStack = MmCreateKernelStack (FALSE); 00213 pDpcStack = MmCreateKernelStack (FALSE); 00214 pThreadObject = (PUCHAR)ExAllocatePoolWithTag (NonPagedPool, sizeof(ETHREAD), ' eK'); 00215 00216 // 00217 // Zero initialize these... 00218 // 00219 00220 RtlZeroMemory ((PVOID) PCRDesc.Base, sizeof (KPCR)); 00221 RtlZeroMemory ((PVOID) pThreadObject, sizeof (KTHREAD)); 00222 00223 00224 // 00225 // Setup context 00226 // Push variables onto new stack 00227 // 00228 00229 pTopOfStack = (PULONG) pStack; 00230 pTopOfStack[-1] = (ULONG) KeLoaderBlock; 00231 ProcessorState.ContextFrame.Esp = (ULONG) (pTopOfStack-2); 00232 ProcessorState.ContextFrame.Eip = (ULONG) KiSystemStartup; 00233 00234 ProcessorState.ContextFrame.SegCs = KGDT_R0_CODE; 00235 ProcessorState.ContextFrame.SegDs = KGDT_R3_DATA; 00236 ProcessorState.ContextFrame.SegEs = KGDT_R3_DATA; 00237 ProcessorState.ContextFrame.SegFs = KGDT_R0_PCR; 00238 ProcessorState.ContextFrame.SegSs = KGDT_R0_DATA; 00239 00240 00241 // 00242 // Initialize new processor's PCR & Prcb 00243 // 00244 00245 NewProcessorNumber = KeNumberProcessors; 00246 KiInitializePcr ( 00247 (ULONG) NewProcessorNumber, 00248 (PKPCR) PCRDesc.Base, 00249 (PKIDTENTRY) ProcessorState.SpecialRegisters.Idtr.Base, 00250 (PKGDTENTRY) ProcessorState.SpecialRegisters.Gdtr.Base, 00251 (PKTSS) TSSDesc.Base, 00252 (PKTHREAD) pThreadObject, 00253 (PVOID) pDpcStack 00254 ); 00255 00256 00257 // 00258 // Adjust LoaderBlock so it has the next processors state 00259 // 00260 00261 KeLoaderBlock->KernelStack = (ULONG) pTopOfStack; 00262 KeLoaderBlock->Thread = (ULONG) pThreadObject; 00263 KeLoaderBlock->Prcb = (ULONG) ((PKPCR) PCRDesc.Base)->Prcb; 00264 00265 00266 // 00267 // Contact hal to start new processor 00268 // 00269 00270 NewProcessor = HalStartNextProcessor (KeLoaderBlock, &ProcessorState); 00271 00272 00273 if (!NewProcessor) { 00274 00275 // 00276 // There wasn't another processor, so free resources and 00277 // break 00278 // 00279 00280 KiProcessorBlock[NewProcessorNumber] = NULL; 00281 ExFreePool ((PVOID) ProcessorState.SpecialRegisters.Gdtr.Base); 00282 ExFreePool ((PVOID) ProcessorState.SpecialRegisters.Idtr.Base); 00283 ExFreePool ((PVOID) TSSDesc.Base); 00284 ExFreePool ((PVOID) DFTSSDesc.Base); 00285 ExFreePool ((PVOID) NMITSSDesc.Base); 00286 ExFreePool ((PVOID) PCRDesc.Base); 00287 ExFreePool ((PVOID) pThreadObject); 00288 ExFreePool ((PVOID) DFStack); 00289 MmDeleteKernelStack ( pStack, FALSE); 00290 MmDeleteKernelStack ( pDpcStack, FALSE); 00291 break; 00292 } 00293 00294 00295 // 00296 // Wait for processor to initialize in kernel, then loop for another 00297 // 00298 00299 while (*((volatile ULONG *) &KeLoaderBlock->Prcb) != 0) { 00300 KeYieldProcessor(); 00301 } 00302 } 00303 00304 // 00305 // Reset and synchronize the performance counters of all processors, by 00306 // applying a null adjustment to the interrupt time 00307 // 00308 00309 KiAdjustInterruptTime (0); 00310 00311 // 00312 // Allow all processors that were started to enter the idle loop and 00313 // begin execution. 00314 // 00315 00316 KiBarrierWait = 0; 00317 }

VOID KiCloneDescriptor IN PKDESCRIPTOR  pSrcDescriptorInfo,
IN PKDESCRIPTOR  pDestDescriptorInfo
[static]
 

Definition at line 375 of file i386/allproc.c.

References ExAllocatePoolWithTag, NonPagedPool, Size, and USHORT.

Referenced by KeStartAllProcessors(), and KiCloneSelector().

00381 : 00382 00383 Makes a copy of the specified descriptor, and supplies a return 00384 descriptor for the new copy 00385 00386 Arguments: 00387 pSrcDescriptor - descriptor to clone 00388 pDescDescriptor - the cloned descriptor 00389 00390 Return Value: 00391 00392 --*/ 00393 { 00394 ULONG Size; 00395 00396 Size = pSrcDescriptor->Limit + 1; 00397 pDestDescriptor->Limit = (USHORT) Size -1; 00398 pDestDescriptor->Base = (ULONG) ExAllocatePoolWithTag (NonPagedPool, Size, ' eK'); 00399 00400 RtlMoveMemory ((PVOID) pDestDescriptor->Base, 00401 (PVOID) pSrcDescriptor->Base, Size); 00402 }

VOID KiCloneSelector IN ULONG  SrcSelector,
IN PKGDTENTRY  pNGDT,
IN PKDESCRIPTOR  pDestDescriptor
[static]
 

Definition at line 322 of file i386/allproc.c.

References KiCloneDescriptor(), PAGE_SHIFT, and USHORT.

Referenced by KeStartAllProcessors().

00328 : 00329 00330 Makes a copy of the current selector's data, and update the new 00331 gdt's linear address to point to the new copy. 00332 00333 Arguments: 00334 SrcSelector - Selector value to clone 00335 pNGDT - New gdt table which is being built 00336 DescDescriptor - descriptor structure to fill in with resulting memory 00337 00338 Return Value: 00339 00340 --*/ 00341 ) 00342 { 00343 KDESCRIPTOR Descriptor; 00344 PKGDTENTRY pGDT; 00345 ULONG CurrentBase; 00346 ULONG NewBase; 00347 00348 _asm { 00349 sgdt fword ptr [Descriptor.Limit] ; Get GDT's addr 00350 } 00351 00352 pGDT = (PKGDTENTRY) Descriptor.Base; 00353 pGDT += SrcSelector >> 3; 00354 pNGDT += SrcSelector >> 3; 00355 00356 CurrentBase = pGDT->BaseLow | (pGDT->HighWord.Bits.BaseMid << 16) | 00357 (pGDT->HighWord.Bits.BaseHi << 24); 00358 00359 Descriptor.Base = CurrentBase; 00360 Descriptor.Limit = pGDT->LimitLow; 00361 if (pGDT->HighWord.Bits.Granularity & GRAN_PAGE) 00362 Descriptor.Limit = (Descriptor.Limit << PAGE_SHIFT) -1; 00363 00364 KiCloneDescriptor (&Descriptor, pDestDescriptor); 00365 NewBase = pDestDescriptor->Base; 00366 00367 pNGDT->BaseLow = (USHORT) NewBase & 0xffff; 00368 pNGDT->HighWord.Bits.BaseMid = (UCHAR) (NewBase >> 16) & 0xff; 00369 pNGDT->HighWord.Bits.BaseHi = (UCHAR) (NewBase >> 24) & 0xff; 00370 }


Variable Documentation

ULONG KeRegisteredProcessors
 

Definition at line 44 of file i386/allproc.c.

ULONG KiBarrierWait = 0
 

Definition at line 68 of file i386/allproc.c.

Referenced by KeStartAllProcessors().


Generated on Sat May 15 19:42:51 2004 for test by doxygen 1.3.7