- Fix __rdtsc so it's considered volatile by GCC instead of caching it.

- Add NtInitialUserProcessBuffer settings and validate/user them when launching smss.
- Use SePublicDefaultUnrestrictedSd for the root system link.
- Make enough space for the smss process parameters, there's 6 strings, not 4.
- Fix incorrect length of NtSystemRoot string.
- Disable SYSENTER on CPUs that don't support it.
- Detect and enable NX feature bit.
- Detect and enable DTS support.
- Implement Ki386EnableXMMIExceptions (the XMMI handler still needs to be done, however).
- Implement KiI386PentiumLockErrataFixup to work around the F00F bug.
- Implement KiIsNpxErrataPresent to detect the FDIV bug.
- Implement CPU Speed detection.
- Only setup Initial FX State if the CPU supports FXSR.
- Setup some more PCR fields during init.
- Use NX_SUPPORT_POLICY flags documented in ntddk.h
- Don't boot if CMPXCHG8B is not supported by the CPU. This is the same requirement as Windows.
- Don't overwrite all the PRCB locks in KiInitSpinlocks due to a stupid bug in the timer spinlock initialization.

svn path=/trunk/; revision=25503
This commit is contained in:
Alex Ionescu 2007-01-18 06:23:14 +00:00
parent 8be76ffcb3
commit ccee43a360
13 changed files with 382 additions and 107 deletions

View file

@ -427,6 +427,11 @@ typedef struct _KSYSTEM_TIME
extern volatile KSYSTEM_TIME KeTickCount;
#define NX_SUPPORT_POLICY_ALWAYSOFF 0
#define NX_SUPPORT_POLICY_ALWAYSON 1
#define NX_SUPPORT_POLICY_OPTIN 2
#define NX_SUPPORT_POLICY_OPTOUT 3
typedef struct _KUSER_SHARED_DATA
{
ULONG TickCountLowDeprecated;

View file

@ -39,6 +39,11 @@ Author:
//
#define SSDT_MAX_ENTRIES 2
//
// Processor Architectures
//
#define PROCESSOR_ARCHITECTURE_INTEL 0
//
// Object Type Mask for Kernel Dispatcher Objects
//
@ -87,8 +92,10 @@ Author:
#define KF_3DNOW 0x00004000
#define KF_AMDK6MTRR 0x00008000
#define KF_XMMI64 0x00010000
#define KF_NX_DISABLED 0x00400000
#define KF_NX_ENABLED 0x00800000
#define KF_DTS 0x00020000
#define KF_NX_BIT 0x20000000
#define KF_NX_DISABLED 0x40000000
#define KF_NX_ENABLED 0x80000000
//
// KPCR Access for non-IA64 builds

View file

@ -930,7 +930,7 @@ static __inline__ __attribute__((always_inline)) unsigned long long __rdtsc(void
unsigned long lo32;
unsigned long hi32;
__asm__("rdtsc" : "=a" (lo32), "=d" (hi32));
__asm__ __volatile__("rdtsc" : "=a" (lo32), "=d" (hi32));
{
union u_

View file

@ -9,7 +9,6 @@
// Failure to respect this will *ACHIEVE NOTHING*.
//
// Ke1:
// - Implement KiInitMachineDependent.
// - Implement Privileged Instruction Handler in Umode GPF.
//
// Ex:
@ -28,10 +27,6 @@
// Kd:
// - Implement KD Kernel Debugging and WinDBG support.
//
// Native:
// - Rewrite loader.
// - Make smss NT-compatible.
//
///////////////////////////////////////////////////////////////////////////////
// REACTOS GUIDANCE PLAN

View file

@ -39,6 +39,12 @@ BOOLEAN NoGuiBoot = FALSE;
/* NT Boot Path */
UNICODE_STRING NtSystemRoot;
/* NT Initial User Application */
WCHAR NtInitialUserProcessBuffer[128] = L"\\SystemRoot\\System32\\smss.exe";
ULONG NtInitialUserProcessBufferLength = sizeof(NtInitialUserProcessBuffer) -
sizeof(WCHAR);
ULONG NtInitialUserProcessBufferType = REG_SZ;
/* Boot NLS information */
PVOID ExpNlsTableBase;
ULONG ExpAnsiCodePageDataOffset, ExpOemCodePageDataOffset;
@ -68,7 +74,7 @@ ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
&LinkName,
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
NULL,
SePublicDefaultSd);
SePublicDefaultUnrestrictedSd);
/* Create it */
Status = NtCreateDirectoryObject(&LinkHandle,
@ -88,7 +94,7 @@ ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
&LinkName,
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
NULL,
SePublicDefaultSd);
SePublicDefaultUnrestrictedSd);
/* Create it */
Status = NtCreateDirectoryObject(&LinkHandle,
@ -115,7 +121,7 @@ ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
&LinkName,
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
NULL,
SePublicDefaultSd);
SePublicDefaultUnrestrictedSd);
/* Build the ARC name */
sprintf(Buffer,
@ -353,10 +359,11 @@ ExpLoadInitialProcess(IN PHANDLE ProcessHandle,
PWSTR p;
UNICODE_STRING NullString = RTL_CONSTANT_STRING(L"");
UNICODE_STRING SmssName, Environment, SystemDriveString;
PVOID EnvironmentPtr = NULL;
/* Allocate memory for the process parameters */
Size = sizeof(RTL_USER_PROCESS_PARAMETERS) +
((MAX_PATH * 4) * sizeof(WCHAR));
((MAX_PATH * 6) * sizeof(WCHAR));
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
(PVOID)&ProcessParameters,
0,
@ -378,7 +385,7 @@ ExpLoadInitialProcess(IN PHANDLE ProcessHandle,
/* Allocate a page for the environment */
Size = PAGE_SIZE;
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
(PVOID)&ProcessParameters->Environment,
&EnvironmentPtr,
0,
&Size,
MEM_COMMIT,
@ -389,6 +396,9 @@ ExpLoadInitialProcess(IN PHANDLE ProcessHandle,
KeBugCheckEx(SESSION2_INITIALIZATION_FAILED, Status, 0, 0, 0);
}
/* Write the pointer */
ProcessParameters->Environment = EnvironmentPtr;
/* Make a buffer for the DOS path */
p = (PWSTR)(ProcessParameters + 1);
ProcessParameters->CurrentDirectory.DosPath.Buffer = p;
@ -416,11 +426,48 @@ ExpLoadInitialProcess(IN PHANDLE ProcessHandle,
ProcessParameters->ImagePathName.Buffer = p;
ProcessParameters->ImagePathName.MaximumLength = MAX_PATH * sizeof(WCHAR);
/* Append the system path and session manager name */
RtlAppendUnicodeToString(&ProcessParameters->ImagePathName,
L"\\SystemRoot\\System32");
RtlAppendUnicodeToString(&ProcessParameters->ImagePathName,
L"\\smss.exe");
/* Make sure the buffer is a valid string which within the given length */
if ((NtInitialUserProcessBufferType != REG_SZ) ||
((NtInitialUserProcessBufferLength != -1) &&
((NtInitialUserProcessBufferLength < sizeof(WCHAR)) ||
(NtInitialUserProcessBufferLength >
sizeof(NtInitialUserProcessBuffer) - sizeof(WCHAR)))))
{
/* Invalid initial process string, bugcheck */
KeBugCheckEx(SESSION2_INITIALIZATION_FAILED,
(ULONG_PTR)STATUS_INVALID_PARAMETER,
NtInitialUserProcessBufferType,
NtInitialUserProcessBufferLength,
sizeof(NtInitialUserProcessBuffer));
}
/* Cut out anything after a space */
p = NtInitialUserProcessBuffer;
while (*p && *p != L' ') p++;
/* Set the image path length */
ProcessParameters->ImagePathName.Length =
(USHORT)((PCHAR)p - (PCHAR)NtInitialUserProcessBuffer);
/* Copy the actual buffer */
RtlCopyMemory(ProcessParameters->ImagePathName.Buffer,
NtInitialUserProcessBuffer,
ProcessParameters->ImagePathName.Length);
/* Null-terminate it */
ProcessParameters->
ImagePathName.Buffer[ProcessParameters->ImagePathName.Length /
sizeof(WCHAR)] = UNICODE_NULL;
/* Make a buffer for the command line */
p = (PWSTR)((PCHAR)ProcessParameters->ImagePathName.Buffer +
ProcessParameters->ImagePathName.MaximumLength);
ProcessParameters->CommandLine.Buffer = p;
ProcessParameters->CommandLine.MaximumLength = MAX_PATH * sizeof(WCHAR);
/* Add the image name to the command line */
RtlAppendUnicodeToString(&ProcessParameters->CommandLine,
NtInitialUserProcessBuffer);
/* Create the environment string */
RtlInitEmptyUnicodeString(&Environment,
@ -446,11 +493,8 @@ ExpLoadInitialProcess(IN PHANDLE ProcessHandle,
RtlAppendUnicodeStringToString(&Environment, &NtSystemRoot);
RtlAppendUnicodeStringToString(&Environment, &NullString);
/* Get and set the command line equal to the image path */
ProcessParameters->CommandLine = ProcessParameters->ImagePathName;
SmssName = ProcessParameters->ImagePathName;
/* Create SMSS process */
SmssName = ProcessParameters->ImagePathName;
Status = RtlCreateUserProcess(&SmssName,
OBJ_CASE_INSENSITIVE,
RtlDeNormalizeProcessParams(
@ -731,9 +775,9 @@ ExpInitializeExecutive(IN ULONG Cpu,
Buffer[--AnsiPath.Length] = ANSI_NULL;
/* Get the string from KUSER_SHARED_DATA's buffer */
NtSystemRoot.Buffer = SharedUserData->NtSystemRoot;
NtSystemRoot.MaximumLength = sizeof(SharedUserData->NtSystemRoot) / sizeof(WCHAR);
NtSystemRoot.Length = 0;
RtlInitEmptyUnicodeString(&NtSystemRoot,
SharedUserData->NtSystemRoot,
sizeof(SharedUserData->NtSystemRoot));
/* Now fill it in */
Status = RtlAnsiStringToUnicodeString(&NtSystemRoot, &AnsiPath, FALSE);
@ -960,19 +1004,17 @@ ExPhase2Init(PVOID Context)
/* Bugcheck the system if SMSS couldn't initialize */
KeBugCheck(SESSION5_INITIALIZATION_FAILED);
}
else
{
/* Close process handles */
ZwClose(ThreadHandle);
ZwClose(ProcessHandle);
/* FIXME: We should free the initial process' memory!*/
/* Close process handles */
ZwClose(ThreadHandle);
ZwClose(ProcessHandle);
/* Increase init phase */
ExpInitializationPhase += 1;
/* FIXME: We should free the initial process' memory!*/
/* Jump into zero page thread */
MmZeroPageThreadMain(NULL);
}
/* Increase init phase */
ExpInitializationPhase += 1;
/* Jump into zero page thread */
MmZeroPageThreadMain(NULL);
}
/* EOF */

View file

@ -92,6 +92,12 @@ KiIsNpxPresent(
VOID
);
BOOLEAN
NTAPI
KiIsNpxErrataPresent(
VOID
);
VOID
NTAPI
KiSetProcessorType(VOID);

View file

@ -37,6 +37,18 @@ typedef struct _DISPATCH_INFO
PKINTERRUPT_ROUTINE *FlatDispatch;
} DISPATCH_INFO, *PDISPATCH_INFO;
typedef struct _KI_SAMPLE_MAP
{
LARGE_INTEGER PerfStart;
LARGE_INTEGER PerfEnd;
LONGLONG PerfDelta;
LARGE_INTEGER PerfFreq;
LONGLONG TSCStart;
LONGLONG TSCEnd;
LONGLONG TSCDelta;
ULONG MHz;
} KI_SAMPLE_MAP, *PKI_SAMPLE_MAP;
typedef struct _KTIMER_TABLE_ENTRY
{
LIST_ENTRY Entry;
@ -113,7 +125,7 @@ extern KSPIN_LOCK BugCheckCallbackLock;
extern KDPC KiExpireTimerDpc;
extern KTIMER_TABLE_ENTRY KiTimerTableListHead[TIMER_TABLE_SIZE];
extern LIST_ENTRY KiTimerListHead;
extern KMUTEX KiGenericCallDpcMutex;
extern FAST_MUTEX KiGenericCallDpcMutex;
extern LIST_ENTRY KiProfileListHead, KiProfileSourceListHead;
extern KSPIN_LOCK KiProfileLock;
extern LIST_ENTRY KiProcessListHead;
@ -235,6 +247,13 @@ KiSelectNextThread(
IN PKPRCB Prcb
);
VOID
NTAPI
CPUID(
OUT ULONG CpuInfo[4],
IN ULONG InfoType
);
/* gmutex.c ********************************************************************/
VOID

View file

@ -23,7 +23,7 @@ ULONG KiMinimumDpcRate = 3;
ULONG KiAdjustDpcThreshold = 20;
ULONG KiIdealDpcRate = 20;
BOOLEAN KeThreadDpcEnable;
KMUTEX KiGenericCallDpcMutex;
FAST_MUTEX KiGenericCallDpcMutex;
/* PRIVATE FUNCTIONS *********************************************************/

View file

@ -340,6 +340,14 @@ KiGetFeatureBits(VOID)
FeatureBits &= ~KF_WORKING_PTE;
}
/* Check if the CPU is too old to support SYSENTER */
if ((Prcb->CpuType < 6) ||
((Prcb->CpuType == 6) && (Prcb->CpuStep < 0x0303)))
{
/* Disable it */
Reg[3] &= ~0x800;
}
/* Set the current features */
CpuFeatures = Reg[3];
}
@ -354,6 +362,7 @@ KiGetFeatureBits(VOID)
if (CpuFeatures & 0x00002000) FeatureBits |= KF_GLOBAL_PAGE | KF_CR4;
if (CpuFeatures & 0x00008000) FeatureBits |= KF_CMOV;
if (CpuFeatures & 0x00010000) FeatureBits |= KF_PAT;
if (CpuFeatures & 0x00200000) FeatureBits |= KF_DTS;
if (CpuFeatures & 0x00800000) FeatureBits |= KF_MMX;
if (CpuFeatures & 0x01000000) FeatureBits |= KF_FXSR;
if (CpuFeatures & 0x02000000) FeatureBits |= KF_XMMI;
@ -389,6 +398,9 @@ KiGetFeatureBits(VOID)
/* Check which extended features are available. */
CPUID(Reg, 0x80000001);
/* Check if NX-bit is supported */
if (Reg[3] & 0x00100000) FeatureBits |= KF_NX_BIT;
/* Now handle each features for each CPU Vendor */
switch (Vendor)
{
@ -741,8 +753,23 @@ ULONG_PTR
NTAPI
Ki386EnableXMMIExceptions(IN ULONG_PTR Context)
{
/* FIXME: Support this */
DPRINT1("Your machine supports XMMI exceptions but ReactOS doesn't\n");
#if 0 // needs kitrap13
PKIDTENTRY IdtEntry;
/* Get the IDT Entry for Interrupt 19 */
IdtEntry = ((PKIPCR)KeGetPcr())->IDT[19];
/* Set it up */
IdtEntry->Selector = KGDT_R0_CODE;
IdtEntry->Offset = (KiTrap13 & 0xFFFF);
IdtEntry->ExtendedOffset = (KiTrap13 >> 16) & 0xFFFF;
((PKIDT_ACCESS)&IdtEntry->Access)->Dpl = 0;
((PKIDT_ACCESS)&IdtEntry->Access)->Present = 1;
((PKIDT_ACCESS)&IdtEntry->Access)->SegmentType = I386_INTERRUPT_GATE;
#endif
/* Enable XMMI exceptions */
__writecr4(__readcr4() | CR4_XMMEXCPT);
return 0;
}
@ -750,8 +777,34 @@ VOID
NTAPI
KiI386PentiumLockErrataFixup(VOID)
{
/* FIXME: Support this */
DPRINT1("WARNING: Your machine has a CPU bug that ReactOS can't bypass!\n");
KDESCRIPTOR IdtDescriptor;
PKIDTENTRY NewIdt, NewIdt2;
/* Allocate memory for a new IDT */
NewIdt = ExAllocatePool(NonPagedPool, 2 * PAGE_SIZE);
/* Put everything after the first 7 entries on a new page */
NewIdt2 = (PVOID)((ULONG_PTR)NewIdt + PAGE_SIZE - (7 * sizeof(KIDTENTRY)));
/* Disable interrupts */
_disable();
/* Get the current IDT and copy it */
Ke386GetInterruptDescriptorTable(IdtDescriptor);
RtlCopyMemory(NewIdt2,
(PVOID)IdtDescriptor.Base,
IdtDescriptor.Limit + 1);
IdtDescriptor.Base = (ULONG)NewIdt2;
/* Set the new IDT */
Ke386SetInterruptDescriptorTable(IdtDescriptor);
((PKIPCR)KeGetPcr())->IDT = NewIdt2;
/* Restore interrupts */
_enable();
/* Set the first 7 entries as read-only to produce a fault */
MmSetPageProtect(NULL, NewIdt, PAGE_READONLY);
}
/* PUBLIC FUNCTIONS **********************************************************/

View file

@ -17,8 +17,56 @@
#define Running 2
#define WrDispatchInt 0x1F
Dividend: .float 4195835.0
Divisor: .float 3145727.0
Result1: .float 0
Result2: .float 0
/* FUNCTIONS ****************************************************************/
.globl _KiIsNpxErrataPresent@0
.func KiIsNpxErrataPresent@0
_KiIsNpxErrataPresent@0:
/* Disable interrupts */
cli
/* Get CR0 and mask out FPU flags */
mov eax, cr0
mov ecx, eax
and eax, ~(CR0_MP + CR0_TS + CR0_EM)
mov cr0, eax
/* Initialize the FPU */
fninit
/* Do the divison and inverse multiplication */
fld qword ptr Dividend
fstp qword ptr Result1
fld qword ptr Divisor
fstp qword ptr Result2
fld qword ptr Result1
fdiv qword ptr Result2
fmul qword ptr Result2
/* Do the compare and check flags */
fcomp qword ptr Result1
fstsw ax
sahf
/* Restore CR0 and interrupts */
mov cr0, ecx
sti
/* Return errata status */
xor eax, eax
jz NoErrata
inc eax
NoErrata:
ret
.endfunc
.globl _KiIsNpxPresent@0
.func KiIsNpxPresent@0
_KiIsNpxPresent@0:

View file

@ -30,15 +30,18 @@ KiInitMachineDependent(VOID)
BOOLEAN FbCaching = FALSE;
NTSTATUS Status;
ULONG ReturnLength;
ULONG i, Affinity;
ULONG i, Affinity, Sample = 0;
PFX_SAVE_AREA FxSaveArea;
ULONG MXCsrMask = 0xFFBF, NewMask;
ULONG MXCsrMask = 0xFFBF;
ULONG Dummy[4];
KI_SAMPLE_MAP Samples[4];
PKI_SAMPLE_MAP CurrentSample = Samples;
/* Check for large page support */
if (KeFeatureBits & KF_LARGE_PAGE)
{
/* FIXME: Support this */
DPRINT1("Your machine supports PGE but ReactOS doesn't yet.\n");
DPRINT1("Large Page support detected but not yet taken advantage of!\n");
}
/* Check for global page support */
@ -70,6 +73,34 @@ KiInitMachineDependent(VOID)
/* Assume no errata for now */
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = 0;
/* Check if we have an NPX */
if (KeI386NpxPresent)
{
/* Loop every CPU */
i = KeActiveProcessors;
for (Affinity = 1; i; Affinity <<= 1)
{
/* Check if this is part of the set */
if (i & Affinity)
{
/* Run on this CPU */
i &= ~Affinity;
KeSetSystemAffinityThread(Affinity);
/* Detect FPU errata */
if (KiIsNpxErrataPresent())
{
/* Disable NPX support */
KeI386NpxPresent = FALSE;
SharedUserData->
ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] =
TRUE;
break;
}
}
}
}
/* If there's no NPX, then we're emulating the FPU */
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] =
!KeI386NpxPresent;
@ -148,18 +179,66 @@ KiInitMachineDependent(VOID)
/* Start sampling loop */
for (;;)
{
//
// FIXME: TODO
//
break;
/* Do a dummy CPUID to start the sample */
CPUID(Dummy, 0);
/* Fill out the starting data */
CurrentSample->PerfStart = KeQueryPerformanceCounter(NULL);
CurrentSample->TSCStart = __rdtsc();
CurrentSample->PerfFreq.QuadPart = -50000;
/* Sleep for this sample */
KeDelayExecutionThread(KernelMode,
FALSE,
&CurrentSample->PerfFreq);
/* Do another dummy CPUID */
CPUID(Dummy, 0);
/* Fill out the ending data */
CurrentSample->PerfEnd =
KeQueryPerformanceCounter(&CurrentSample->PerfFreq);
CurrentSample->TSCEnd = __rdtsc();
/* Calculate the differences */
CurrentSample->PerfDelta = CurrentSample->PerfEnd.QuadPart -
CurrentSample->PerfStart.QuadPart;
CurrentSample->TSCDelta = CurrentSample->TSCEnd -
CurrentSample->TSCStart;
/* Compute CPU Speed */
CurrentSample->MHz = ((CurrentSample->TSCDelta *
CurrentSample->PerfFreq.QuadPart +
500000) /
(CurrentSample->PerfDelta * 1000000));
/* Check if this isn't the first sample */
if (Sample)
{
/* Check if we got a good precision within 1MHz */
if ((CurrentSample->MHz == CurrentSample[-1].MHz) ||
(CurrentSample->MHz == CurrentSample[-1].MHz + 1) ||
(CurrentSample->MHz == CurrentSample[-1].MHz - 1))
{
/* We did, stop sampling */
break;
}
}
/* Move on */
CurrentSample++;
Sample++;
}
/* Save the CPU Speed */
KeGetCurrentPrcb()->MHz = CurrentSample[-1].MHz;
}
/* Check if we have MTRR without PAT */
if (!(KeFeatureBits & KF_PAT) && (KeFeatureBits & KF_MTRR))
/* Check if we have MTRR */
if (KeFeatureBits & KF_MTRR)
{
/* Then manually initialize MTRR for the CPU */
KiInitializeMTRR((BOOLEAN)i);
KiInitializeMTRR((BOOLEAN)i ? FALSE : TRUE);
}
/* Check if we have AMD MTRR and initialize it for the CPU */
@ -168,52 +247,53 @@ KiInitMachineDependent(VOID)
/* Check if this is a buggy Pentium and apply the fixup if so */
if (KiI386PentiumLockErrataPresent) KiI386PentiumLockErrataFixup();
/* Get the current thread NPX state */
FxSaveArea = (PVOID)
((ULONG_PTR)KeGetCurrentThread()->InitialStack -
NPX_FRAME_LENGTH);
/* Check if the CPU supports FXSR */
if (KeFeatureBits & KF_FXSR)
{
/* Get the current thread NPX state */
FxSaveArea = (PVOID)
((ULONG_PTR)KeGetCurrentThread()->InitialStack -
NPX_FRAME_LENGTH);
/* Clear initial MXCsr mask */
FxSaveArea->U.FxArea.MXCsrMask = 0;
/* Clear initial MXCsr mask */
FxSaveArea->U.FxArea.MXCsrMask = 0;
/* Save the current NPX State */
/* Save the current NPX State */
#ifdef __GNUC__
asm volatile("fxsave %0\n\t" : "=m" (*FxSaveArea));
asm volatile("fxsave %0\n\t" : "=m" (*FxSaveArea));
#else
__asm fxsave [FxSaveArea]
__asm fxsave [FxSaveArea]
#endif
/* Check if the current mask doesn't match the reserved bits */
if (FxSaveArea->U.FxArea.MXCsrMask != MXCsrMask)
{
/* Then use whatever it's holding */
MXCsrMask = FxSaveArea->U.FxArea.MXCsrMask;
}
/* Check if nobody set the kernel-wide mask */
if (!KiMXCsrMask)
{
/* Then use the one we calculated above */
NewMask = MXCsrMask;
}
else
{
/* Use the existing mask */
NewMask = KiMXCsrMask;
/* Was it set to the same value we found now? */
if (NewMask != MXCsrMask)
/* Check if the current mask doesn't match the reserved bits */
if (FxSaveArea->U.FxArea.MXCsrMask != 0)
{
/* No, something is definitely wrong */
KEBUGCHECKEX(MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED,
KF_FXSR,
NewMask,
MXCsrMask,
0);
/* Then use whatever it's holding */
MXCsrMask = FxSaveArea->U.FxArea.MXCsrMask;
}
}
/* Now set the kernel mask */
KiMXCsrMask = NewMask & MXCsrMask;
/* Check if nobody set the kernel-wide mask */
if (!KiMXCsrMask)
{
/* Then use the one we calculated above */
KiMXCsrMask = MXCsrMask;
}
else
{
/* Was it set to the same value we found now? */
if (KiMXCsrMask != MXCsrMask)
{
/* No, something is definitely wrong */
KEBUGCHECKEX(MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED,
KF_FXSR,
KiMXCsrMask,
MXCsrMask,
0);
}
}
/* Now set the kernel mask */
KiMXCsrMask &= MXCsrMask;
}
}
}
@ -242,7 +322,7 @@ KiInitializePcr(IN ULONG ProcessorNumber,
Pcr->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
Pcr->NtTib.StackBase = 0;
Pcr->NtTib.StackLimit = 0;
Pcr->NtTib.Self = 0;
Pcr->NtTib.Self = NULL;
/* Set the Current Thread */
Pcr->PrcbData.CurrentThread = IdleThread;
@ -282,7 +362,11 @@ KiInitializePcr(IN ULONG ProcessorNumber,
Pcr->GDT = (PVOID)Gdt;
Pcr->IDT = Idt;
Pcr->TSS = Tss;
Pcr->TssCopy = Tss;
Pcr->PrcbData.DpcStack = DpcStack;
/* Setup the processor set */
Pcr->PrcbData.MultiThreadProcessorSet = Pcr->PrcbData.SetMember;
}
VOID
@ -299,6 +383,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
LARGE_INTEGER PageDirectory;
PVOID DpcStack;
ULONG NXSupportPolicy;
ULONG Vendor[3];
/* Detect and set the CPU Type */
KiSetProcessorType();
@ -319,19 +404,19 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
FeatureBits = KiGetFeatureBits();
/* Set the default NX policy (opt-in) */
NXSupportPolicy = 2;
NXSupportPolicy = NX_SUPPORT_POLICY_OPTIN;
/* Check if NPX is always on */
if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSON"))
{
/* Set it always on */
NXSupportPolicy = 1;
NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSON;
FeatureBits |= KF_NX_ENABLED;
}
else if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTOUT"))
{
/* Set it in opt-out mode */
NXSupportPolicy = 3;
NXSupportPolicy = NX_SUPPORT_POLICY_OPTOUT;
FeatureBits |= KF_NX_ENABLED;
}
else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTIN")) ||
@ -344,7 +429,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
(strstr(KeLoaderBlock->LoadOptions, "EXECUTE")))
{
/* Set disabled mode */
NXSupportPolicy = 0;
NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSOFF;
FeatureBits |= KF_NX_DISABLED;
}
@ -372,18 +457,32 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
KeI386NpxPresent = NpxPresent;
KeI386CpuType = Prcb->CpuType;
KeI386CpuStep = Prcb->CpuStep;
KeProcessorArchitecture = 0;
KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
KeProcessorLevel = (USHORT)Prcb->CpuType;
if (Prcb->CpuID) KeProcessorRevision = Prcb->CpuStep;
KeFeatureBits = FeatureBits;
KeI386FxsrPresent = (KeFeatureBits & KF_FXSR) ? TRUE : FALSE;
KeI386XMMIPresent = (KeFeatureBits & KF_XMMI) ? TRUE : FALSE;
/* Detect 8-byte compare exchange support */
if (!(KeFeatureBits & KF_CMPXCHG8B))
{
/* Copy the vendor string */
RtlCopyMemory(Vendor, Prcb->VendorString, sizeof(Vendor));
/* Bugcheck the system. Windows *requires* this */
KeBugCheckEx(0x5D,
(1 << 24 ) | (Prcb->CpuType << 16) | Prcb->CpuStep,
Vendor[0],
Vendor[1],
Vendor[2]);
}
/* Set the current MP Master KPRCB to the Boot PRCB */
Prcb->MultiThreadSetMaster = Prcb;
/* Lower to APC_LEVEL */
KfLowerIrql(APC_LEVEL);
KeLowerIrql(APC_LEVEL);
/* Initialize some spinlocks */
KeInitializeSpinLock(&KiFreezeExecutionLock);
@ -499,7 +598,9 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
KeSetPriorityThread(InitThread, 0);
/* If there's no thread scheduled, put this CPU in the Idle summary */
KiAcquirePrcbLock(Prcb);
if (!Prcb->NextThread) KiIdleSummary |= 1 << Number;
KiReleasePrcbLock(Prcb);
/* Raise back to HIGH_LEVEL and clear the PRCB for the loader block */
KfRaiseIrql(HIGH_LEVEL);
@ -683,11 +784,6 @@ AppCpuInit:
/* Set the right wait IRQL */
KeGetCurrentThread()->WaitIrql = DISPATCH_LEVEL;
/* Set idle thread as running on UP builds */
#ifndef CONFIG_SMP
KeGetCurrentThread()->State = Running;
#endif
/* Jump into the idle loop */
KiIdleLoop();
}

View file

@ -59,5 +59,5 @@ NTAPI
KiInitializePAT(VOID)
{
/* FIXME: Support this */
DPRINT1("Your machine supports PAT but ReactOS doesn't yet.\n");
DPRINT1("Advanced Memory features detected but not yet taken advantage of.\n");
}

View file

@ -94,7 +94,7 @@ KiInitSystem(VOID)
InitializeListHead(&KiStackInSwapListHead);
/* Initialize the mutex for generic DPC calls */
KeInitializeMutex(&KiGenericCallDpcMutex, 0);
ExInitializeFastMutex(&KiGenericCallDpcMutex);
/* Initialize the syscall table */
KeServiceDescriptorTable[0].Base = MainSSDT;
@ -183,7 +183,7 @@ KiInitSpinLocks(IN PKPRCB Prcb,
Prcb->QueueIndex = 1;
Prcb->ReadySummary = 0;
Prcb->DeferredReadyListHead.Next = NULL;
for (i = 0; i < 32; i++)
for (i = 0; i < MAXIMUM_PRIORITY; i++)
{
/* Initialize the ready list */
InitializeListHead(&Prcb->DispatcherReadyListHead[i]);
@ -246,10 +246,14 @@ KiInitSpinLocks(IN PKPRCB Prcb,
{
/* Initialize the lock and setup the Queued Spinlock */
KeInitializeSpinLock(&KiTimerTableLock[i]);
Prcb->LockQueue[i].Next = NULL;
Prcb->LockQueue[i].Lock = &KiTimerTableLock[i];
Prcb->LockQueue[LockQueueTimerTableLock + i].Next = NULL;
Prcb->LockQueue[LockQueueTimerTableLock + i].Lock =
&KiTimerTableLock[i];
}
/* Initialize the PRCB lock */
KeInitializeSpinLock(&Prcb->PrcbLock);
/* Check if this is the boot CPU */
if (!Number)
{