Author: ion
Date: Thu Jan 18 09:23:14 2007
New Revision: 25503
URL:
http://svn.reactos.org/svn/reactos?rev=25503&view=rev
Log:
- 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.
Modified:
trunk/reactos/include/ddk/winddk.h
trunk/reactos/include/ndk/ketypes.h
trunk/reactos/include/psdk/intrin.h
trunk/reactos/ntoskrnl/KrnlFun.c
trunk/reactos/ntoskrnl/ex/init.c
trunk/reactos/ntoskrnl/include/internal/i386/ke.h
trunk/reactos/ntoskrnl/include/internal/ke.h
trunk/reactos/ntoskrnl/ke/dpc.c
trunk/reactos/ntoskrnl/ke/i386/cpu.c
trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S
trunk/reactos/ntoskrnl/ke/i386/kiinit.c
trunk/reactos/ntoskrnl/ke/i386/patpge.c
trunk/reactos/ntoskrnl/ke/krnlinit.c
Modified: trunk/reactos/include/ddk/winddk.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/winddk.h?rev=2…
==============================================================================
--- trunk/reactos/include/ddk/winddk.h (original)
+++ trunk/reactos/include/ddk/winddk.h Thu Jan 18 09:23:14 2007
@@ -426,6 +426,11 @@
} KSYSTEM_TIME, *PKSYSTEM_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
{
Modified: trunk/reactos/include/ndk/ketypes.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/ketypes.h?rev=…
==============================================================================
--- trunk/reactos/include/ndk/ketypes.h (original)
+++ trunk/reactos/include/ndk/ketypes.h Thu Jan 18 09:23:14 2007
@@ -38,6 +38,11 @@
// Maximum System Descriptor Table Entries
//
#define SSDT_MAX_ENTRIES 2
+
+//
+// Processor Architectures
+//
+#define PROCESSOR_ARCHITECTURE_INTEL 0
//
// Object Type Mask for Kernel Dispatcher Objects
@@ -87,8 +92,10 @@
#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
Modified: trunk/reactos/include/psdk/intrin.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/intrin.h?rev=…
==============================================================================
--- trunk/reactos/include/psdk/intrin.h (original)
+++ trunk/reactos/include/psdk/intrin.h Thu Jan 18 09:23:14 2007
@@ -930,7 +930,7 @@
unsigned long lo32;
unsigned long hi32;
- __asm__("rdtsc" : "=a" (lo32), "=d" (hi32));
+ __asm__ __volatile__("rdtsc" : "=a" (lo32), "=d"
(hi32));
{
union u_
Modified: trunk/reactos/ntoskrnl/KrnlFun.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/KrnlFun.c?rev=255…
==============================================================================
--- trunk/reactos/ntoskrnl/KrnlFun.c (original)
+++ trunk/reactos/ntoskrnl/KrnlFun.c Thu Jan 18 09:23:14 2007
@@ -9,7 +9,6 @@
// Failure to respect this will *ACHIEVE NOTHING*.
//
// Ke1:
-// - Implement KiInitMachineDependent.
// - Implement Privileged Instruction Handler in Umode GPF.
//
// Ex:
@@ -27,10 +26,6 @@
//
// Kd:
// - Implement KD Kernel Debugging and WinDBG support.
-//
-// Native:
-// - Rewrite loader.
-// - Make smss NT-compatible.
//
///////////////////////////////////////////////////////////////////////////////
Modified: trunk/reactos/ntoskrnl/ex/init.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/init.c?rev=255…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/init.c (original)
+++ trunk/reactos/ntoskrnl/ex/init.c Thu Jan 18 09:23:14 2007
@@ -38,6 +38,12 @@
/* 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;
@@ -68,7 +74,7 @@
&LinkName,
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
NULL,
- SePublicDefaultSd);
+ SePublicDefaultUnrestrictedSd);
/* Create it */
Status = NtCreateDirectoryObject(&LinkHandle,
@@ -88,7 +94,7 @@
&LinkName,
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
NULL,
- SePublicDefaultSd);
+ SePublicDefaultUnrestrictedSd);
/* Create it */
Status = NtCreateDirectoryObject(&LinkHandle,
@@ -115,7 +121,7 @@
&LinkName,
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
NULL,
- SePublicDefaultSd);
+ SePublicDefaultUnrestrictedSd);
/* Build the ARC name */
sprintf(Buffer,
@@ -353,10 +359,11 @@
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 @@
/* Allocate a page for the environment */
Size = PAGE_SIZE;
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
- (PVOID)&ProcessParameters->Environment,
+ &EnvironmentPtr,
0,
&Size,
MEM_COMMIT,
@@ -388,6 +395,9 @@
/* Failed */
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);
@@ -416,11 +426,48 @@
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 @@
RtlAppendUnicodeStringToString(&Environment, &NtSystemRoot);
RtlAppendUnicodeStringToString(&Environment, &NullString);
- /* Get and set the command line equal to the image path */
- ProcessParameters->CommandLine = ProcessParameters->ImagePathName;
+ /* Create SMSS process */
SmssName = ProcessParameters->ImagePathName;
-
- /* Create SMSS process */
Status = RtlCreateUserProcess(&SmssName,
OBJ_CASE_INSENSITIVE,
RtlDeNormalizeProcessParams(
@@ -731,9 +775,9 @@
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 @@
/* 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!*/
-
- /* Increase init phase */
- ExpInitializationPhase += 1;
-
- /* Jump into zero page thread */
- MmZeroPageThreadMain(NULL);
- }
+
+ /* Close process handles */
+ ZwClose(ThreadHandle);
+ ZwClose(ProcessHandle);
+
+ /* FIXME: We should free the initial process' memory!*/
+
+ /* Increase init phase */
+ ExpInitializationPhase += 1;
+
+ /* Jump into zero page thread */
+ MmZeroPageThreadMain(NULL);
}
/* EOF */
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/i386/ke.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/i386/ke.h Thu Jan 18 09:23:14 2007
@@ -92,6 +92,12 @@
VOID
);
+BOOLEAN
+NTAPI
+KiIsNpxErrataPresent(
+ VOID
+);
+
VOID
NTAPI
KiSetProcessorType(VOID);
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h Thu Jan 18 09:23:14 2007
@@ -36,6 +36,18 @@
PKINTERRUPT_ROUTINE ChainedDispatch;
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
{
@@ -113,7 +125,7 @@
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 @@
IN PKPRCB Prcb
);
+VOID
+NTAPI
+CPUID(
+ OUT ULONG CpuInfo[4],
+ IN ULONG InfoType
+);
+
/* gmutex.c ********************************************************************/
VOID
Modified: trunk/reactos/ntoskrnl/ke/dpc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/dpc.c?rev=2550…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/dpc.c (original)
+++ trunk/reactos/ntoskrnl/ke/dpc.c Thu Jan 18 09:23:14 2007
@@ -23,7 +23,7 @@
ULONG KiAdjustDpcThreshold = 20;
ULONG KiIdealDpcRate = 20;
BOOLEAN KeThreadDpcEnable;
-KMUTEX KiGenericCallDpcMutex;
+FAST_MUTEX KiGenericCallDpcMutex;
/* PRIVATE FUNCTIONS *********************************************************/
Modified: trunk/reactos/ntoskrnl/ke/i386/cpu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/cpu.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/cpu.c (original)
+++ trunk/reactos/ntoskrnl/ke/i386/cpu.c Thu Jan 18 09:23:14 2007
@@ -340,6 +340,14 @@
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 @@
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;
@@ -388,6 +397,9 @@
{
/* 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 @@
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 @@
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 **********************************************************/
Modified: trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/ctxswitch…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S (original)
+++ trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S Thu Jan 18 09:23:14 2007
@@ -17,7 +17,55 @@
#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
Modified: trunk/reactos/ntoskrnl/ke/i386/kiinit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/kiinit.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/kiinit.c (original)
+++ trunk/reactos/ntoskrnl/ke/i386/kiinit.c Thu Jan 18 09:23:14 2007
@@ -30,15 +30,18 @@
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 @@
/* 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 @@
/* 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 @@
/* 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);
-
- /* Clear initial MXCsr mask */
- FxSaveArea->U.FxArea.MXCsrMask = 0;
-
- /* Save the current NPX State */
+ /* 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;
+
+ /* 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 the current mask doesn't match the reserved bits */
+ if (FxSaveArea->U.FxArea.MXCsrMask != 0)
+ {
+ /* 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 */
+ 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;
}
-
- /* 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)
- {
- /* No, something is definitely wrong */
- KEBUGCHECKEX(MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED,
- KF_FXSR,
- NewMask,
- MXCsrMask,
- 0);
- }
- }
-
- /* Now set the kernel mask */
- KiMXCsrMask = NewMask & MXCsrMask;
}
}
@@ -242,7 +322,7 @@
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 @@
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 @@
LARGE_INTEGER PageDirectory;
PVOID DpcStack;
ULONG NXSupportPolicy;
+ ULONG Vendor[3];
/* Detect and set the CPU Type */
KiSetProcessorType();
@@ -319,19 +404,19 @@
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 @@
(strstr(KeLoaderBlock->LoadOptions, "EXECUTE")))
{
/* Set disabled mode */
- NXSupportPolicy = 0;
+ NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSOFF;
FeatureBits |= KF_NX_DISABLED;
}
@@ -372,18 +457,32 @@
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 @@
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 @@
/* 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();
}
Modified: trunk/reactos/ntoskrnl/ke/i386/patpge.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/patpge.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/patpge.c (original)
+++ trunk/reactos/ntoskrnl/ke/i386/patpge.c Thu Jan 18 09:23:14 2007
@@ -59,5 +59,5 @@
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");
}
Modified: trunk/reactos/ntoskrnl/ke/krnlinit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/krnlinit.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/krnlinit.c (original)
+++ trunk/reactos/ntoskrnl/ke/krnlinit.c Thu Jan 18 09:23:14 2007
@@ -94,7 +94,7 @@
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 @@
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,9 +246,13 @@
{
/* 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)