mirror of
https://github.com/reactos/reactos.git
synced 2025-06-15 12:59:33 +00:00
- 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:
parent
8be76ffcb3
commit
ccee43a360
13 changed files with 382 additions and 107 deletions
|
@ -427,6 +427,11 @@ typedef struct _KSYSTEM_TIME
|
||||||
|
|
||||||
extern volatile KSYSTEM_TIME KeTickCount;
|
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
|
typedef struct _KUSER_SHARED_DATA
|
||||||
{
|
{
|
||||||
ULONG TickCountLowDeprecated;
|
ULONG TickCountLowDeprecated;
|
||||||
|
|
|
@ -39,6 +39,11 @@ Author:
|
||||||
//
|
//
|
||||||
#define SSDT_MAX_ENTRIES 2
|
#define SSDT_MAX_ENTRIES 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Processor Architectures
|
||||||
|
//
|
||||||
|
#define PROCESSOR_ARCHITECTURE_INTEL 0
|
||||||
|
|
||||||
//
|
//
|
||||||
// Object Type Mask for Kernel Dispatcher Objects
|
// Object Type Mask for Kernel Dispatcher Objects
|
||||||
//
|
//
|
||||||
|
@ -87,8 +92,10 @@ Author:
|
||||||
#define KF_3DNOW 0x00004000
|
#define KF_3DNOW 0x00004000
|
||||||
#define KF_AMDK6MTRR 0x00008000
|
#define KF_AMDK6MTRR 0x00008000
|
||||||
#define KF_XMMI64 0x00010000
|
#define KF_XMMI64 0x00010000
|
||||||
#define KF_NX_DISABLED 0x00400000
|
#define KF_DTS 0x00020000
|
||||||
#define KF_NX_ENABLED 0x00800000
|
#define KF_NX_BIT 0x20000000
|
||||||
|
#define KF_NX_DISABLED 0x40000000
|
||||||
|
#define KF_NX_ENABLED 0x80000000
|
||||||
|
|
||||||
//
|
//
|
||||||
// KPCR Access for non-IA64 builds
|
// KPCR Access for non-IA64 builds
|
||||||
|
|
|
@ -930,7 +930,7 @@ static __inline__ __attribute__((always_inline)) unsigned long long __rdtsc(void
|
||||||
unsigned long lo32;
|
unsigned long lo32;
|
||||||
unsigned long hi32;
|
unsigned long hi32;
|
||||||
|
|
||||||
__asm__("rdtsc" : "=a" (lo32), "=d" (hi32));
|
__asm__ __volatile__("rdtsc" : "=a" (lo32), "=d" (hi32));
|
||||||
|
|
||||||
{
|
{
|
||||||
union u_
|
union u_
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
// Failure to respect this will *ACHIEVE NOTHING*.
|
// Failure to respect this will *ACHIEVE NOTHING*.
|
||||||
//
|
//
|
||||||
// Ke1:
|
// Ke1:
|
||||||
// - Implement KiInitMachineDependent.
|
|
||||||
// - Implement Privileged Instruction Handler in Umode GPF.
|
// - Implement Privileged Instruction Handler in Umode GPF.
|
||||||
//
|
//
|
||||||
// Ex:
|
// Ex:
|
||||||
|
@ -28,10 +27,6 @@
|
||||||
// Kd:
|
// Kd:
|
||||||
// - Implement KD Kernel Debugging and WinDBG support.
|
// - Implement KD Kernel Debugging and WinDBG support.
|
||||||
//
|
//
|
||||||
// Native:
|
|
||||||
// - Rewrite loader.
|
|
||||||
// - Make smss NT-compatible.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// REACTOS GUIDANCE PLAN
|
// REACTOS GUIDANCE PLAN
|
||||||
|
|
|
@ -39,6 +39,12 @@ BOOLEAN NoGuiBoot = FALSE;
|
||||||
/* NT Boot Path */
|
/* NT Boot Path */
|
||||||
UNICODE_STRING NtSystemRoot;
|
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 */
|
/* Boot NLS information */
|
||||||
PVOID ExpNlsTableBase;
|
PVOID ExpNlsTableBase;
|
||||||
ULONG ExpAnsiCodePageDataOffset, ExpOemCodePageDataOffset;
|
ULONG ExpAnsiCodePageDataOffset, ExpOemCodePageDataOffset;
|
||||||
|
@ -68,7 +74,7 @@ ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
&LinkName,
|
&LinkName,
|
||||||
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
|
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
|
||||||
NULL,
|
NULL,
|
||||||
SePublicDefaultSd);
|
SePublicDefaultUnrestrictedSd);
|
||||||
|
|
||||||
/* Create it */
|
/* Create it */
|
||||||
Status = NtCreateDirectoryObject(&LinkHandle,
|
Status = NtCreateDirectoryObject(&LinkHandle,
|
||||||
|
@ -88,7 +94,7 @@ ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
&LinkName,
|
&LinkName,
|
||||||
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
|
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
|
||||||
NULL,
|
NULL,
|
||||||
SePublicDefaultSd);
|
SePublicDefaultUnrestrictedSd);
|
||||||
|
|
||||||
/* Create it */
|
/* Create it */
|
||||||
Status = NtCreateDirectoryObject(&LinkHandle,
|
Status = NtCreateDirectoryObject(&LinkHandle,
|
||||||
|
@ -115,7 +121,7 @@ ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
&LinkName,
|
&LinkName,
|
||||||
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
|
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
|
||||||
NULL,
|
NULL,
|
||||||
SePublicDefaultSd);
|
SePublicDefaultUnrestrictedSd);
|
||||||
|
|
||||||
/* Build the ARC name */
|
/* Build the ARC name */
|
||||||
sprintf(Buffer,
|
sprintf(Buffer,
|
||||||
|
@ -353,10 +359,11 @@ ExpLoadInitialProcess(IN PHANDLE ProcessHandle,
|
||||||
PWSTR p;
|
PWSTR p;
|
||||||
UNICODE_STRING NullString = RTL_CONSTANT_STRING(L"");
|
UNICODE_STRING NullString = RTL_CONSTANT_STRING(L"");
|
||||||
UNICODE_STRING SmssName, Environment, SystemDriveString;
|
UNICODE_STRING SmssName, Environment, SystemDriveString;
|
||||||
|
PVOID EnvironmentPtr = NULL;
|
||||||
|
|
||||||
/* Allocate memory for the process parameters */
|
/* Allocate memory for the process parameters */
|
||||||
Size = sizeof(RTL_USER_PROCESS_PARAMETERS) +
|
Size = sizeof(RTL_USER_PROCESS_PARAMETERS) +
|
||||||
((MAX_PATH * 4) * sizeof(WCHAR));
|
((MAX_PATH * 6) * sizeof(WCHAR));
|
||||||
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
|
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
|
||||||
(PVOID)&ProcessParameters,
|
(PVOID)&ProcessParameters,
|
||||||
0,
|
0,
|
||||||
|
@ -378,7 +385,7 @@ ExpLoadInitialProcess(IN PHANDLE ProcessHandle,
|
||||||
/* Allocate a page for the environment */
|
/* Allocate a page for the environment */
|
||||||
Size = PAGE_SIZE;
|
Size = PAGE_SIZE;
|
||||||
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
|
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
|
||||||
(PVOID)&ProcessParameters->Environment,
|
&EnvironmentPtr,
|
||||||
0,
|
0,
|
||||||
&Size,
|
&Size,
|
||||||
MEM_COMMIT,
|
MEM_COMMIT,
|
||||||
|
@ -389,6 +396,9 @@ ExpLoadInitialProcess(IN PHANDLE ProcessHandle,
|
||||||
KeBugCheckEx(SESSION2_INITIALIZATION_FAILED, Status, 0, 0, 0);
|
KeBugCheckEx(SESSION2_INITIALIZATION_FAILED, Status, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write the pointer */
|
||||||
|
ProcessParameters->Environment = EnvironmentPtr;
|
||||||
|
|
||||||
/* Make a buffer for the DOS path */
|
/* Make a buffer for the DOS path */
|
||||||
p = (PWSTR)(ProcessParameters + 1);
|
p = (PWSTR)(ProcessParameters + 1);
|
||||||
ProcessParameters->CurrentDirectory.DosPath.Buffer = p;
|
ProcessParameters->CurrentDirectory.DosPath.Buffer = p;
|
||||||
|
@ -416,11 +426,48 @@ ExpLoadInitialProcess(IN PHANDLE ProcessHandle,
|
||||||
ProcessParameters->ImagePathName.Buffer = p;
|
ProcessParameters->ImagePathName.Buffer = p;
|
||||||
ProcessParameters->ImagePathName.MaximumLength = MAX_PATH * sizeof(WCHAR);
|
ProcessParameters->ImagePathName.MaximumLength = MAX_PATH * sizeof(WCHAR);
|
||||||
|
|
||||||
/* Append the system path and session manager name */
|
/* Make sure the buffer is a valid string which within the given length */
|
||||||
RtlAppendUnicodeToString(&ProcessParameters->ImagePathName,
|
if ((NtInitialUserProcessBufferType != REG_SZ) ||
|
||||||
L"\\SystemRoot\\System32");
|
((NtInitialUserProcessBufferLength != -1) &&
|
||||||
RtlAppendUnicodeToString(&ProcessParameters->ImagePathName,
|
((NtInitialUserProcessBufferLength < sizeof(WCHAR)) ||
|
||||||
L"\\smss.exe");
|
(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 */
|
/* Create the environment string */
|
||||||
RtlInitEmptyUnicodeString(&Environment,
|
RtlInitEmptyUnicodeString(&Environment,
|
||||||
|
@ -446,11 +493,8 @@ ExpLoadInitialProcess(IN PHANDLE ProcessHandle,
|
||||||
RtlAppendUnicodeStringToString(&Environment, &NtSystemRoot);
|
RtlAppendUnicodeStringToString(&Environment, &NtSystemRoot);
|
||||||
RtlAppendUnicodeStringToString(&Environment, &NullString);
|
RtlAppendUnicodeStringToString(&Environment, &NullString);
|
||||||
|
|
||||||
/* Get and set the command line equal to the image path */
|
|
||||||
ProcessParameters->CommandLine = ProcessParameters->ImagePathName;
|
|
||||||
SmssName = ProcessParameters->ImagePathName;
|
|
||||||
|
|
||||||
/* Create SMSS process */
|
/* Create SMSS process */
|
||||||
|
SmssName = ProcessParameters->ImagePathName;
|
||||||
Status = RtlCreateUserProcess(&SmssName,
|
Status = RtlCreateUserProcess(&SmssName,
|
||||||
OBJ_CASE_INSENSITIVE,
|
OBJ_CASE_INSENSITIVE,
|
||||||
RtlDeNormalizeProcessParams(
|
RtlDeNormalizeProcessParams(
|
||||||
|
@ -731,9 +775,9 @@ ExpInitializeExecutive(IN ULONG Cpu,
|
||||||
Buffer[--AnsiPath.Length] = ANSI_NULL;
|
Buffer[--AnsiPath.Length] = ANSI_NULL;
|
||||||
|
|
||||||
/* Get the string from KUSER_SHARED_DATA's buffer */
|
/* Get the string from KUSER_SHARED_DATA's buffer */
|
||||||
NtSystemRoot.Buffer = SharedUserData->NtSystemRoot;
|
RtlInitEmptyUnicodeString(&NtSystemRoot,
|
||||||
NtSystemRoot.MaximumLength = sizeof(SharedUserData->NtSystemRoot) / sizeof(WCHAR);
|
SharedUserData->NtSystemRoot,
|
||||||
NtSystemRoot.Length = 0;
|
sizeof(SharedUserData->NtSystemRoot));
|
||||||
|
|
||||||
/* Now fill it in */
|
/* Now fill it in */
|
||||||
Status = RtlAnsiStringToUnicodeString(&NtSystemRoot, &AnsiPath, FALSE);
|
Status = RtlAnsiStringToUnicodeString(&NtSystemRoot, &AnsiPath, FALSE);
|
||||||
|
@ -960,8 +1004,7 @@ ExPhase2Init(PVOID Context)
|
||||||
/* Bugcheck the system if SMSS couldn't initialize */
|
/* Bugcheck the system if SMSS couldn't initialize */
|
||||||
KeBugCheck(SESSION5_INITIALIZATION_FAILED);
|
KeBugCheck(SESSION5_INITIALIZATION_FAILED);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Close process handles */
|
/* Close process handles */
|
||||||
ZwClose(ThreadHandle);
|
ZwClose(ThreadHandle);
|
||||||
ZwClose(ProcessHandle);
|
ZwClose(ProcessHandle);
|
||||||
|
@ -973,6 +1016,5 @@ ExPhase2Init(PVOID Context)
|
||||||
|
|
||||||
/* Jump into zero page thread */
|
/* Jump into zero page thread */
|
||||||
MmZeroPageThreadMain(NULL);
|
MmZeroPageThreadMain(NULL);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -92,6 +92,12 @@ KiIsNpxPresent(
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
KiIsNpxErrataPresent(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KiSetProcessorType(VOID);
|
KiSetProcessorType(VOID);
|
||||||
|
|
|
@ -37,6 +37,18 @@ typedef struct _DISPATCH_INFO
|
||||||
PKINTERRUPT_ROUTINE *FlatDispatch;
|
PKINTERRUPT_ROUTINE *FlatDispatch;
|
||||||
} DISPATCH_INFO, *PDISPATCH_INFO;
|
} 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
|
typedef struct _KTIMER_TABLE_ENTRY
|
||||||
{
|
{
|
||||||
LIST_ENTRY Entry;
|
LIST_ENTRY Entry;
|
||||||
|
@ -113,7 +125,7 @@ extern KSPIN_LOCK BugCheckCallbackLock;
|
||||||
extern KDPC KiExpireTimerDpc;
|
extern KDPC KiExpireTimerDpc;
|
||||||
extern KTIMER_TABLE_ENTRY KiTimerTableListHead[TIMER_TABLE_SIZE];
|
extern KTIMER_TABLE_ENTRY KiTimerTableListHead[TIMER_TABLE_SIZE];
|
||||||
extern LIST_ENTRY KiTimerListHead;
|
extern LIST_ENTRY KiTimerListHead;
|
||||||
extern KMUTEX KiGenericCallDpcMutex;
|
extern FAST_MUTEX KiGenericCallDpcMutex;
|
||||||
extern LIST_ENTRY KiProfileListHead, KiProfileSourceListHead;
|
extern LIST_ENTRY KiProfileListHead, KiProfileSourceListHead;
|
||||||
extern KSPIN_LOCK KiProfileLock;
|
extern KSPIN_LOCK KiProfileLock;
|
||||||
extern LIST_ENTRY KiProcessListHead;
|
extern LIST_ENTRY KiProcessListHead;
|
||||||
|
@ -235,6 +247,13 @@ KiSelectNextThread(
|
||||||
IN PKPRCB Prcb
|
IN PKPRCB Prcb
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
CPUID(
|
||||||
|
OUT ULONG CpuInfo[4],
|
||||||
|
IN ULONG InfoType
|
||||||
|
);
|
||||||
|
|
||||||
/* gmutex.c ********************************************************************/
|
/* gmutex.c ********************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -23,7 +23,7 @@ ULONG KiMinimumDpcRate = 3;
|
||||||
ULONG KiAdjustDpcThreshold = 20;
|
ULONG KiAdjustDpcThreshold = 20;
|
||||||
ULONG KiIdealDpcRate = 20;
|
ULONG KiIdealDpcRate = 20;
|
||||||
BOOLEAN KeThreadDpcEnable;
|
BOOLEAN KeThreadDpcEnable;
|
||||||
KMUTEX KiGenericCallDpcMutex;
|
FAST_MUTEX KiGenericCallDpcMutex;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
|
|
|
@ -340,6 +340,14 @@ KiGetFeatureBits(VOID)
|
||||||
FeatureBits &= ~KF_WORKING_PTE;
|
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 */
|
/* Set the current features */
|
||||||
CpuFeatures = Reg[3];
|
CpuFeatures = Reg[3];
|
||||||
}
|
}
|
||||||
|
@ -354,6 +362,7 @@ KiGetFeatureBits(VOID)
|
||||||
if (CpuFeatures & 0x00002000) FeatureBits |= KF_GLOBAL_PAGE | KF_CR4;
|
if (CpuFeatures & 0x00002000) FeatureBits |= KF_GLOBAL_PAGE | KF_CR4;
|
||||||
if (CpuFeatures & 0x00008000) FeatureBits |= KF_CMOV;
|
if (CpuFeatures & 0x00008000) FeatureBits |= KF_CMOV;
|
||||||
if (CpuFeatures & 0x00010000) FeatureBits |= KF_PAT;
|
if (CpuFeatures & 0x00010000) FeatureBits |= KF_PAT;
|
||||||
|
if (CpuFeatures & 0x00200000) FeatureBits |= KF_DTS;
|
||||||
if (CpuFeatures & 0x00800000) FeatureBits |= KF_MMX;
|
if (CpuFeatures & 0x00800000) FeatureBits |= KF_MMX;
|
||||||
if (CpuFeatures & 0x01000000) FeatureBits |= KF_FXSR;
|
if (CpuFeatures & 0x01000000) FeatureBits |= KF_FXSR;
|
||||||
if (CpuFeatures & 0x02000000) FeatureBits |= KF_XMMI;
|
if (CpuFeatures & 0x02000000) FeatureBits |= KF_XMMI;
|
||||||
|
@ -389,6 +398,9 @@ KiGetFeatureBits(VOID)
|
||||||
/* Check which extended features are available. */
|
/* Check which extended features are available. */
|
||||||
CPUID(Reg, 0x80000001);
|
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 */
|
/* Now handle each features for each CPU Vendor */
|
||||||
switch (Vendor)
|
switch (Vendor)
|
||||||
{
|
{
|
||||||
|
@ -741,8 +753,23 @@ ULONG_PTR
|
||||||
NTAPI
|
NTAPI
|
||||||
Ki386EnableXMMIExceptions(IN ULONG_PTR Context)
|
Ki386EnableXMMIExceptions(IN ULONG_PTR Context)
|
||||||
{
|
{
|
||||||
/* FIXME: Support this */
|
#if 0 // needs kitrap13
|
||||||
DPRINT1("Your machine supports XMMI exceptions but ReactOS doesn't\n");
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -750,8 +777,34 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KiI386PentiumLockErrataFixup(VOID)
|
KiI386PentiumLockErrataFixup(VOID)
|
||||||
{
|
{
|
||||||
/* FIXME: Support this */
|
KDESCRIPTOR IdtDescriptor;
|
||||||
DPRINT1("WARNING: Your machine has a CPU bug that ReactOS can't bypass!\n");
|
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 **********************************************************/
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
|
@ -17,8 +17,56 @@
|
||||||
#define Running 2
|
#define Running 2
|
||||||
#define WrDispatchInt 0x1F
|
#define WrDispatchInt 0x1F
|
||||||
|
|
||||||
|
Dividend: .float 4195835.0
|
||||||
|
Divisor: .float 3145727.0
|
||||||
|
Result1: .float 0
|
||||||
|
Result2: .float 0
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* 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
|
.globl _KiIsNpxPresent@0
|
||||||
.func KiIsNpxPresent@0
|
.func KiIsNpxPresent@0
|
||||||
_KiIsNpxPresent@0:
|
_KiIsNpxPresent@0:
|
||||||
|
|
|
@ -30,15 +30,18 @@ KiInitMachineDependent(VOID)
|
||||||
BOOLEAN FbCaching = FALSE;
|
BOOLEAN FbCaching = FALSE;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG ReturnLength;
|
ULONG ReturnLength;
|
||||||
ULONG i, Affinity;
|
ULONG i, Affinity, Sample = 0;
|
||||||
PFX_SAVE_AREA FxSaveArea;
|
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 */
|
/* Check for large page support */
|
||||||
if (KeFeatureBits & KF_LARGE_PAGE)
|
if (KeFeatureBits & KF_LARGE_PAGE)
|
||||||
{
|
{
|
||||||
/* FIXME: Support this */
|
/* 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 */
|
/* Check for global page support */
|
||||||
|
@ -70,6 +73,34 @@ KiInitMachineDependent(VOID)
|
||||||
/* Assume no errata for now */
|
/* Assume no errata for now */
|
||||||
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = 0;
|
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 */
|
/* If there's no NPX, then we're emulating the FPU */
|
||||||
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] =
|
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] =
|
||||||
!KeI386NpxPresent;
|
!KeI386NpxPresent;
|
||||||
|
@ -148,18 +179,66 @@ KiInitMachineDependent(VOID)
|
||||||
/* Start sampling loop */
|
/* Start sampling loop */
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
//
|
/* Do a dummy CPUID to start the sample */
|
||||||
// FIXME: TODO
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we have MTRR without PAT */
|
/* Move on */
|
||||||
if (!(KeFeatureBits & KF_PAT) && (KeFeatureBits & KF_MTRR))
|
CurrentSample++;
|
||||||
|
Sample++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the CPU Speed */
|
||||||
|
KeGetCurrentPrcb()->MHz = CurrentSample[-1].MHz;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we have MTRR */
|
||||||
|
if (KeFeatureBits & KF_MTRR)
|
||||||
{
|
{
|
||||||
/* Then manually initialize MTRR for the CPU */
|
/* 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 */
|
/* Check if we have AMD MTRR and initialize it for the CPU */
|
||||||
|
@ -168,6 +247,9 @@ KiInitMachineDependent(VOID)
|
||||||
/* Check if this is a buggy Pentium and apply the fixup if so */
|
/* Check if this is a buggy Pentium and apply the fixup if so */
|
||||||
if (KiI386PentiumLockErrataPresent) KiI386PentiumLockErrataFixup();
|
if (KiI386PentiumLockErrataPresent) KiI386PentiumLockErrataFixup();
|
||||||
|
|
||||||
|
/* Check if the CPU supports FXSR */
|
||||||
|
if (KeFeatureBits & KF_FXSR)
|
||||||
|
{
|
||||||
/* Get the current thread NPX state */
|
/* Get the current thread NPX state */
|
||||||
FxSaveArea = (PVOID)
|
FxSaveArea = (PVOID)
|
||||||
((ULONG_PTR)KeGetCurrentThread()->InitialStack -
|
((ULONG_PTR)KeGetCurrentThread()->InitialStack -
|
||||||
|
@ -183,7 +265,7 @@ KiInitMachineDependent(VOID)
|
||||||
__asm fxsave [FxSaveArea]
|
__asm fxsave [FxSaveArea]
|
||||||
#endif
|
#endif
|
||||||
/* Check if the current mask doesn't match the reserved bits */
|
/* Check if the current mask doesn't match the reserved bits */
|
||||||
if (FxSaveArea->U.FxArea.MXCsrMask != MXCsrMask)
|
if (FxSaveArea->U.FxArea.MXCsrMask != 0)
|
||||||
{
|
{
|
||||||
/* Then use whatever it's holding */
|
/* Then use whatever it's holding */
|
||||||
MXCsrMask = FxSaveArea->U.FxArea.MXCsrMask;
|
MXCsrMask = FxSaveArea->U.FxArea.MXCsrMask;
|
||||||
|
@ -193,27 +275,25 @@ KiInitMachineDependent(VOID)
|
||||||
if (!KiMXCsrMask)
|
if (!KiMXCsrMask)
|
||||||
{
|
{
|
||||||
/* Then use the one we calculated above */
|
/* Then use the one we calculated above */
|
||||||
NewMask = MXCsrMask;
|
KiMXCsrMask = MXCsrMask;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Use the existing mask */
|
|
||||||
NewMask = KiMXCsrMask;
|
|
||||||
|
|
||||||
/* Was it set to the same value we found now? */
|
/* Was it set to the same value we found now? */
|
||||||
if (NewMask != MXCsrMask)
|
if (KiMXCsrMask != MXCsrMask)
|
||||||
{
|
{
|
||||||
/* No, something is definitely wrong */
|
/* No, something is definitely wrong */
|
||||||
KEBUGCHECKEX(MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED,
|
KEBUGCHECKEX(MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED,
|
||||||
KF_FXSR,
|
KF_FXSR,
|
||||||
NewMask,
|
KiMXCsrMask,
|
||||||
MXCsrMask,
|
MXCsrMask,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now set the kernel mask */
|
/* Now set the kernel mask */
|
||||||
KiMXCsrMask = NewMask & MXCsrMask;
|
KiMXCsrMask &= MXCsrMask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +322,7 @@ KiInitializePcr(IN ULONG ProcessorNumber,
|
||||||
Pcr->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
|
Pcr->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
|
||||||
Pcr->NtTib.StackBase = 0;
|
Pcr->NtTib.StackBase = 0;
|
||||||
Pcr->NtTib.StackLimit = 0;
|
Pcr->NtTib.StackLimit = 0;
|
||||||
Pcr->NtTib.Self = 0;
|
Pcr->NtTib.Self = NULL;
|
||||||
|
|
||||||
/* Set the Current Thread */
|
/* Set the Current Thread */
|
||||||
Pcr->PrcbData.CurrentThread = IdleThread;
|
Pcr->PrcbData.CurrentThread = IdleThread;
|
||||||
|
@ -282,7 +362,11 @@ KiInitializePcr(IN ULONG ProcessorNumber,
|
||||||
Pcr->GDT = (PVOID)Gdt;
|
Pcr->GDT = (PVOID)Gdt;
|
||||||
Pcr->IDT = Idt;
|
Pcr->IDT = Idt;
|
||||||
Pcr->TSS = Tss;
|
Pcr->TSS = Tss;
|
||||||
|
Pcr->TssCopy = Tss;
|
||||||
Pcr->PrcbData.DpcStack = DpcStack;
|
Pcr->PrcbData.DpcStack = DpcStack;
|
||||||
|
|
||||||
|
/* Setup the processor set */
|
||||||
|
Pcr->PrcbData.MultiThreadProcessorSet = Pcr->PrcbData.SetMember;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -299,6 +383,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
|
||||||
LARGE_INTEGER PageDirectory;
|
LARGE_INTEGER PageDirectory;
|
||||||
PVOID DpcStack;
|
PVOID DpcStack;
|
||||||
ULONG NXSupportPolicy;
|
ULONG NXSupportPolicy;
|
||||||
|
ULONG Vendor[3];
|
||||||
|
|
||||||
/* Detect and set the CPU Type */
|
/* Detect and set the CPU Type */
|
||||||
KiSetProcessorType();
|
KiSetProcessorType();
|
||||||
|
@ -319,19 +404,19 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
|
||||||
FeatureBits = KiGetFeatureBits();
|
FeatureBits = KiGetFeatureBits();
|
||||||
|
|
||||||
/* Set the default NX policy (opt-in) */
|
/* Set the default NX policy (opt-in) */
|
||||||
NXSupportPolicy = 2;
|
NXSupportPolicy = NX_SUPPORT_POLICY_OPTIN;
|
||||||
|
|
||||||
/* Check if NPX is always on */
|
/* Check if NPX is always on */
|
||||||
if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSON"))
|
if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=ALWAYSON"))
|
||||||
{
|
{
|
||||||
/* Set it always on */
|
/* Set it always on */
|
||||||
NXSupportPolicy = 1;
|
NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSON;
|
||||||
FeatureBits |= KF_NX_ENABLED;
|
FeatureBits |= KF_NX_ENABLED;
|
||||||
}
|
}
|
||||||
else if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTOUT"))
|
else if (strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTOUT"))
|
||||||
{
|
{
|
||||||
/* Set it in opt-out mode */
|
/* Set it in opt-out mode */
|
||||||
NXSupportPolicy = 3;
|
NXSupportPolicy = NX_SUPPORT_POLICY_OPTOUT;
|
||||||
FeatureBits |= KF_NX_ENABLED;
|
FeatureBits |= KF_NX_ENABLED;
|
||||||
}
|
}
|
||||||
else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTIN")) ||
|
else if ((strstr(KeLoaderBlock->LoadOptions, "NOEXECUTE=OPTIN")) ||
|
||||||
|
@ -344,7 +429,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
|
||||||
(strstr(KeLoaderBlock->LoadOptions, "EXECUTE")))
|
(strstr(KeLoaderBlock->LoadOptions, "EXECUTE")))
|
||||||
{
|
{
|
||||||
/* Set disabled mode */
|
/* Set disabled mode */
|
||||||
NXSupportPolicy = 0;
|
NXSupportPolicy = NX_SUPPORT_POLICY_ALWAYSOFF;
|
||||||
FeatureBits |= KF_NX_DISABLED;
|
FeatureBits |= KF_NX_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,18 +457,32 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
|
||||||
KeI386NpxPresent = NpxPresent;
|
KeI386NpxPresent = NpxPresent;
|
||||||
KeI386CpuType = Prcb->CpuType;
|
KeI386CpuType = Prcb->CpuType;
|
||||||
KeI386CpuStep = Prcb->CpuStep;
|
KeI386CpuStep = Prcb->CpuStep;
|
||||||
KeProcessorArchitecture = 0;
|
KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
|
||||||
KeProcessorLevel = (USHORT)Prcb->CpuType;
|
KeProcessorLevel = (USHORT)Prcb->CpuType;
|
||||||
if (Prcb->CpuID) KeProcessorRevision = Prcb->CpuStep;
|
if (Prcb->CpuID) KeProcessorRevision = Prcb->CpuStep;
|
||||||
KeFeatureBits = FeatureBits;
|
KeFeatureBits = FeatureBits;
|
||||||
KeI386FxsrPresent = (KeFeatureBits & KF_FXSR) ? TRUE : FALSE;
|
KeI386FxsrPresent = (KeFeatureBits & KF_FXSR) ? TRUE : FALSE;
|
||||||
KeI386XMMIPresent = (KeFeatureBits & KF_XMMI) ? 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 */
|
/* Set the current MP Master KPRCB to the Boot PRCB */
|
||||||
Prcb->MultiThreadSetMaster = Prcb;
|
Prcb->MultiThreadSetMaster = Prcb;
|
||||||
|
|
||||||
/* Lower to APC_LEVEL */
|
/* Lower to APC_LEVEL */
|
||||||
KfLowerIrql(APC_LEVEL);
|
KeLowerIrql(APC_LEVEL);
|
||||||
|
|
||||||
/* Initialize some spinlocks */
|
/* Initialize some spinlocks */
|
||||||
KeInitializeSpinLock(&KiFreezeExecutionLock);
|
KeInitializeSpinLock(&KiFreezeExecutionLock);
|
||||||
|
@ -499,7 +598,9 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
|
||||||
KeSetPriorityThread(InitThread, 0);
|
KeSetPriorityThread(InitThread, 0);
|
||||||
|
|
||||||
/* If there's no thread scheduled, put this CPU in the Idle summary */
|
/* If there's no thread scheduled, put this CPU in the Idle summary */
|
||||||
|
KiAcquirePrcbLock(Prcb);
|
||||||
if (!Prcb->NextThread) KiIdleSummary |= 1 << Number;
|
if (!Prcb->NextThread) KiIdleSummary |= 1 << Number;
|
||||||
|
KiReleasePrcbLock(Prcb);
|
||||||
|
|
||||||
/* Raise back to HIGH_LEVEL and clear the PRCB for the loader block */
|
/* Raise back to HIGH_LEVEL and clear the PRCB for the loader block */
|
||||||
KfRaiseIrql(HIGH_LEVEL);
|
KfRaiseIrql(HIGH_LEVEL);
|
||||||
|
@ -683,11 +784,6 @@ AppCpuInit:
|
||||||
/* Set the right wait IRQL */
|
/* Set the right wait IRQL */
|
||||||
KeGetCurrentThread()->WaitIrql = DISPATCH_LEVEL;
|
KeGetCurrentThread()->WaitIrql = DISPATCH_LEVEL;
|
||||||
|
|
||||||
/* Set idle thread as running on UP builds */
|
|
||||||
#ifndef CONFIG_SMP
|
|
||||||
KeGetCurrentThread()->State = Running;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Jump into the idle loop */
|
/* Jump into the idle loop */
|
||||||
KiIdleLoop();
|
KiIdleLoop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,5 +59,5 @@ NTAPI
|
||||||
KiInitializePAT(VOID)
|
KiInitializePAT(VOID)
|
||||||
{
|
{
|
||||||
/* FIXME: Support this */
|
/* 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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ KiInitSystem(VOID)
|
||||||
InitializeListHead(&KiStackInSwapListHead);
|
InitializeListHead(&KiStackInSwapListHead);
|
||||||
|
|
||||||
/* Initialize the mutex for generic DPC calls */
|
/* Initialize the mutex for generic DPC calls */
|
||||||
KeInitializeMutex(&KiGenericCallDpcMutex, 0);
|
ExInitializeFastMutex(&KiGenericCallDpcMutex);
|
||||||
|
|
||||||
/* Initialize the syscall table */
|
/* Initialize the syscall table */
|
||||||
KeServiceDescriptorTable[0].Base = MainSSDT;
|
KeServiceDescriptorTable[0].Base = MainSSDT;
|
||||||
|
@ -183,7 +183,7 @@ KiInitSpinLocks(IN PKPRCB Prcb,
|
||||||
Prcb->QueueIndex = 1;
|
Prcb->QueueIndex = 1;
|
||||||
Prcb->ReadySummary = 0;
|
Prcb->ReadySummary = 0;
|
||||||
Prcb->DeferredReadyListHead.Next = NULL;
|
Prcb->DeferredReadyListHead.Next = NULL;
|
||||||
for (i = 0; i < 32; i++)
|
for (i = 0; i < MAXIMUM_PRIORITY; i++)
|
||||||
{
|
{
|
||||||
/* Initialize the ready list */
|
/* Initialize the ready list */
|
||||||
InitializeListHead(&Prcb->DispatcherReadyListHead[i]);
|
InitializeListHead(&Prcb->DispatcherReadyListHead[i]);
|
||||||
|
@ -246,10 +246,14 @@ KiInitSpinLocks(IN PKPRCB Prcb,
|
||||||
{
|
{
|
||||||
/* Initialize the lock and setup the Queued Spinlock */
|
/* Initialize the lock and setup the Queued Spinlock */
|
||||||
KeInitializeSpinLock(&KiTimerTableLock[i]);
|
KeInitializeSpinLock(&KiTimerTableLock[i]);
|
||||||
Prcb->LockQueue[i].Next = NULL;
|
Prcb->LockQueue[LockQueueTimerTableLock + i].Next = NULL;
|
||||||
Prcb->LockQueue[i].Lock = &KiTimerTableLock[i];
|
Prcb->LockQueue[LockQueueTimerTableLock + i].Lock =
|
||||||
|
&KiTimerTableLock[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize the PRCB lock */
|
||||||
|
KeInitializeSpinLock(&Prcb->PrcbLock);
|
||||||
|
|
||||||
/* Check if this is the boot CPU */
|
/* Check if this is the boot CPU */
|
||||||
if (!Number)
|
if (!Number)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue