* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/kernel.c
* PURPOSE: Initializes the kernel
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
ULONG OrigFlags, Flags, FinalFlags;
ULONG MaxCpuidLevel;
ULONG Dummy, Eax, Ecx, Edx;
- PKPCR Pcr = KeGetCurrentKPCR();
+ PKIPCR Pcr = (PKIPCR)KeGetCurrentKPCR();
Ke386CpuidFlags2 = Ke386CpuidExFlags = 0;
Ke386CacheAlignment = 32;
Flags = OrigFlags ^ X86_EFLAGS_ID;
Ke386RestoreFlags(Flags);
Ke386SaveFlags(FinalFlags);
-
+
Pcr->PrcbData.LogicalProcessorsPerPhysicalProcessor = 1;
Pcr->PrcbData.InitialApicId = 0xff;
-
+
if ((OrigFlags & X86_EFLAGS_ID) == (FinalFlags & X86_EFLAGS_ID))
{
/* No cpuid supported. */
/* Get the vendor name and the maximum cpuid level supported. */
Ki386Cpuid(0, &MaxCpuidLevel, (PULONG)&Pcr->PrcbData.VendorString[0], (PULONG)&Pcr->PrcbData.VendorString[8], (PULONG)&Pcr->PrcbData.VendorString[4]);
if (MaxCpuidLevel > 0)
- {
+ {
/* Get the feature flags. */
Ki386Cpuid(1, &Eax, &Ke386CpuidExMisc, &Ke386CpuidFlags2, &Pcr->PrcbData.FeatureBits);
+
+ DPRINT ("Model: %x\n", (Eax & 0xf00) == 0xf00 ? ((Eax >> 4) & 0xf) | ((Eax >> 12) & 0xf0) : (Eax >> 4) & 0xf);
+ DPRINT ("Family: %x\n", (Eax & 0xf00) == 0xf00 ? ((Eax >> 8) & 0xf) + ((Eax >> 20) & 0xff) : (Eax >> 8) & 0xf);
+
/* Get the cache alignment, if it is available */
if (Pcr->PrcbData.FeatureBits & (1<<19))
{
}
Pcr->PrcbData.CpuType = (Eax >> 8) & 0xf;
Pcr->PrcbData.CpuStep = (Eax & 0xf) | ((Eax << 4) & 0xf00);
-
+
Pcr->PrcbData.InitialApicId = (Ke386CpuidExMisc >> 24) & 0xff;
/* detect Hyper-Threading on Pentium 4 CPUs or later */
IdleProcessorMask |= (1 << KeGetCurrentProcessorNumber());
KeReleaseDispatcherDatabaseLock(oldIrql);
}
-
-VOID
+
+VOID
INIT_FUNCTION
KeCreateApplicationProcessorIdleThread(ULONG Id)
{
PsInitializeIdleOrFirstThread(PsIdleProcess,
&IdleThread,
NULL,
- KernelMode,
+ KernelMode,
FALSE);
IdleThread->Tcb.State = Running;
IdleThread->Tcb.FreezeCount = 0;
Id, IdleThread->Cid.UniqueThread);
}
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
+NTAPI
KePrepareForApplicationProcessorInit(ULONG Id)
{
DPRINT("KePrepareForApplicationProcessorInit(Id %d)\n", Id);
PFN_TYPE PrcPfn;
- PKPCR Pcr;
- PKPCR BootPcr;
+ PKIPCR Pcr;
+ PKIPCR BootPcr;
- BootPcr = (PKPCR)KPCR_BASE;
- Pcr = (PKPCR)((ULONG_PTR)KPCR_BASE + Id * PAGE_SIZE);
+ BootPcr = (PKIPCR)KPCR_BASE;
+ Pcr = (PKIPCR)((ULONG_PTR)KPCR_BASE + Id * PAGE_SIZE);
MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &PrcPfn);
MmCreateVirtualMappingForKernel((PVOID)Pcr,
* Create a PCR for this processor
*/
memset(Pcr, 0, PAGE_SIZE);
- Pcr->ProcessorNumber = Id;
- Pcr->Tib.Self = &Pcr->Tib;
- Pcr->Self = Pcr;
+ Pcr->Number = Id;
+ Pcr->SetMember = 1 << Id;
+ Pcr->NtTib.Self = &Pcr->NtTib;
+ Pcr->Self = (PKPCR)Pcr;
Pcr->Prcb = &Pcr->PrcbData;
Pcr->Irql = SYNCH_LEVEL;
+ Pcr->PrcbData.SetMember = 1 << Id;
Pcr->PrcbData.MHz = BootPcr->PrcbData.MHz;
- Pcr->StallScaleFactor = BootPcr->StallScaleFactor;
+ Pcr->StallScaleFactor = BootPcr->StallScaleFactor;
/* Mark the end of the exception handler list */
- Pcr->Tib.ExceptionList = (PVOID)-1;
+ Pcr->NtTib.ExceptionList = (PVOID)-1;
KiGdtPrepareForApplicationProcessorInit(Id);
+
+ KeActiveProcessors |= 1 << Id;
}
VOID
+NTAPI
KeApplicationProcessorInit(VOID)
{
ULONG Offset;
- PKPCR Pcr;
+ PKIPCR Pcr;
DPRINT("KeApplicationProcessorInit()\n");
/* Enable global pages */
Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE);
}
-
+
Offset = InterlockedIncrementUL(&PcrsAllocated) - 1;
- Pcr = (PKPCR)((ULONG_PTR)KPCR_BASE + Offset * PAGE_SIZE);
+ Pcr = (PKIPCR)((ULONG_PTR)KPCR_BASE + Offset * PAGE_SIZE);
/*
* Initialize the GDT
*/
- KiInitializeGdt(Pcr);
+ KiInitializeGdt((PKPCR)Pcr);
/* Get processor information. */
Ki386GetCpuId();
Ke386EnableInterrupts();
}
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
+NTAPI
KeInit1(PCHAR CommandLine, PULONG LastKernelAddress)
{
- PKPCR KPCR;
+ PKIPCR KPCR;
BOOLEAN Pae = FALSE;
BOOLEAN NoExecute = FALSE;
PCHAR p1, p2;
/*
* Initialize the initial PCR region. We can't allocate a page
* with MmAllocPage() here because MmInit1() has not yet been
- * called, so we use a predefined page in low memory
+ * called, so we use a predefined page in low memory
*/
- KPCR = (PKPCR)KPCR_BASE;
+ KPCR = (PKIPCR)KPCR_BASE;
memset(KPCR, 0, PAGE_SIZE);
- KPCR->Self = KPCR;
+ KPCR->Self = (PKPCR)KPCR;
KPCR->Prcb = &KPCR->PrcbData;
KPCR->Irql = SYNCH_LEVEL;
- KPCR->Tib.Self = &KPCR->Tib;
+ KPCR->NtTib.Self = &KPCR->NtTib;
KPCR->GDT = KiBootGdt;
KPCR->IDT = (PUSHORT)KiIdt;
KPCR->TSS = &KiBootTss;
- KPCR->ProcessorNumber = 0;
+ KPCR->Number = 0;
+ KPCR->SetMember = 1 << 0;
+ KeActiveProcessors = 1 << 0;
+ KPCR->PrcbData.SetMember = 1 << 0;
KiPcrInitDone = 1;
PcrsAllocated++;
KiCheckFPU();
/* Mark the end of the exception handler list */
- KPCR->Tib.ExceptionList = (PVOID)-1;
+ KPCR->NtTib.ExceptionList = (PVOID)-1;
KeInitDpc(KPCR->Prcb);
KeInitExceptions ();
KeInitInterrupts ();
+ KeActiveProcessors |= 1 << 0;
+
+
if (KPCR->PrcbData.FeatureBits & X86_FEATURE_PGE)
{
ULONG Flags;
p1 = p2;
}
#if 0
- /*
+ /*
* FIXME:
* Make the detection of the noexecute feature more portable.
*/
Ke386NoExecute = TRUE;
Ke386RestoreFlags(Flags);
}
- }
+ }
else
{
NoExecute=FALSE;
}
#endif
- Ke386Pae = Ke386GetCr4() & X86_CR4_PAE ? TRUE : FALSE;
-#if 0
+ Ke386Pae = Ke386GetCr4() & X86_CR4_PAE ? TRUE : FALSE;
+#if 0
/* Enable PAE mode */
if ((Pae && (KPCR->PrcbData.FeatureBits & X86_FEATURE_PAE)) || NoExecute)
{
}
}
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
+NTAPI
KeInit2(VOID)
{
- PKPCR Pcr = KeGetCurrentKPCR();
+ PKIPCR Pcr = (PKIPCR)KeGetCurrentKPCR();
KiInitializeBugCheck();
KeInitializeDispatcher();
VOID INIT_FUNCTION
Ki386SetProcessorFeatures(VOID)
{
- PKPCR Pcr = KeGetCurrentKPCR();
+ PKIPCR Pcr = (PKIPCR)KeGetCurrentKPCR();
OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING KeyName;
- UNICODE_STRING ValueName;
+ UNICODE_STRING KeyName =
+ RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\Kernel");
+ UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"FastSystemCallDisable");
HANDLE KeyHandle;
ULONG ResultLength;
KEY_VALUE_PARTIAL_INFORMATION ValueData;
(Pcr->PrcbData.FeatureBits & X86_FEATURE_MMX);
SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE;
SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE;
- SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
+ SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE);
SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
(Ke386CpuidExFlags & X86_EXT_FEATURE_3DNOW);
/* Does the CPU Support Fast System Call? */
if (Pcr->PrcbData.FeatureBits & X86_FEATURE_SYSCALL) {
-
+
/* FIXME: Check for Family == 6, Model < 3 and Stepping < 3 and disable */
-
+
/* Make sure it's not disabled in registry */
- RtlRosInitUnicodeStringFromLiteral(&KeyName,
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\Kernel");
- RtlRosInitUnicodeStringFromLiteral(&ValueName,
- L"FastSystemCallDisable");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes);
-
+
if (NT_SUCCESS(Status)) {
-
+
/* Read the Value then Close the Key */
Status = NtQueryValueKey(KeyHandle,
&ValueName,
sizeof(ValueData),
&ResultLength);
RtlMoveMemory(&FastSystemCallDisable, ValueData.Data, sizeof(ULONG));
-
+
NtClose(KeyHandle);
}
-
+
} else {
-
+
/* Disable SYSENTER/SYSEXIT, because the CPU doesn't support it */
FastSystemCallDisable = 1;
-
+
}
-
+
if (FastSystemCallDisable) {
-
- /* Use INT2E */
- SharedUserData->SystemCall[0] = 0x8D;
- SharedUserData->SystemCall[1] = 0x54;
- SharedUserData->SystemCall[2] = 0x24;
- SharedUserData->SystemCall[3] = 0x08;
- SharedUserData->SystemCall[4] = 0xCD;
- SharedUserData->SystemCall[5] = 0x2E;
- SharedUserData->SystemCall[6] = 0xC3;
-
+ /* Use INT2E */
+ const unsigned char Entry[7] = {0x8D, 0x54, 0x24, 0x08, /* lea 0x8(%esp),%edx */
+ 0xCD, 0x2E, /* int 0x2e */
+ 0xC3}; /* ret */
+ memcpy(&SharedUserData->SystemCall, Entry, sizeof(Entry));
} else {
-
/* Use SYSENTER */
- SharedUserData->SystemCall[0] = 0x8B;
- SharedUserData->SystemCall[1] = 0xD4;
- SharedUserData->SystemCall[2] = 0x0F;
- SharedUserData->SystemCall[3] = 0x34;
- SharedUserData->SystemCall[4] = 0xC3;
-
+ const unsigned char Entry[5] = {0x8B, 0xD4, /* movl %esp,%edx */
+ 0x0F, 0x34, /* sysenter */
+ 0xC3}; /* ret */
+ memcpy(&SharedUserData->SystemCall, Entry, sizeof(Entry));
/* Enable SYSENTER/SYSEXIT */
KiFastSystemCallDisable = 0;
}