return __readmsr(Register);
}
+/* NSC/Cyrix CPU configuration register index */
+#define CX86_CCR1 0xc1
+
+/* NSC/Cyrix CPU indexed register access macros */
+static __inline
+ULONG
+getCx86(UCHAR reg)
+{
+ WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)0x22, reg);
+ return READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)0x23);
+}
+
+#define setCx86(reg, data) do { \
+ WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)0x22,(reg)); \
+ WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)0x23,(data)); \
+} while (0)
+
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
+INIT_FUNCTION
KiSetProcessorType(VOID)
{
ULONG EFlags, NewEFlags;
ULONG
NTAPI
+INIT_FUNCTION
KiGetCpuVendor(VOID)
{
PKPRCB Prcb = KeGetCurrentPrcb();
ULONG
NTAPI
+INIT_FUNCTION
KiGetFeatureBits(VOID)
{
PKPRCB Prcb = KeGetCurrentPrcb();
ULONG Vendor;
ULONG FeatureBits = KF_WORKING_PTE;
- ULONG Reg[4], Dummy;
+ ULONG Reg[4], Dummy, Ccr1;
BOOLEAN ExtendedCPUID = TRUE;
ULONG CpuFeatures = 0;
/* Remove support for correct PTE support. */
FeatureBits &= ~KF_WORKING_PTE;
}
+
+ /* Virtualbox claims to have no SYSENTER support,
+ * which is false for processors >= Pentium Pro */
+ if(Prcb->CpuType >= 6)
+ {
+ Reg[3] |= 0x800;
+ }
/* Check if the CPU is too old to support SYSENTER */
- if ((Prcb->CpuType < 6) ||
- ((Prcb->CpuType == 6) && (Prcb->CpuStep < 0x0303)))
+ if ((Reg[0] & 0x0FFF3FFF) < 0x00000633)
{
/* Disable it */
Reg[3] &= ~0x800;
/* Cyrix CPUs */
case CPU_CYRIX:
- /* FIXME: CMPXCGH8B */
+ /* Workaround the "COMA" bug on 6x family of Cyrix CPUs */
+ if (Prcb->CpuType == 6 &&
+ Prcb->CpuStep <= 1)
+ {
+ /* Get CCR1 value */
+ Ccr1 = getCx86(CX86_CCR1);
+
+ /* Enable the NO_LOCK bit */
+ Ccr1 |= 0x10;
+
+ /* Set the new CCR1 value */
+ setCx86(CX86_CCR1, Ccr1);
+ }
+
+ /* Set the current features */
+ CpuFeatures = Reg[3];
break;
}
}
}
+
+ DPRINT1("Supported CPU features :\n");
+#define print_supported(kf_value) \
+ if(FeatureBits & kf_value) DPRINT1("\t" #kf_value "\n")
+ print_supported(KF_V86_VIS);
+ print_supported(KF_RDTSC);
+ print_supported(KF_CR4);
+ print_supported(KF_CMOV);
+ print_supported(KF_GLOBAL_PAGE);
+ print_supported(KF_LARGE_PAGE);
+ print_supported(KF_MTRR);
+ print_supported(KF_CMPXCHG8B);
+ print_supported(KF_MMX);
+ print_supported(KF_WORKING_PTE);
+ print_supported(KF_PAT);
+ print_supported(KF_FXSR);
+ print_supported(KF_FAST_SYSCALL);
+ print_supported(KF_XMMI);
+ print_supported(KF_3DNOW);
+ print_supported(KF_AMDK6MTRR);
+ print_supported(KF_XMMI64);
+ print_supported(KF_DTS);
+ print_supported(KF_NX_BIT);
+ print_supported(KF_NX_DISABLED);
+ print_supported(KF_NX_ENABLED);
+#undef print_supported
/* Return the Feature Bits */
return FeatureBits;
VOID
NTAPI
+INIT_FUNCTION
KiGetCacheInformation(VOID)
{
PKIPCR Pcr = (PKIPCR)KeGetPcr();
VOID
NTAPI
+INIT_FUNCTION
KiSetCR0Bits(VOID)
{
ULONG Cr0;
VOID
NTAPI
+INIT_FUNCTION
KiInitializeTSS2(IN PKTSS Tss,
IN PKGDTENTRY TssEntry OPTIONAL)
{
VOID
FASTCALL
+INIT_FUNCTION
Ki386InitializeTss(IN PKTSS Tss,
IN PKIDTENTRY Idt,
IN PKGDTENTRY Gdt)
VOID
NTAPI
+INIT_FUNCTION
KiInitializeMachineType(VOID)
{
/* Set the Machine Type we got from NTLDR */
ULONG_PTR
NTAPI
+INIT_FUNCTION
KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context)
{
/* Set CS and ESP */
VOID
NTAPI
+INIT_FUNCTION
KiRestoreFastSyscallReturnState(VOID)
{
/* Check if the CPU Supports fast system call */
ULONG_PTR
NTAPI
+INIT_FUNCTION
Ki386EnableDE(IN ULONG_PTR Context)
{
/* Enable DE */
ULONG_PTR
NTAPI
+INIT_FUNCTION
Ki386EnableFxsr(IN ULONG_PTR Context)
{
/* Enable FXSR */
ULONG_PTR
NTAPI
+INIT_FUNCTION
Ki386EnableXMMIExceptions(IN ULONG_PTR Context)
{
PKIDTENTRY IdtEntry;
VOID
NTAPI
+INIT_FUNCTION
KiI386PentiumLockErrataFixup(VOID)
{
KDESCRIPTOR IdtDescriptor;
BOOLEAN
NTAPI
+INIT_FUNCTION
KiIsNpxPresent(VOID)
{
ULONG Cr0;
Cr0 = __readcr0() & ~(CR0_MP | CR0_TS | CR0_EM | CR0_ET);
/* Store on FPU stack */
+#ifdef _MSC_VER
+ __asm fninit;
+ __asm fnstsw Magic;
+#else
asm volatile ("fninit;" "fnstsw %0" : "+m"(Magic));
+#endif
/* Magic should now be cleared */
if (Magic & 0xFF)
BOOLEAN
NTAPI
+INIT_FUNCTION
KiIsNpxErrataPresent(VOID)
{
BOOLEAN ErrataPresent;
__writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
/* Initialize FPU state */
- asm volatile ("fninit");
+ Ke386FnInit();
/* Multiply the magic values and divide, we should get the result back */
Value1 = 4195835.0;
return ErrataPresent;
}
-NTAPI
VOID
+NTAPI
KiFlushNPXState(IN PFLOATING_SAVE_AREA SaveArea)
{
ULONG EFlags, Cr0;