00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
#include "ki.h"
00031
00032
#ifdef NT_UP
00033
00034
VOID
00035
KeStartAllProcessors (
00036 VOID
00037 )
00038 {
00039
00040 }
00041
00042
#else
00043
00044 extern ULONG
KeRegisteredProcessors;
00045
00046
static VOID
00047
KiCloneDescriptor (
00048 IN PKDESCRIPTOR pSrcDescriptorInfo,
00049 IN PKDESCRIPTOR pDestDescriptorInfo
00050 );
00051
00052
static VOID
00053
KiCloneSelector (
00054 IN ULONG SrcSelector,
00055 IN PKGDTENTRY pNGDT,
00056 IN PKDESCRIPTOR pDestDescriptor
00057 );
00058
00059
00060
#ifdef ALLOC_PRAGMA
00061
#pragma alloc_text(INIT,KeStartAllProcessors)
00062
#pragma alloc_text(INIT,KiCloneDescriptor)
00063
#pragma alloc_text(INIT,KiCloneSelector)
00064
#endif
00065
00066
#if !defined(NT_UP)
00067
00068 ULONG
KiBarrierWait = 0;
00069
00070
#endif
00071
00072
00073
00074
VOID
00075 KeStartAllProcessors (
00076 VOID
00077 )
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
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 }
00318
00319
00320
00321
static VOID
00322 KiCloneSelector (
00323 IN ULONG SrcSelector,
00324 IN PKGDTENTRY pNGDT,
00325 IN PKDESCRIPTOR pDestDescriptor
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
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 }
00371
00372
00373
00374
static VOID
00375 KiCloneDescriptor (
00376 IN PKDESCRIPTOR pSrcDescriptor,
00377 IN PKDESCRIPTOR pDestDescriptor
00378 )
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
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 }
00403
00404
00405
#endif // !NT_UP