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
00112
00113
00114
00115
00116
if (
KeRegisteredProcessors >
MAXIMUM_PROCESSORS) {
00117
KeRegisteredProcessors =
MAXIMUM_PROCESSORS;
00118 }
00119
00120
00121
00122
00123
00124
00125
KiBarrierWait = 1;
00126
00127
00128
while ((ULONG)
KeNumberProcessors <
KeRegisteredProcessors) {
00129
00130
00131
00132
00133 RtlZeroMemory ((PVOID) &ProcessorState,
sizeof ProcessorState);
00134
00135
00136
00137
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
00152
00153
00154 _asm {
00155 sidt Descriptor.Limit
00156 }
00157
KiCloneDescriptor (&Descriptor,
00158 &ProcessorState.SpecialRegisters.Idtr);
00159
00160
00161
00162
00163
00164
00165
KiCloneSelector (KGDT_TSS, pGDT, &TSSDesc);
00166
KiCloneSelector (KGDT_R0_PCR, pGDT, &PCRDesc);
00167
00168
00169
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
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
00209
00210
00211
00212 pStack =
MmCreateKernelStack (FALSE);
00213 pDpcStack =
MmCreateKernelStack (FALSE);
00214 pThreadObject = (PUCHAR)
ExAllocatePoolWithTag (NonPagedPool,
sizeof(
ETHREAD), ' eK');
00215
00216
00217
00218
00219
00220 RtlZeroMemory ((PVOID) PCRDesc.Base, sizeof (KPCR));
00221 RtlZeroMemory ((PVOID) pThreadObject,
sizeof (
KTHREAD));
00222
00223
00224
00225
00226
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
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
00259
00260
00261
KeLoaderBlock->
KernelStack = (ULONG) pTopOfStack;
00262
KeLoaderBlock->
Thread = (ULONG) pThreadObject;
00263
KeLoaderBlock->
Prcb = (ULONG) ((PKPCR) PCRDesc.Base)->Prcb;
00264
00265
00266
00267
00268
00269
00270 NewProcessor =
HalStartNextProcessor (KeLoaderBlock, &ProcessorState);
00271
00272
00273
if (!NewProcessor) {
00274
00275
00276
00277
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
00297
00298
00299
while (*((
volatile ULONG *) &
KeLoaderBlock->
Prcb) != 0) {
00300 KeYieldProcessor();
00301 }
00302 }
00303
00304
00305
00306
00307
00308
00309
KiAdjustInterruptTime (0);
00310
00311
00312
00313
00314
00315
00316
KiBarrierWait = 0;
00317 }