mirror of
https://github.com/reactos/reactos.git
synced 2024-10-01 23:14:53 +00:00
- Add KF_XMMI64 feature flag for SSE2 and detect it.
- Detect Hyper-Threading and set Local APIC ID (put back Thomas's code that he added in an old revision and that I had accidentally removed and forgotten to re-convert into the new KiGetFeatureBits function). - Add code to set the kernel MX Csr Mask in the FX Save Area. - Startup the sysenter handler on the DPC stack. - Detect and notify users with broken Pentiums. - Do some NPX checks to forcefully disable any FPU flags that might be set (SSE, MMX, 3DNOW) if the NPX is disabled. svn path=/trunk/; revision=24386
This commit is contained in:
parent
917979cceb
commit
1e4f141555
|
@ -86,6 +86,7 @@ Author:
|
|||
#define KF_XMMI 0x00002000
|
||||
#define KF_3DNOW 0x00004000
|
||||
#define KF_AMDK6MTRR 0x00008000
|
||||
#define KF_XMMI64 0x00010000
|
||||
|
||||
//
|
||||
// KPCR Access for non-IA64 builds
|
||||
|
|
|
@ -82,6 +82,7 @@ extern ULONG_PTR KERNEL_BASE;
|
|||
extern ULONG KeI386NpxPresent;
|
||||
extern ULONG KeI386XMMIPresent;
|
||||
extern ULONG KeI386FxsrPresent;
|
||||
extern ULONG KiMXCsrMask;
|
||||
extern ULONG KeI386CpuType;
|
||||
extern ULONG KeI386CpuStep;
|
||||
extern ULONG KeProcessorArchitecture;
|
||||
|
@ -89,6 +90,7 @@ extern ULONG KeProcessorLevel;
|
|||
extern ULONG KeProcessorRevision;
|
||||
extern ULONG KeFeatureBits;
|
||||
extern ULONG Ke386GlobalPagesEnabled;
|
||||
extern BOOLEAN KiI386PentiumLockErrataPresent;
|
||||
extern KNODE KiNode0;
|
||||
extern PKNODE KeNodeBlock[1];
|
||||
extern UCHAR KeNumberNodes;
|
||||
|
@ -119,6 +121,7 @@ extern ULONG KiIdealDpcRate;
|
|||
extern BOOLEAN KeThreadDpcEnable;
|
||||
extern LARGE_INTEGER KiTimeIncrementReciprocal;
|
||||
extern UCHAR KiTimeIncrementShiftCount;
|
||||
extern ULONG KiTimeLimitIsrMicroseconds;
|
||||
extern LIST_ENTRY BugcheckCallbackListHead, BugcheckReasonCallbackListHead;
|
||||
extern KSPIN_LOCK BugCheckCallbackLock;
|
||||
extern KDPC KiExpireTimerDpc;
|
||||
|
@ -860,6 +863,10 @@ VOID
|
|||
NTAPI
|
||||
KiInitMachineDependent(VOID);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiI386PentiumLockErrataFixup(VOID);
|
||||
|
||||
VOID
|
||||
WRMSR(
|
||||
IN ULONG Register,
|
||||
|
|
|
@ -318,6 +318,7 @@ C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, CurrentThread) == K
|
|||
C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, NpxThread) == KPCR_NPX_THREAD);
|
||||
C_ASSERT(FIELD_OFFSET(KTSS, Esp0) == KTSS_ESP0);
|
||||
C_ASSERT(FIELD_OFFSET(KTSS, IoMapBase) == KTSS_IOMAPBASE);
|
||||
C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, DpcStack) == KPCR_PRCB_DPC_STACK);
|
||||
C_ASSERT(sizeof(FX_SAVE_AREA) == SIZEOF_FX_SAVE_AREA);
|
||||
|
||||
#endif /* INCLUDE_INTERNAL_NTOSKRNL_H */
|
||||
|
|
|
@ -37,7 +37,7 @@ LARGE_INTEGER SystemBootTime = { 0 };
|
|||
|
||||
KDPC KiExpireTimerDpc;
|
||||
BOOLEAN KiClockSetupComplete = FALSE;
|
||||
|
||||
ULONG KiTimeLimitIsrMicroseconds;
|
||||
|
||||
/*
|
||||
* Number of timer interrupts since initialisation
|
||||
|
|
|
@ -58,19 +58,21 @@ ULONG KeProcessorRevision;
|
|||
ULONG KeFeatureBits;
|
||||
ULONG KiFastSystemCallDisable = 1;
|
||||
ULONG KeI386NpxPresent = 0;
|
||||
ULONG KiMXCsrMask = 0;
|
||||
ULONG MxcsrFeatureMask = 0;
|
||||
ULONG KeI386XMMIPresent = 0;
|
||||
ULONG KeI386FxsrPresent = 0;
|
||||
ULONG KeI386MachineType;
|
||||
ULONG Ke386Pae = FALSE;
|
||||
ULONG Ke386NoExecute = FALSE;
|
||||
BOOLEAN KiI386PentiumLockErrataPresent;
|
||||
ULONG KeLargestCacheLine = 0x40;
|
||||
ULONG KeDcacheFlushCount = 0;
|
||||
ULONG KeIcacheFlushCount = 0;
|
||||
ULONG KiDmaIoCoherency = 0;
|
||||
CHAR KeNumberProcessors;
|
||||
KAFFINITY KeActiveProcessors = 1;
|
||||
BOOLEAN KiI386PentiumLockErrataPresent;
|
||||
BOOLEAN KiSMTProcessorsPresent;
|
||||
|
||||
/* CPU Signatures */
|
||||
CHAR CmpIntelID[] = "GenuineIntel";
|
||||
|
@ -255,6 +257,9 @@ KiGetFeatureBits(VOID)
|
|||
/* Get the CPUID Info. Features are in Reg[3]. */
|
||||
CPUID(Reg, 1);
|
||||
|
||||
/* Set the initial APIC ID */
|
||||
Prcb->InitialApicId = (UCHAR)(Reg[1] >> 24);
|
||||
|
||||
/* Check for AMD CPU */
|
||||
if (Vendor == CPU_AMD)
|
||||
{
|
||||
|
@ -351,6 +356,24 @@ KiGetFeatureBits(VOID)
|
|||
if (CpuFeatures & 0x00800000) FeatureBits |= KF_MMX;
|
||||
if (CpuFeatures & 0x01000000) FeatureBits |= KF_FXSR;
|
||||
if (CpuFeatures & 0x02000000) FeatureBits |= KF_XMMI;
|
||||
if (CpuFeatures & 0x04000000) FeatureBits |= KF_XMMI64;
|
||||
|
||||
/* Check if the CPU has hyper-threading */
|
||||
if (CpuFeatures & 0x10000000)
|
||||
{
|
||||
/* Set the number of logical CPUs */
|
||||
Prcb->LogicalProcessorsPerPhysicalProcessor = (UCHAR)(Reg[1] >> 16);
|
||||
if (Prcb->LogicalProcessorsPerPhysicalProcessor > 1)
|
||||
{
|
||||
/* We're on dual-core */
|
||||
KiSMTProcessorsPresent = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We only have a single CPU */
|
||||
Prcb->LogicalProcessorsPerPhysicalProcessor = 1;
|
||||
}
|
||||
|
||||
/* Check if CPUID 0x80000000 is supported */
|
||||
if (ExtendedCPUID)
|
||||
|
@ -765,7 +788,7 @@ KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context)
|
|||
{
|
||||
/* Set CS and ESP */
|
||||
Ke386Wrmsr(0x174, KGDT_R0_CODE, 0);
|
||||
Ke386Wrmsr(0x175, 0, 0);
|
||||
Ke386Wrmsr(0x175, KeGetCurrentPrcb()->DpcStack, 0);
|
||||
|
||||
/* Set LSTAR */
|
||||
Ke386Wrmsr(0x176, KiFastCallEntry, 0);
|
||||
|
@ -813,6 +836,14 @@ Ki386EnableXMMIExceptions(IN ULONG_PTR Context)
|
|||
return 0;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiI386PentiumLockErrataFixup(VOID)
|
||||
{
|
||||
/* FIXME: Support this */
|
||||
DPRINT1("WARNING: Your machine has a CPU bug that ReactOS can't bypass!\n");
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS **********************************************************/
|
||||
|
||||
/*
|
||||
|
|
|
@ -30,6 +30,8 @@ KiInitMachineDependent(VOID)
|
|||
NTSTATUS Status;
|
||||
//ULONG ReturnLength;
|
||||
ULONG i, Affinity;
|
||||
PFX_SAVE_AREA FxSaveArea;
|
||||
ULONG MXCsrMask = 0xFFBF, NewMask;
|
||||
|
||||
/* Check for large page support */
|
||||
if (KeFeatureBits & KF_LARGE_PAGE)
|
||||
|
@ -69,6 +71,30 @@ KiInitMachineDependent(VOID)
|
|||
/* Check for PAT support and enable it */
|
||||
if (KeFeatureBits & KF_PAT) KiInitializePAT();
|
||||
|
||||
/* Assume no errata for now */
|
||||
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = 0;
|
||||
|
||||
/* If there's no NPX, then we're emulating the FPU */
|
||||
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] =
|
||||
!KeI386NpxPresent;
|
||||
|
||||
/* Check if there's no NPX, so that we can disable associated features */
|
||||
if (!KeI386NpxPresent)
|
||||
{
|
||||
/* Remove NPX-related bits */
|
||||
KeFeatureBits &= ~(KF_XMMI64 | KF_XMMI | KF_FXSR | KF_MMX);
|
||||
|
||||
/* Disable kernel flags */
|
||||
KeI386FxsrPresent = KeI386XMMIPresent = FALSE;
|
||||
|
||||
/* Disable processor features that might've been set until now */
|
||||
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] =
|
||||
SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] =
|
||||
SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
|
||||
SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
|
||||
SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = 0;
|
||||
}
|
||||
|
||||
/* Check for CR4 support */
|
||||
if (KeFeatureBits & KF_CR4)
|
||||
{
|
||||
|
@ -143,12 +169,67 @@ KiInitMachineDependent(VOID)
|
|||
/* Check if we have AMD MTRR and initialize it for the CPU */
|
||||
if (KeFeatureBits & KF_AMDK6MTRR) KiAmdK6InitializeMTRR();
|
||||
|
||||
/* FIXME: Apply P5 LOCK Errata fixups */
|
||||
/* 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 */
|
||||
#ifdef __GNUC__
|
||||
asm volatile("fxsave %0\n\t" : "=m" (*FxSaveArea));
|
||||
#else
|
||||
__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)
|
||||
{
|
||||
/* No, something is definitely wrong */
|
||||
KEBUGCHECKEX(MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED,
|
||||
KF_FXSR,
|
||||
NewMask,
|
||||
MXCsrMask,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now set the kernel mask */
|
||||
KiMXCsrMask = NewMask & MXCsrMask;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return affinity back to where it was */
|
||||
KeRevertToUserAffinityThread();
|
||||
|
||||
/* NT allows limiting the duration of an ISR with a registry key */
|
||||
if (KiTimeLimitIsrMicroseconds)
|
||||
{
|
||||
/* FIXME: TODO */
|
||||
DPRINT1("ISR Time Limit not yet supported\n");
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -519,11 +600,17 @@ AppCpuInit:
|
|||
|
||||
/* Align stack and make space for the trap frame and NPX frame */
|
||||
InitialStack &= ~KTRAP_FRAME_ALIGN;
|
||||
#ifdef __GNUC__
|
||||
__asm__ __volatile__("movl %0,%%esp" : :"r" (InitialStack));
|
||||
__asm__ __volatile__("subl %0,%%esp" : :"r" (NPX_FRAME_LENGTH +
|
||||
KTRAP_FRAME_LENGTH +
|
||||
KTRAP_FRAME_ALIGN));
|
||||
__asm__ __volatile__("push %0" : :"r" (CR0_EM + CR0_TS + CR0_MP));
|
||||
#else
|
||||
__asm mov esp, InitialStack;
|
||||
__asm sub esp, NPX_FRAME_LENGTH + KTRAP_FRAME_ALIGN + KTRAP_FRAME_LENGTH;
|
||||
__asm push CR0_EM + CR0_TS + CR0_MP
|
||||
#endif
|
||||
|
||||
/* Call main kernel initialization */
|
||||
KiInitializeKernel(&KiInitialProcess.Pcb,
|
||||
|
|
|
@ -111,9 +111,13 @@ _KiFastCallEntry:
|
|||
/* Set FS to PCR */
|
||||
mov ecx, KGDT_R0_PCR
|
||||
mov fs, cx
|
||||
//push KGDT_R0_PCR
|
||||
//pop fs
|
||||
|
||||
/* Set user selector */
|
||||
mov ecx, KGDT_R3_DATA | RPL_MASK
|
||||
|
||||
/* Set DS/ES to User Selector */
|
||||
mov ecx, KGDT_R3_DATA | RPL_MASK
|
||||
mov ds, cx
|
||||
mov es, cx
|
||||
|
||||
|
|
Loading…
Reference in a new issue