ReactOS 0.4.16-dev-311-g9382aa2
cpu.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include <xmmintrin.h>
Include dependency graph for cpu.c:

Go to the source code of this file.

Classes

union  _CPU_SIGNATURE
 

Macros

#define NDEBUG
 
#define FXSAVE_ALIGN   15
 
#define CX86_CCR1   0xc1
 

Typedefs

typedef union _CPU_SIGNATURE CPU_SIGNATURE
 

Functions

static __inline UCHAR getCx86 (UCHAR reg)
 
static __inline void setCx86 (UCHAR reg, UCHAR data)
 
ULONG NTAPI KiGetCpuVendor (VOID)
 
VOID NTAPI KiSetProcessorType (VOID)
 
ULONG NTAPI KiGetFeatureBits (VOID)
 Evaluates the KeFeatureFlag bits for the current CPU.
 
VOID NTAPI KiGetCacheInformation (VOID)
 
VOID NTAPI KiSetCR0Bits (VOID)
 
VOID NTAPI KiInitializeTSS2 (IN PKTSS Tss, IN PKGDTENTRY TssEntry OPTIONAL)
 
VOID NTAPI KiInitializeTSS (IN PKTSS Tss)
 
VOID FASTCALL Ki386InitializeTss (IN PKTSS Tss, IN PKIDTENTRY Idt, IN PKGDTENTRY Gdt)
 
VOID NTAPI KeFlushCurrentTb (VOID)
 
VOID NTAPI KiRestoreProcessorControlState (PKPROCESSOR_STATE ProcessorState)
 
VOID NTAPI KiSaveProcessorControlState (OUT PKPROCESSOR_STATE ProcessorState)
 
VOID NTAPI KiInitializeMachineType (VOID)
 
ULONG_PTR NTAPI KiLoadFastSyscallMachineSpecificRegisters (IN ULONG_PTR Context)
 
VOID NTAPI KiRestoreFastSyscallReturnState (VOID)
 
ULONG_PTR NTAPI Ki386EnableDE (IN ULONG_PTR Context)
 
ULONG_PTR NTAPI Ki386EnableFxsr (IN ULONG_PTR Context)
 
ULONG_PTR NTAPI Ki386EnableXMMIExceptions (IN ULONG_PTR Context)
 
VOID NTAPI KiI386PentiumLockErrataFixup (VOID)
 
BOOLEAN NTAPI KeInvalidateAllCaches (VOID)
 
VOID NTAPI KiSaveProcessorState (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
 
BOOLEAN NTAPI KiIsNpxErrataPresent (VOID)
 
VOID NTAPI KiFlushNPXState (IN PFLOATING_SAVE_AREA SaveArea)
 
VOID NTAPI KiCoprocessorError (VOID)
 
NTSTATUS NTAPI KeSaveFloatingPointState (_Out_ PKFLOATING_SAVE Save)
 Saves the current floating point unit state context of the current calling thread.
 
NTSTATUS NTAPI KeRestoreFloatingPointState (_In_ PKFLOATING_SAVE Save)
 Restores the original FPU state context that has been saved by a API call of KeSaveFloatingPointState. Callers are expected to restore the floating point state by calling this function when they've finished doing FPU operations.
 
ULONG NTAPI KeGetRecommendedSharedDataAlignment (VOID)
 
VOID NTAPI KiFlushTargetEntireTb (IN PKIPI_CONTEXT PacketContext, IN PVOID Ignored1, IN PVOID Ignored2, IN PVOID Ignored3)
 
VOID NTAPI KeFlushEntireTb (IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
 
VOID NTAPI KeSetDmaIoCoherency (IN ULONG Coherency)
 
KAFFINITY NTAPI KeQueryActiveProcessors (VOID)
 
VOID __cdecl KeSaveStateForHibernate (IN PKPROCESSOR_STATE State)
 

Variables

UCHAR KiDoubleFaultTSS [KTSS_IO_MAPS]
 
UCHAR KiNMITSS [KTSS_IO_MAPS]
 
ULONG KeI386CpuType
 
ULONG KeI386CpuStep
 
ULONG KiFastSystemCallDisable = 0
 
ULONG KeI386NpxPresent = TRUE
 
ULONG KiMXCsrMask = 0
 
ULONG MxcsrFeatureMask = 0
 
ULONG KeI386XMMIPresent = 0
 
ULONG KeI386FxsrPresent = 0
 
ULONG KeI386MachineType
 
ULONG Ke386Pae = FALSE
 
ULONG Ke386NoExecute = FALSE
 
ULONG KeLargestCacheLine = 0x40
 
ULONG KeDcacheFlushCount = 0
 
ULONG KeIcacheFlushCount = 0
 
ULONG KiDmaIoCoherency = 0
 
ULONG KePrefetchNTAGranularity = 32
 
BOOLEAN KiI386PentiumLockErrataPresent
 
BOOLEAN KiSMTProcessorsPresent
 
UCHAR KiSystemCallExitAdjust
 
UCHAR KiSystemCallExitAdjusted
 
BOOLEAN KiFastCallCopyDoneOnce
 
volatile LONG KiTbFlushTimeStamp
 
static const CHAR CmpIntelID [] = "GenuineIntel"
 
static const CHAR CmpAmdID [] = "AuthenticAMD"
 
static const CHAR CmpCyrixID [] = "CyrixInstead"
 
static const CHAR CmpTransmetaID [] = "GenuineTMx86"
 
static const CHAR CmpCentaurID [] = "CentaurHauls"
 
static const CHAR CmpRiseID [] = "RiseRiseRise"
 

Macro Definition Documentation

◆ CX86_CCR1

#define CX86_CCR1   0xc1

Definition at line 86 of file cpu.c.

◆ FXSAVE_ALIGN

#define FXSAVE_ALIGN   15

Definition at line 81 of file cpu.c.

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file cpu.c.

Typedef Documentation

◆ CPU_SIGNATURE

Function Documentation

◆ getCx86()

static __inline UCHAR getCx86 ( UCHAR  reg)
static

Definition at line 91 of file cpu.c.

92{
94 return READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)0x23);
95}
static int reg
Definition: i386-dis.c:1290
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by KiGetFeatureBits().

◆ KeFlushCurrentTb()

VOID NTAPI KeFlushCurrentTb ( VOID  )

Definition at line 899 of file cpu.c.

900{
901
902#if !defined(_GLOBAL_PAGES_ARE_AWESOME_)
903
904 /* Flush the TLB by resetting CR3 */
906
907#else
908
909 /* Check if global pages are enabled */
911 {
912 ULONG Cr4;
913
914 /* Disable PGE (Note: may not have been enabled yet) */
915 Cr4 = __readcr4();
916 __writecr4(Cr4 & ~CR4_PGE);
917
918 /* Flush everything */
920
921 /* Re-enable PGE */
922 __writecr4(Cr4);
923 }
924 else
925 {
926 /* No global pages, resetting CR3 is enough */
928 }
929
930#endif
931
932}
__INTRIN_INLINE unsigned long __readcr3(void)
Definition: intrin_x86.h:1818
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1825
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1794
__INTRIN_INLINE void __writecr4(unsigned int Data)
Definition: intrin_x86.h:1799
#define CR4_PGE
Definition: ketypes.h:141
#define KF_GLOBAL_PAGE
Definition: ketypes.h:35
ULONG KeFeatureBits
Definition: krnlinit.c:22
uint32_t ULONG
Definition: typedefs.h:59

Referenced by KeThawExecution(), MiDeletePte(), MiFlushTbAndCapture(), MiFlushTlbIpiRoutine(), MiInitializePageTable(), MiInitMachineDependent(), MiProcessValidPteList(), MiRemoveMappedPtes(), MmChangeKernelResourceSectionProtection(), and MmFreeLoaderBlock().

◆ KeFlushEntireTb()

VOID NTAPI KeFlushEntireTb ( IN BOOLEAN  Invalid,
IN BOOLEAN  AllProcessors 
)

Definition at line 1590 of file cpu.c.

1592{
1593 KIRQL OldIrql;
1594#ifdef CONFIG_SMP
1595 KAFFINITY TargetAffinity;
1596 PKPRCB Prcb = KeGetCurrentPrcb();
1597#endif
1598
1599 /* Raise the IRQL for the TB Flush */
1601
1602#ifdef CONFIG_SMP
1603 /* FIXME: Use KiTbFlushTimeStamp to synchronize TB flush */
1604
1605 /* Get the current processor affinity, and exclude ourselves */
1606 TargetAffinity = KeActiveProcessors;
1607 TargetAffinity &= ~Prcb->SetMember;
1608
1609 /* Make sure this is MP */
1610 if (TargetAffinity)
1611 {
1612 /* Send an IPI TB flush to the other processors */
1613 KiIpiSendPacket(TargetAffinity,
1615 NULL,
1616 0,
1617 NULL);
1618 }
1619#endif
1620
1621 /* Flush the TB for the Current CPU, and update the flush stamp */
1623
1624#ifdef CONFIG_SMP
1625 /* If this is MP, wait for the other processors to finish */
1626 if (TargetAffinity)
1627 {
1628 /* Sanity check */
1629 ASSERT(Prcb == KeGetCurrentPrcb());
1630
1631 /* FIXME: TODO */
1632 ASSERTMSG("Not yet implemented\n", FALSE);
1633 }
1634#endif
1635
1636 /* Update the flush stamp and return to original IRQL */
1639}
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
ULONG_PTR KAFFINITY
Definition: compat.h:85
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: pic.c:156
#define InterlockedExchangeAdd
Definition: interlocked.h:181
#define ASSERT(a)
Definition: mode.c:44
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1150
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
KAFFINITY KeActiveProcessors
Definition: krnlinit.c:23
VOID NTAPI KiIpiSendPacket(IN KAFFINITY TargetProcessors, IN PKIPI_WORKER WorkerFunction, IN PKIPI_BROADCAST_WORKER BroadcastFunction, IN ULONG_PTR Context, IN PULONG Count)
Definition: ipi.c:45
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:526
volatile LONG KiTbFlushTimeStamp
Definition: cpu.c:33
VOID NTAPI KiFlushTargetEntireTb(IN PKIPI_CONTEXT PacketContext, IN PVOID Ignored1, IN PVOID Ignored2, IN PVOID Ignored3)
Definition: cpu.c:1573
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

◆ KeGetRecommendedSharedDataAlignment()

ULONG NTAPI KeGetRecommendedSharedDataAlignment ( VOID  )

Definition at line 1565 of file cpu.c.

1566{
1567 /* Return the global variable */
1568 return KeLargestCacheLine;
1569}
ULONG KeLargestCacheLine
Definition: cpu.c:28

◆ KeInvalidateAllCaches()

BOOLEAN NTAPI KeInvalidateAllCaches ( VOID  )

Definition at line 1146 of file cpu.c.

1147{
1148 /* Only supported on Pentium Pro and higher */
1149 if (KeI386CpuType < 6) return FALSE;
1150
1151 /* Invalidate all caches */
1152 __wbinvd();
1153 return TRUE;
1154}
#define TRUE
Definition: types.h:120
PPC_QUAL void __wbinvd(void)
Definition: intrin_ppc.h:759
ULONG KeI386CpuType
Definition: cpu.c:26

Referenced by MiMapLockedPagesInUserSpace(), and MmMapIoSpace().

◆ KeQueryActiveProcessors()

KAFFINITY NTAPI KeQueryActiveProcessors ( VOID  )

Definition at line 1657 of file cpu.c.

1658{
1659 PAGED_CODE();
1660
1661 /* Simply return the number of active processors */
1662 return KeActiveProcessors;
1663}
#define PAGED_CODE()

◆ KeRestoreFloatingPointState()

NTSTATUS NTAPI KeRestoreFloatingPointState ( _In_ PKFLOATING_SAVE  Save)

Restores the original FPU state context that has been saved by a API call of KeSaveFloatingPointState. Callers are expected to restore the floating point state by calling this function when they've finished doing FPU operations.

Parameters
[in]SaveThe saved floating point context that is to be given to the function to restore the FPU state.
Returns
Returns STATUS_SUCCESS indicating the function has fully completed its operations.

Definition at line 1489 of file cpu.c.

1491{
1493
1494 /* Sanity checks */
1495 ASSERT(Save);
1498
1499 /* Cache the saved FS context */
1500 FsContext = *((PVOID *) Save);
1501
1502 /*
1503 * We have to restore the regular saved FPU
1504 * state. For this we must first do some
1505 * validation checks so that we are sure
1506 * ourselves the state context is saved
1507 * properly. Check if we are in the same
1508 * calling thread.
1509 */
1510 if (FsContext->CurrentThread != KeGetCurrentThread())
1511 {
1512 /*
1513 * This isn't the thread that saved the
1514 * FPU state context, crash the system!
1515 */
1516 KeBugCheckEx(INVALID_FLOATING_POINT_STATE,
1517 0x2,
1518 (ULONG_PTR)FsContext->CurrentThread,
1520 0);
1521 }
1522
1523 /* Are we under the same NPX interrupt level? */
1524 if (FsContext->CurrentThread->Header.NpxIrql != KeGetCurrentIrql())
1525 {
1526 /* The interrupt level has changed, crash the system! */
1527 KeBugCheckEx(INVALID_FLOATING_POINT_STATE,
1528 0x1,
1529 (ULONG_PTR)FsContext->CurrentThread->Header.NpxIrql,
1531 0);
1532 }
1533
1534 /* Disable interrupts */
1535 _disable();
1536
1537 /*
1538 * The saved FPU state context is valid,
1539 * it's time to restore the state. First,
1540 * clear FPU exceptions now.
1541 */
1542 Ke386ClearFpExceptions();
1543
1544 /* Restore the state */
1545 Ke386RestoreFpuState(FsContext->PfxSaveArea);
1546
1547 /* Give the saved NPX IRQL back to the NPX thread */
1548 FsContext->CurrentThread->Header.NpxIrql = FsContext->OldNpxIrql;
1549
1550 /* Enable interrupts back */
1551 _enable();
1552
1553 /* We're done, free the allocated area and context */
1556
1557 return STATUS_SUCCESS;
1558}
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
_Inout_ PLIST_ENTRY _In_ PVOID FsContext
Definition: fltkernel.h:2239
#define KeGetCurrentThread
Definition: hal.h:55
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
ULONG KeI386NpxPresent
Definition: cpu.c:29
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TAG_FLOATING_POINT_CONTEXT
Definition: tag.h:44
#define TAG_FLOATING_POINT_FX
Definition: tag.h:43
static int Save(const char **args)
Definition: vfdcmd.c:1851

◆ KeSaveFloatingPointState()

NTSTATUS NTAPI KeSaveFloatingPointState ( _Out_ PKFLOATING_SAVE  Save)

Saves the current floating point unit state context of the current calling thread.

Parameters
[out]SaveThe saved floating point context given to the caller at the end of function's operations. The structure whose data contents are opaque to the calling thread.
Returns
Returns STATUS_SUCCESS if the function has successfully completed its operations. STATUS_INSUFFICIENT_RESOURCES is returned if the function couldn't allocate memory for FPU state information.
Remarks
The function performs a FPU state save in two ways. A normal FPU save (FNSAVE) is performed if the system doesn't have SSE/SSE2, otherwise the function performs a save of FPU, MMX and SSE states save (FXSAVE).

Definition at line 1363 of file cpu.c.

1365{
1367 PFX_SAVE_AREA FxSaveAreaFrame;
1368 PKPRCB CurrentPrcb;
1369
1370 /* Sanity checks */
1371 ASSERT(Save);
1374
1375 /* Initialize the floating point context */
1377 sizeof(FLOATING_SAVE_CONTEXT),
1379 if (!FsContext)
1380 {
1381 /* Bail out if we failed */
1383 }
1384
1385 /*
1386 * Allocate some memory pool for the buffer. The size
1387 * of this allocated buffer is the FX area plus the
1388 * alignment requirement needed for FXSAVE as a 16-byte
1389 * aligned pointer is compulsory in order to save the
1390 * FPU state.
1391 */
1393 sizeof(FX_SAVE_AREA) + FXSAVE_ALIGN,
1395 if (!FsContext->Buffer)
1396 {
1397 /* Bail out if we failed */
1400 }
1401
1402 /*
1403 * Now cache the allocated buffer into the save area
1404 * and align the said area to a 16-byte boundary. Why
1405 * do we have to do this is because of ExAllocate function.
1406 * We gave the necessary alignment requirement in the pool
1407 * allocation size although the function will always return
1408 * a 8-byte aligned pointer. Aligning the given pointer directly
1409 * can cause issues when freeing it from memory afterwards. With
1410 * that said, we have to cache the buffer to the area so that we
1411 * do not touch or mess the allocated buffer any further.
1412 */
1413 FsContext->PfxSaveArea = ALIGN_UP_POINTER_BY(FsContext->Buffer, 16);
1414
1415 /* Disable interrupts and get the current processor control region */
1416 _disable();
1417 CurrentPrcb = KeGetCurrentPrcb();
1418
1419 /* Store the current thread to context */
1420 FsContext->CurrentThread = KeGetCurrentThread();
1421
1422 /*
1423 * Save the previous NPX thread state registers (aka Numeric
1424 * Processor eXtension) into the current context so that
1425 * we are informing the scheduler the current FPU state
1426 * belongs to this thread.
1427 */
1428 if (FsContext->CurrentThread != CurrentPrcb->NpxThread)
1429 {
1430 if ((CurrentPrcb->NpxThread != NULL) &&
1431 (CurrentPrcb->NpxThread->NpxState == NPX_STATE_LOADED))
1432 {
1433 /* Get the FX frame */
1434 FxSaveAreaFrame = KiGetThreadNpxArea(CurrentPrcb->NpxThread);
1435
1436 /* Save the FPU state */
1437 Ke386SaveFpuState(FxSaveAreaFrame);
1438
1439 /* NPX thread has lost its state */
1440 CurrentPrcb->NpxThread->NpxState = NPX_STATE_NOT_LOADED;
1441 FxSaveAreaFrame->NpxSavedCpu = 0;
1442 }
1443
1444 /* The new NPX thread is the current thread */
1445 CurrentPrcb->NpxThread = FsContext->CurrentThread;
1446 }
1447
1448 /* Perform the save */
1449 Ke386SaveFpuState(FsContext->PfxSaveArea);
1450
1451 /* Store the NPX IRQL */
1452 FsContext->OldNpxIrql = FsContext->CurrentThread->Header.NpxIrql;
1453
1454 /* Set the current IRQL to NPX */
1455 FsContext->CurrentThread->Header.NpxIrql = KeGetCurrentIrql();
1456
1457 /* Initialize the FPU */
1458 Ke386FnInit();
1459
1460 /* Enable interrupts back */
1461 _enable();
1462
1463 /* Give the saved FPU context to the caller */
1464 *((PVOID *) Save) = FsContext;
1465 return STATUS_SUCCESS;
1466}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define NPX_STATE_NOT_LOADED
Definition: asm.h:265
#define NPX_STATE_LOADED
Definition: asm.h:266
FORCEINLINE PFX_SAVE_AREA KiGetThreadNpxArea(IN PKTHREAD Thread)
Definition: ke.h:733
#define FXSAVE_ALIGN
Definition: cpu.c:81
ULONG NpxSavedCpu
Definition: ketypes.h:504
struct _KTHREAD * NpxThread
Definition: ketypes.h:567
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ALIGN_UP_POINTER_BY(ptr, align)
Definition: umtypes.h:85

◆ KeSaveStateForHibernate()

VOID __cdecl KeSaveStateForHibernate ( IN PKPROCESSOR_STATE  State)

Definition at line 1670 of file cpu.c.

1671{
1672 /* Capture the context */
1673 RtlCaptureContext(&State->ContextFrame);
1674
1675 /* Capture the control state */
1677}
NTSYSAPI VOID NTAPI RtlCaptureContext(_Out_ PCONTEXT ContextRecord)
VOID NTAPI KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
Definition: cpu.c:576

◆ KeSetDmaIoCoherency()

VOID NTAPI KeSetDmaIoCoherency ( IN ULONG  Coherency)

Definition at line 1646 of file cpu.c.

1647{
1648 /* Save the coherency globally */
1649 KiDmaIoCoherency = Coherency;
1650}
ULONG KiDmaIoCoherency
Definition: cpu.c:29

◆ Ki386EnableDE()

ULONG_PTR NTAPI Ki386EnableDE ( IN ULONG_PTR  Context)

Definition at line 1065 of file cpu.c.

1066{
1067 /* Enable DE */
1069 return 0;
1070}
#define CR4_DE
Definition: ketypes.h:137

Referenced by KiInitMachineDependent().

◆ Ki386EnableFxsr()

ULONG_PTR NTAPI Ki386EnableFxsr ( IN ULONG_PTR  Context)

Definition at line 1075 of file cpu.c.

1076{
1077 /* Enable FXSR */
1079 return 0;
1080}
#define CR4_FXSR
Definition: ketypes.h:142

Referenced by KiInitMachineDependent().

◆ Ki386EnableXMMIExceptions()

ULONG_PTR NTAPI Ki386EnableXMMIExceptions ( IN ULONG_PTR  Context)

Definition at line 1085 of file cpu.c.

1086{
1087 PKIDTENTRY IdtEntry;
1088
1089 /* Get the IDT Entry for Interrupt 0x13 */
1090 IdtEntry = &((PKIPCR)KeGetPcr())->IDT[0x13];
1091
1092 /* Set it up */
1093 IdtEntry->Selector = KGDT_R0_CODE;
1094 IdtEntry->Offset = ((ULONG_PTR)KiTrap13 & 0xFFFF);
1095 IdtEntry->ExtendedOffset = ((ULONG_PTR)KiTrap13 >> 16) & 0xFFFF;
1096 ((PKIDT_ACCESS)&IdtEntry->Access)->Dpl = 0;
1097 ((PKIDT_ACCESS)&IdtEntry->Access)->Present = 1;
1098 ((PKIDT_ACCESS)&IdtEntry->Access)->SegmentType = I386_INTERRUPT_GATE;
1099
1100 /* Enable XMMI exceptions */
1102 return 0;
1103}
#define ULONG_PTR
Definition: config.h:101
#define CR4_XMMEXCPT
Definition: ketypes.h:143
struct _KIPCR * PKIPCR
#define I386_INTERRUPT_GATE
Definition: ketypes.h:113
struct _KIDT_ACCESS * PKIDT_ACCESS
#define KeGetPcr()
Definition: ketypes.h:81
#define KGDT_R0_CODE
Definition: ketypes.h:123
VOID __cdecl KiTrap13(VOID)
USHORT Offset
Definition: ketypes.h:440
USHORT Selector
Definition: ketypes.h:441
USHORT Access
Definition: ketypes.h:442
USHORT ExtendedOffset
Definition: ketypes.h:443

Referenced by KiInitMachineDependent().

◆ Ki386InitializeTss()

VOID FASTCALL Ki386InitializeTss ( IN PKTSS  Tss,
IN PKIDTENTRY  Idt,
IN PKGDTENTRY  Gdt 
)

Definition at line 819 of file cpu.c.

822{
823 PKGDTENTRY TssEntry, TaskGateEntry;
824
825 /* Initialize the boot TSS. */
826 TssEntry = &Gdt[KGDT_TSS / sizeof(KGDTENTRY)];
827 TssEntry->HighWord.Bits.Type = I386_TSS;
828 TssEntry->HighWord.Bits.Pres = 1;
829 TssEntry->HighWord.Bits.Dpl = 0;
830 KiInitializeTSS2(Tss, TssEntry);
831 KiInitializeTSS(Tss);
832
833 /* Load the task register */
834 Ke386SetTr(KGDT_TSS);
835
836 /* Setup the Task Gate for Double Fault Traps */
837 TaskGateEntry = (PKGDTENTRY)&Idt[8];
838 TaskGateEntry->HighWord.Bits.Type = I386_TASK_GATE;
839 TaskGateEntry->HighWord.Bits.Pres = 1;
840 TaskGateEntry->HighWord.Bits.Dpl = 0;
841 ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_DF_TSS;
842
843 /* Initialize the TSS used for handling double faults. */
844 Tss = (PKTSS)KiDoubleFaultTSS;
845 KiInitializeTSS(Tss);
846 Tss->CR3 = __readcr3();
847 Tss->Esp0 = KiDoubleFaultStack;
848 Tss->Esp = KiDoubleFaultStack;
849 Tss->Eip = PtrToUlong(KiTrap08);
850 Tss->Cs = KGDT_R0_CODE;
851 Tss->Fs = KGDT_R0_PCR;
852 Tss->Ss = Ke386GetSs();
853 Tss->Es = KGDT_R3_DATA | RPL_MASK;
854 Tss->Ds = KGDT_R3_DATA | RPL_MASK;
855
856 /* Setup the Double Trap TSS entry in the GDT */
857 TssEntry = &Gdt[KGDT_DF_TSS / sizeof(KGDTENTRY)];
858 TssEntry->HighWord.Bits.Type = I386_TSS;
859 TssEntry->HighWord.Bits.Pres = 1;
860 TssEntry->HighWord.Bits.Dpl = 0;
861 TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF);
862 TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16);
863 TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
864 TssEntry->LimitLow = KTSS_IO_MAPS;
865
866 /* Now setup the NMI Task Gate */
867 TaskGateEntry = (PKGDTENTRY)&Idt[2];
868 TaskGateEntry->HighWord.Bits.Type = I386_TASK_GATE;
869 TaskGateEntry->HighWord.Bits.Pres = 1;
870 TaskGateEntry->HighWord.Bits.Dpl = 0;
871 ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_NMI_TSS;
872
873 /* Initialize the actual TSS */
874 Tss = (PKTSS)KiNMITSS;
875 KiInitializeTSS(Tss);
876 Tss->CR3 = __readcr3();
877 Tss->Esp0 = KiDoubleFaultStack;
878 Tss->Esp = KiDoubleFaultStack;
879 Tss->Eip = PtrToUlong(KiTrap02);
880 Tss->Cs = KGDT_R0_CODE;
881 Tss->Fs = KGDT_R0_PCR;
882 Tss->Ss = Ke386GetSs();
883 Tss->Es = KGDT_R3_DATA | RPL_MASK;
884 Tss->Ds = KGDT_R3_DATA | RPL_MASK;
885
886 /* And its associated TSS Entry */
887 TssEntry = &Gdt[KGDT_NMI_TSS / sizeof(KGDTENTRY)];
888 TssEntry->HighWord.Bits.Type = I386_TSS;
889 TssEntry->HighWord.Bits.Pres = 1;
890 TssEntry->HighWord.Bits.Dpl = 0;
891 TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF);
892 TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16);
893 TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
894 TssEntry->LimitLow = KTSS_IO_MAPS;
895}
#define PtrToUlong(u)
Definition: config.h:107
#define PKIDTENTRY
Definition: ketypes.h:554
#define I386_TASK_GATE
Definition: ketypes.h:109
#define I386_TSS
Definition: ketypes.h:110
#define PKTSS
Definition: ketypes.h:996
#define PKGDTENTRY
Definition: ketypes.h:512
#define KGDTENTRY
Definition: ketypes.h:511
#define RPL_MASK
Definition: ketypes.h:119
#define KTSS_IO_MAPS
Definition: asm.h:84
#define KGDT_R3_DATA
Definition: ketypes.h:126
#define KGDT_NMI_TSS
Definition: ketypes.h:133
#define KGDT_TSS
Definition: ketypes.h:127
#define KGDT_R0_PCR
Definition: ketypes.h:128
#define KGDT_DF_TSS
Definition: ketypes.h:132
VOID __cdecl KiTrap02(VOID)
VOID __cdecl KiTrap08(VOID)
ULONG_PTR KiDoubleFaultStack
Definition: kiinit.c:22
UCHAR KiDoubleFaultTSS[KTSS_IO_MAPS]
Definition: cpu.c:20
VOID NTAPI KiInitializeTSS(IN PKTSS Tss)
Definition: cpu.c:803
VOID NTAPI KiInitializeTSS2(IN PKTSS Tss, IN PKGDTENTRY TssEntry OPTIONAL)
Definition: cpu.c:765
UCHAR KiNMITSS[KTSS_IO_MAPS]
Definition: cpu.c:23
unsigned short USHORT
Definition: pedump.c:61
struct _KGDTENTRY::@2455::@2456 Bytes
USHORT BaseLow
Definition: ketypes.h:390
USHORT LimitLow
Definition: ketypes.h:389
struct _KGDTENTRY::@2455::@2457 Bits
union _KGDTENTRY::@2455 HighWord
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by KiSystemStartup().

◆ KiCoprocessorError()

VOID NTAPI KiCoprocessorError ( VOID  )

Definition at line 1321 of file cpu.c.

1322{
1323 PFX_SAVE_AREA NpxArea;
1324
1325 /* Get the FPU area */
1327
1328 /* Set CR0_TS */
1329 NpxArea->Cr0NpxState = CR0_TS;
1331}
__INTRIN_INLINE unsigned long __readcr0(void)
Definition: intrin_x86.h:1804
__INTRIN_INLINE void __writecr0(unsigned int Data)
Definition: intrin_x86.h:1789
#define CR0_TS
Definition: asm.h:248
ULONG Cr0NpxState
Definition: ketypes.h:505

◆ KiFlushNPXState()

VOID NTAPI KiFlushNPXState ( IN PFLOATING_SAVE_AREA  SaveArea)

Definition at line 1230 of file cpu.c.

1231{
1232 ULONG EFlags, Cr0;
1233 PKTHREAD Thread, NpxThread;
1234 PFX_SAVE_AREA FxSaveArea;
1235
1236 /* Save volatiles and disable interrupts */
1237 EFlags = __readeflags();
1238 _disable();
1239
1240 /* Save the PCR and get the current thread */
1242
1243 /* Check if we're already loaded */
1244 if (Thread->NpxState != NPX_STATE_LOADED)
1245 {
1246 /* If there's nothing to load, quit */
1247 if (!SaveArea)
1248 {
1249 /* Restore interrupt state and return */
1250 __writeeflags(EFlags);
1251 return;
1252 }
1253
1254 /* Need FXSR support for this */
1256
1257 /* Check for sane CR0 */
1258 Cr0 = __readcr0();
1259 if (Cr0 & (CR0_MP | CR0_TS | CR0_EM))
1260 {
1261 /* Mask out FPU flags */
1262 __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
1263 }
1264
1265 /* Get the NPX thread and check its FPU state */
1266 NpxThread = KeGetCurrentPrcb()->NpxThread;
1267 if ((NpxThread) && (NpxThread->NpxState == NPX_STATE_LOADED))
1268 {
1269 /* Get the FX frame and store the state there */
1270 FxSaveArea = KiGetThreadNpxArea(NpxThread);
1271 Ke386FxSave(FxSaveArea);
1272
1273 /* NPX thread has lost its state */
1274 NpxThread->NpxState = NPX_STATE_NOT_LOADED;
1275 }
1276
1277 /* Now load NPX state from the NPX area */
1278 FxSaveArea = KiGetThreadNpxArea(Thread);
1279 Ke386FxStore(FxSaveArea);
1280 }
1281 else
1282 {
1283 /* Check for sane CR0 */
1284 Cr0 = __readcr0();
1285 if (Cr0 & (CR0_MP | CR0_TS | CR0_EM))
1286 {
1287 /* Mask out FPU flags */
1288 __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
1289 }
1290
1291 /* Get FX frame */
1292 FxSaveArea = KiGetThreadNpxArea(Thread);
1293 Thread->NpxState = NPX_STATE_NOT_LOADED;
1294
1295 /* Save state if supported by CPU */
1296 if (KeI386FxsrPresent) Ke386FxSave(FxSaveArea);
1297 }
1298
1299 /* Now save the FN state wherever it was requested */
1300 if (SaveArea) Ke386FnSave(SaveArea);
1301
1302 /* Clear NPX thread */
1303 KeGetCurrentPrcb()->NpxThread = NULL;
1304
1305 /* Add the CR0 from the NPX frame */
1306 Cr0 |= NPX_STATE_NOT_LOADED;
1307 Cr0 |= FxSaveArea->Cr0NpxState;
1308 __writecr0(Cr0);
1309
1310 /* Restore interrupt state */
1311 __writeeflags(EFlags);
1312}
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1669
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1674
#define CR0_MP
Definition: asm.h:246
#define CR0_EM
Definition: asm.h:247
ULONG KeI386FxsrPresent
Definition: cpu.c:33
ULONG64 NpxState
Definition: ketypes.h:2068

◆ KiFlushTargetEntireTb()

VOID NTAPI KiFlushTargetEntireTb ( IN PKIPI_CONTEXT  PacketContext,
IN PVOID  Ignored1,
IN PVOID  Ignored2,
IN PVOID  Ignored3 
)

Definition at line 1573 of file cpu.c.

1577{
1578 /* Signal this packet as done */
1579 KiIpiSignalPacketDone(PacketContext);
1580
1581 /* Flush the TB for the Current CPU */
1583}
VOID FASTCALL KiIpiSignalPacketDone(IN PKIPI_CONTEXT PacketContext)
Definition: ipi.c:57

Referenced by KeFlushEntireTb().

◆ KiGetCacheInformation()

VOID NTAPI KiGetCacheInformation ( VOID  )

Definition at line 485 of file cpu.c.

486{
487 PKIPCR Pcr = (PKIPCR)KeGetPcr();
488 CPU_INFO CpuInfo;
489 ULONG CacheRequests = 0, i;
490 ULONG CurrentRegister;
491 UCHAR RegisterByte, Associativity = 0;
492 ULONG Size, CacheLine = 64, CurrentSize = 0;
493 BOOLEAN FirstPass = TRUE;
494
495 /* Set default L2 size */
496 Pcr->SecondLevelCacheSize = 0;
497
498 /* Check the Vendor ID */
499 switch (KiGetCpuVendor())
500 {
501 /* Handle Intel case */
502 case CPU_INTEL:
503
504 /* Check if we support CPUID 2 */
505 KiCpuId(&CpuInfo, 0);
506 if (CpuInfo.Eax >= 2)
507 {
508 /* We need to loop for the number of times CPUID will tell us to */
509 do
510 {
511 /* Do the CPUID call */
512 KiCpuId(&CpuInfo, 2);
513
514 /* Check if it was the first call */
515 if (FirstPass)
516 {
517 /*
518 * The number of times to loop is the first byte. Read
519 * it and then destroy it so we don't get confused.
520 */
521 CacheRequests = CpuInfo.Eax & 0xFF;
522 CpuInfo.Eax &= 0xFFFFFF00;
523
524 /* Don't go over this again */
525 FirstPass = FALSE;
526 }
527
528 /* Loop all 4 registers */
529 for (i = 0; i < 4; i++)
530 {
531 /* Get the current register */
532 CurrentRegister = CpuInfo.AsUINT32[i];
533
534 /*
535 * If the upper bit is set, then this register should
536 * be skipped.
537 */
538 if (CurrentRegister & 0x80000000) continue;
539
540 /* Keep looping for every byte inside this register */
541 while (CurrentRegister)
542 {
543 /* Read a byte, skip a byte. */
544 RegisterByte = (UCHAR)(CurrentRegister & 0xFF);
545 CurrentRegister >>= 8;
546 if (!RegisterByte) continue;
547
548 Size = 0;
549 switch (RegisterByte)
550 {
551 case 0x06:
552 case 0x08:
554 break;
555 case 0x09:
557 break;
558 case 0x0a:
559 case 0x0c:
561 break;
562 case 0x0d:
563 case 0x0e:
565 break;
566 case 0x1d:
567 Size = 128 * 1024;
568 Associativity = 2;
569 break;
570 case 0x21:
571 Size = 256 * 1024;
572 Associativity = 8;
573 break;
574 case 0x24:
575 Size = 1024 * 1024;
576 Associativity = 16;
577 break;
578 case 0x2c:
579 case 0x30:
581 break;
582 case 0x41:
583 case 0x42:
584 case 0x43:
585 case 0x44:
586 case 0x45:
587 Size = (1 << (RegisterByte - 0x41)) * 128 * 1024;
588 Associativity = 4;
589 break;
590 case 0x48:
591 Size = 3 * 1024 * 1024;
592 Associativity = 12;
593 break;
594 case 0x49:
595 Size = 4 * 1024 * 1024;
596 Associativity = 16;
597 break;
598 case 0x4e:
599 Size = 6 * 1024 * 1024;
600 Associativity = 24;
601 break;
602 case 0x60:
603 case 0x66:
604 case 0x67:
605 case 0x68:
607 break;
608 case 0x78:
609 Size = 1024 * 1024;
610 Associativity = 4;
611 break;
612 case 0x79:
613 case 0x7a:
614 case 0x7b:
615 case 0x7c:
616 case 0x7d:
617 Size = (1 << (RegisterByte - 0x79)) * 128 * 1024;
618 Associativity = 8;
619 break;
620 case 0x7f:
621 Size = 512 * 1024;
622 Associativity = 2;
623 break;
624 case 0x80:
625 Size = 512 * 1024;
626 Associativity = 8;
627 break;
628 case 0x82:
629 case 0x83:
630 case 0x84:
631 case 0x85:
632 Size = (1 << (RegisterByte - 0x82)) * 256 * 1024;
633 Associativity = 8;
634 break;
635 case 0x86:
636 Size = 512 * 1024;
637 Associativity = 4;
638 break;
639 case 0x87:
640 Size = 1024 * 1024;
641 Associativity = 8;
642 break;
643 case 0xf0:
645 break;
646 case 0xf1:
648 break;
649 }
650 if (Size && (Size / Associativity) > CurrentSize)
651 {
652 /* Set the L2 Cache Size and Associativity */
653 CurrentSize = Size / Associativity;
655 Pcr->SecondLevelCacheAssociativity = Associativity;
656 }
657 }
658 }
659 } while (--CacheRequests);
660 }
661 break;
662
663 case CPU_AMD:
664
665 /* Check if we support CPUID 0x80000005 */
666 KiCpuId(&CpuInfo, 0x80000000);
667 if (CpuInfo.Eax >= 0x80000005)
668 {
669 /* Get L1 size first */
670 KiCpuId(&CpuInfo, 0x80000005);
671 KePrefetchNTAGranularity = CpuInfo.Ecx & 0xFF;
672
673 /* Check if we support CPUID 0x80000006 */
674 KiCpuId(&CpuInfo, 0x80000000);
675 if (CpuInfo.Eax >= 0x80000006)
676 {
677 /* Get 2nd level cache and tlb size */
678 KiCpuId(&CpuInfo, 0x80000006);
679
680 /* Cache line size */
681 CacheLine = CpuInfo.Ecx & 0xFF;
682
683 /* Hardcode associativity */
684 RegisterByte = (CpuInfo.Ecx >> 12) & 0xFF;
685 switch (RegisterByte)
686 {
687 case 2:
688 Associativity = 2;
689 break;
690
691 case 4:
692 Associativity = 4;
693 break;
694
695 case 6:
696 Associativity = 8;
697 break;
698
699 case 8:
700 case 15:
701 Associativity = 16;
702 break;
703
704 default:
705 Associativity = 1;
706 break;
707 }
708
709 /* Compute size */
710 Size = (CpuInfo.Ecx >> 16) << 10;
711
712 /* Hack for Model 6, Steping 300 */
713 if ((KeGetCurrentPrcb()->CpuType == 6) &&
714 (KeGetCurrentPrcb()->CpuStep == 0x300))
715 {
716 /* Stick 64K in there */
717 Size = 64 * 1024;
718 }
719
720 /* Set the L2 Cache Size and associativity */
722 Pcr->SecondLevelCacheAssociativity = Associativity;
723 }
724 }
725 break;
726
727 case CPU_CYRIX:
728 case CPU_TRANSMETA:
729 case CPU_CENTAUR:
730 case CPU_RISE:
731
732 /* FIXME */
733 break;
734 }
735
736 /* Set the cache line */
737 if (CacheLine > KeLargestCacheLine) KeLargestCacheLine = CacheLine;
738 DPRINT1("Prefetch Cache: %lu bytes\tL2 Cache: %lu bytes\tL2 Cache Line: %lu bytes\tL2 Cache Associativity: %lu\n",
743}
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
@ CPU_INTEL
Definition: ketypes.h:95
@ CPU_AMD
Definition: ketypes.h:94
@ CPU_RISE
Definition: ketypes.h:96
@ CPU_CENTAUR
Definition: ketypes.h:95
@ CPU_CYRIX
Definition: ketypes.h:92
@ CPU_TRANSMETA
Definition: ketypes.h:93
ULONG NTAPI KiGetCpuVendor(VOID)
Definition: cpu.c:59
ULONG KePrefetchNTAGranularity
Definition: cpu.c:41
ULONG SecondLevelCacheSize
Definition: ketypes.h:957
UCHAR SecondLevelCacheAssociativity
Definition: ketypes.h:948
ULONG Eax
Definition: ketypes.h:370
UINT32 AsUINT32[4]
Definition: ketypes.h:367
ULONG Ecx
Definition: ketypes.h:372
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

Referenced by KiInitializeKernel(), and KiSystemStartupBootStack().

◆ KiGetCpuVendor()

ULONG NTAPI KiGetCpuVendor ( VOID  )

Definition at line 110 of file cpu.c.

111{
112 PKPRCB Prcb = KeGetCurrentPrcb();
113 CPU_INFO CpuInfo;
114
115 /* Get the Vendor ID */
116 KiCpuId(&CpuInfo, 0);
117
118 /* Copy it to the PRCB and null-terminate it */
119 *(ULONG*)&Prcb->VendorString[0] = CpuInfo.Ebx;
120 *(ULONG*)&Prcb->VendorString[4] = CpuInfo.Edx;
121 *(ULONG*)&Prcb->VendorString[8] = CpuInfo.Ecx;
122 Prcb->VendorString[12] = 0;
123
124 /* Now check the CPU Type */
126 {
127 return CPU_INTEL;
128 }
129 else if (!strcmp(Prcb->VendorString, CmpAmdID))
130 {
131 return CPU_AMD;
132 }
133 else if (!strcmp(Prcb->VendorString, CmpCyrixID))
134 {
135 DPRINT1("Cyrix CPU support not fully tested!\n");
136 return CPU_CYRIX;
137 }
138 else if (!strcmp(Prcb->VendorString, CmpTransmetaID))
139 {
140 DPRINT1("Transmeta CPU support not fully tested!\n");
141 return CPU_TRANSMETA;
142 }
143 else if (!strcmp(Prcb->VendorString, CmpCentaurID))
144 {
145 DPRINT1("Centaur CPU support not fully tested!\n");
146 return CPU_CENTAUR;
147 }
148 else if (!strcmp(Prcb->VendorString, CmpRiseID))
149 {
150 DPRINT1("Rise CPU support not fully tested!\n");
151 return CPU_RISE;
152 }
153
154 /* Unknown CPU */
155 DPRINT1("%s CPU support not fully tested!\n", Prcb->VendorString);
156 return CPU_UNKNOWN;
157}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
if(dx< 0)
Definition: linetemp.h:194
@ CPU_UNKNOWN
Definition: ketypes.h:93
static const CHAR CmpIntelID[]
Definition: cpu.c:36
static const CHAR CmpAmdID[]
Definition: cpu.c:37
static const CHAR CmpCentaurID[]
Definition: cpu.c:38
static const CHAR CmpTransmetaID[]
Definition: cpu.c:61
static const CHAR CmpRiseID[]
Definition: cpu.c:63
static const CHAR CmpCyrixID[]
Definition: cpu.c:60
UCHAR VendorString[13]
Definition: ketypes.h:870
ULONG Ebx
Definition: ketypes.h:371
ULONG Edx
Definition: ketypes.h:373

◆ KiGetFeatureBits()

ULONG NTAPI KiGetFeatureBits ( VOID  )

Evaluates the KeFeatureFlag bits for the current CPU.

Returns
The feature flags for this CPU.
See also
https://www.geoffchappell.com/studies/windows/km/ntoskrnl/structs/kprcb/featurebits.htm
Todo:
  • KF_VIRT_FIRMWARE_ENABLED 0x08000000 (see notes from Geoff Chappell)
  • KF_FPU_LEAKAGE 0x0000020000000000ULL
  • KF_CAT 0x0000100000000000ULL
  • KF_CET_SS 0x0000400000000000ULL

Definition at line 214 of file cpu.c.

215{
216 PKPRCB Prcb = KeGetCurrentPrcb();
217 ULONG Vendor;
218 ULONG FeatureBits = KF_WORKING_PTE;
219 CPU_INFO CpuInfo, DummyCpuInfo;
220 UCHAR Ccr1;
221 BOOLEAN ExtendedCPUID = TRUE;
222 ULONG CpuFeatures = 0;
223
224 /* Get the Vendor ID */
225 Vendor = KiGetCpuVendor();
226
227 /* Make sure we got a valid vendor ID at least. */
228 if (!Vendor) return FeatureBits;
229
230 /* Get the CPUID Info. Features are in Reg[3]. */
231 KiCpuId(&CpuInfo, 1);
232
233 /* Set the initial APIC ID */
234 Prcb->InitialApicId = (UCHAR)(CpuInfo.Ebx >> 24);
235
236 switch (Vendor)
237 {
238 /* Intel CPUs */
239 case CPU_INTEL:
240
241 /* Check if it's a P6 */
242 if (Prcb->CpuType == 6)
243 {
244 /* Perform the special sequence to get the MicroCode Signature */
245 __writemsr(0x8B, 0);
246 KiCpuId(&DummyCpuInfo, 1);
247 Prcb->UpdateSignature.QuadPart = __readmsr(0x8B);
248 }
249 else if (Prcb->CpuType == 5)
250 {
251 /* On P5, enable workaround for the LOCK errata. */
253 }
254
255 /* Check for broken P6 with bad SMP PTE implementation */
256 if (((CpuInfo.Eax & 0x0FF0) == 0x0610 && (CpuInfo.Eax & 0x000F) <= 0x9) ||
257 ((CpuInfo.Eax & 0x0FF0) == 0x0630 && (CpuInfo.Eax & 0x000F) <= 0x4))
258 {
259 /* Remove support for correct PTE support. */
260 FeatureBits &= ~KF_WORKING_PTE;
261 }
262
263 /* Check if the CPU is too old to support SYSENTER */
264 if ((Prcb->CpuType < 6) ||
265 ((Prcb->CpuType == 6) && (Prcb->CpuStep < 0x0303)))
266 {
267 /* Disable it */
268 CpuInfo.Edx &= ~0x800;
269 }
270
271 break;
272
273 /* AMD CPUs */
274 case CPU_AMD:
275
276 /* Check if this is a K5 or K6. (family 5) */
277 if ((CpuInfo.Eax & 0x0F00) == 0x0500)
278 {
279 /* Get the Model Number */
280 switch (CpuInfo.Eax & 0x00F0)
281 {
282 /* Model 1: K5 - 5k86 (initial models) */
283 case 0x0010:
284
285 /* Check if this is Step 0 or 1. They don't support PGE */
286 if ((CpuInfo.Eax & 0x000F) > 0x03) break;
287
288 /* Model 0: K5 - SSA5 */
289 case 0x0000:
290
291 /* Model 0 doesn't support PGE at all. */
292 CpuInfo.Edx &= ~0x2000;
293 break;
294
295 /* Model 8: K6-2 */
296 case 0x0080:
297
298 /* K6-2, Step 8 and over have support for MTRR. */
299 if ((CpuInfo.Eax & 0x000F) >= 0x8) FeatureBits |= KF_AMDK6MTRR;
300 break;
301
302 /* Model 9: K6-III
303 Model D: K6-2+, K6-III+ */
304 case 0x0090:
305 case 0x00D0:
306
307 FeatureBits |= KF_AMDK6MTRR;
308 break;
309 }
310 }
311 else if((CpuInfo.Eax & 0x0F00) < 0x0500)
312 {
313 /* Families below 5 don't support PGE, PSE or CMOV at all */
314 CpuInfo.Edx &= ~(0x08 | 0x2000 | 0x8000);
315
316 /* They also don't support advanced CPUID functions. */
317 ExtendedCPUID = FALSE;
318 }
319
320 break;
321
322 /* Cyrix CPUs */
323 case CPU_CYRIX:
324
325 /* Workaround the "COMA" bug on 6x family of Cyrix CPUs */
326 if (Prcb->CpuType == 6 &&
327 Prcb->CpuStep <= 1)
328 {
329 /* Get CCR1 value */
330 Ccr1 = getCx86(CX86_CCR1);
331
332 /* Enable the NO_LOCK bit */
333 Ccr1 |= 0x10;
334
335 /* Set the new CCR1 value */
336 setCx86(CX86_CCR1, Ccr1);
337 }
338
339 break;
340
341 /* Transmeta CPUs */
342 case CPU_TRANSMETA:
343
344 /* Enable CMPXCHG8B if the family (>= 5), model and stepping (>= 4.2) support it */
345 if ((CpuInfo.Eax & 0x0FFF) >= 0x0542)
346 {
347 __writemsr(0x80860004, __readmsr(0x80860004) | 0x0100);
348 FeatureBits |= KF_CMPXCHG8B;
349 }
350
351 break;
352
353 /* Centaur, IDT, Rise and VIA CPUs */
354 case CPU_CENTAUR:
355 case CPU_RISE:
356
357 /* These CPUs don't report the presence of CMPXCHG8B through CPUID.
358 However, this feature exists and operates properly without any additional steps. */
359 FeatureBits |= KF_CMPXCHG8B;
360
361 break;
362 }
363
364 /* Set the current features */
365 CpuFeatures = CpuInfo.Edx;
366
367 /* Convert all CPUID Feature bits into our format */
368 if (CpuFeatures & X86_FEATURE_VME) FeatureBits |= KF_V86_VIS | KF_CR4;
369 if (CpuFeatures & X86_FEATURE_PSE) FeatureBits |= KF_LARGE_PAGE | KF_CR4;
370 if (CpuFeatures & X86_FEATURE_TSC) FeatureBits |= KF_RDTSC;
371 if (CpuFeatures & X86_FEATURE_CX8) FeatureBits |= KF_CMPXCHG8B;
372 if (CpuFeatures & X86_FEATURE_SYSCALL) FeatureBits |= KF_FAST_SYSCALL;
373 if (CpuFeatures & X86_FEATURE_MTTR) FeatureBits |= KF_MTRR;
374 if (CpuFeatures & X86_FEATURE_PGE) FeatureBits |= KF_GLOBAL_PAGE | KF_CR4;
375 if (CpuFeatures & X86_FEATURE_CMOV) FeatureBits |= KF_CMOV;
376 if (CpuFeatures & X86_FEATURE_PAT) FeatureBits |= KF_PAT;
377 if (CpuFeatures & X86_FEATURE_DS) FeatureBits |= KF_DTS;
378 if (CpuFeatures & X86_FEATURE_MMX) FeatureBits |= KF_MMX;
379 if (CpuFeatures & X86_FEATURE_FXSR) FeatureBits |= KF_FXSR;
380 if (CpuFeatures & X86_FEATURE_SSE) FeatureBits |= KF_XMMI;
381 if (CpuFeatures & X86_FEATURE_SSE2) FeatureBits |= KF_XMMI64;
382
383 /* Check if the CPU has hyper-threading */
384 if (CpuFeatures & X86_FEATURE_HT)
385 {
386 /* Set the number of logical CPUs */
387 Prcb->LogicalProcessorsPerPhysicalProcessor = (UCHAR)(CpuInfo.Ebx >> 16);
389 {
390 /* We're on dual-core */
392 }
393 }
394 else
395 {
396 /* We only have a single CPU */
398 }
399
400 /* Check if CPUID 0x80000000 is supported */
401 if (ExtendedCPUID)
402 {
403 /* Do the call */
404 KiCpuId(&CpuInfo, 0x80000000);
405 if ((CpuInfo.Eax & 0xffffff00) == 0x80000000)
406 {
407 /* Check if CPUID 0x80000001 is supported */
408 if (CpuInfo.Eax >= 0x80000001)
409 {
410 /* Check which extended features are available. */
411 KiCpuId(&CpuInfo, 0x80000001);
412
413 /* Check if NX-bit is supported */
414 if (CpuInfo.Edx & X86_FEATURE_NX) FeatureBits |= KF_NX_BIT;
415
416 /* Now handle each features for each CPU Vendor */
417 switch (Vendor)
418 {
419 case CPU_AMD:
420 case CPU_CENTAUR:
421 if (CpuInfo.Edx & 0x80000000) FeatureBits |= KF_3DNOW;
422 break;
423 }
424 }
425 }
426 }
427
428 /* Return the Feature Bits */
429 return FeatureBits;
430}
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
#define KF_MTRR
Definition: ketypes.h:37
#define KF_DTS
Definition: ketypes.h:40
#define KF_CR4
Definition: ketypes.h:33
#define KF_XMMI64
Definition: ketypes.h:48
#define KF_CMOV
Definition: ketypes.h:34
#define KF_AMDK6MTRR
Definition: ketypes.h:46
#define KF_CMPXCHG8B
Definition: ketypes.h:38
#define KF_RDTSC
Definition: ketypes.h:32
#define KF_FAST_SYSCALL
Definition: ketypes.h:43
#define KF_3DNOW
Definition: ketypes.h:45
#define KF_NX_BIT
Definition: ketypes.h:61
#define KF_FXSR
Definition: ketypes.h:42
#define KF_LARGE_PAGE
Definition: ketypes.h:36
#define KF_XMMI
Definition: ketypes.h:44
#define KF_MMX
Definition: ketypes.h:39
#define KF_PAT
Definition: ketypes.h:41
#define KF_WORKING_PTE
Definition: ketypes.h:39
#define KF_V86_VIS
Definition: ketypes.h:30
#define X86_FEATURE_TSC
Definition: ke.h:34
#define X86_FEATURE_HT
Definition: ke.h:47
#define X86_FEATURE_SSE2
Definition: ke.h:46
#define X86_FEATURE_SSE
Definition: ke.h:45
#define X86_FEATURE_PGE
Definition: ke.h:39
#define X86_FEATURE_DS
Definition: ke.h:42
#define X86_FEATURE_VME
Definition: ke.h:31
#define X86_FEATURE_MMX
Definition: ke.h:43
#define X86_FEATURE_PSE
Definition: ke.h:33
#define X86_FEATURE_PAT
Definition: ke.h:41
#define X86_FEATURE_MTTR
Definition: ke.h:38
#define X86_FEATURE_CMOV
Definition: ke.h:40
#define X86_FEATURE_CX8
Definition: ke.h:36
#define X86_FEATURE_SYSCALL
Definition: ke.h:37
#define X86_FEATURE_NX
Definition: ke.h:63
#define X86_FEATURE_FXSR
Definition: ke.h:44
BOOLEAN KiSMTProcessorsPresent
Definition: cpu.c:30
#define CX86_CCR1
Definition: cpu.c:86
static __inline void setCx86(UCHAR reg, UCHAR data)
Definition: cpu.c:99
static __inline UCHAR getCx86(UCHAR reg)
Definition: cpu.c:91
BOOLEAN KiI386PentiumLockErrataPresent
Definition: cpu.c:42
CHAR CpuType
Definition: ketypes.h:653
USHORT CpuStep
Definition: ketypes.h:658
UCHAR LogicalProcessorsPerPhysicalProcessor
Definition: ketypes.h:759
ULONG InitialApicId
Definition: ketypes.h:690
LARGE_INTEGER UpdateSignature
Definition: ketypes.h:873
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by KiInitializeCpu(), and KiVerifyCpuFeatures().

◆ KiI386PentiumLockErrataFixup()

VOID NTAPI KiI386PentiumLockErrataFixup ( VOID  )

Definition at line 1108 of file cpu.c.

1109{
1110 KDESCRIPTOR IdtDescriptor = {0, 0, 0};
1111 PKIDTENTRY NewIdt, NewIdt2;
1112 PMMPTE PointerPte;
1113
1114 /* Allocate memory for a new IDT */
1115 NewIdt = ExAllocatePool(NonPagedPool, 2 * PAGE_SIZE);
1116
1117 /* Put everything after the first 7 entries on a new page */
1118 NewIdt2 = (PVOID)((ULONG_PTR)NewIdt + PAGE_SIZE - (7 * sizeof(KIDTENTRY)));
1119
1120 /* Disable interrupts */
1121 _disable();
1122
1123 /* Get the current IDT and copy it */
1124 __sidt(&IdtDescriptor.Limit);
1125 RtlCopyMemory(NewIdt2,
1126 (PVOID)IdtDescriptor.Base,
1127 IdtDescriptor.Limit + 1);
1128 IdtDescriptor.Base = (ULONG)NewIdt2;
1129
1130 /* Set the new IDT */
1131 __lidt(&IdtDescriptor.Limit);
1132 ((PKIPCR)KeGetPcr())->IDT = NewIdt2;
1133
1134 /* Restore interrupts */
1135 _enable();
1136
1137 /* Set the first 7 entries as read-only to produce a fault */
1138 PointerPte = MiAddressToPte(NewIdt);
1139 ASSERT(PointerPte->u.Hard.Write == 1);
1140 PointerPte->u.Hard.Write = 0;
1141 KeInvalidateTlbEntry(NewIdt);
1142}
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
__INTRIN_INLINE void __lidt(void *Source)
Definition: intrin_x86.h:2018
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2023
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define KIDTENTRY
Definition: ketypes.h:553
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:264
PVOID Base
Definition: ketypes.h:560
USHORT Limit
Definition: ketypes.h:559
ULONG64 Write
Definition: mmtypes.h:170
union _MMPTE::@2338 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by KiInitMachineDependent().

◆ KiInitializeMachineType()

VOID NTAPI KiInitializeMachineType ( VOID  )

Definition at line 1008 of file cpu.c.

1009{
1010 /* Set the Machine Type we got from NTLDR */
1012}
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
ULONG KeI386MachineType
Definition: cpu.c:34
ULONG MachineType
Definition: arc.h:454
union _LOADER_PARAMETER_BLOCK::@3373 u
I386_LOADER_BLOCK I386
Definition: arc.h:562

◆ KiInitializeTSS()

VOID NTAPI KiInitializeTSS ( IN PKTSS  Tss)

Definition at line 803 of file cpu.c.

804{
805 /* Set an invalid map base */
806 Tss->IoMapBase = KiComputeIopmOffset(IO_ACCESS_MAP_NONE);
807
808 /* Disable traps during Task Switches */
809 Tss->Flags = 0;
810
811 /* Set LDT and Ring 0 SS */
812 Tss->LDT = 0;
813 Tss->Ss0 = KGDT_R0_DATA;
814}
#define KiComputeIopmOffset(MapNumber)
Definition: ketypes.h:335
#define IO_ACCESS_MAP_NONE
Definition: ketypes.h:333
#define KGDT_R0_DATA
Definition: ketypes.h:124

Referenced by Ki386InitializeTss().

◆ KiInitializeTSS2()

VOID NTAPI KiInitializeTSS2 ( IN PKTSS  Tss,
IN PKGDTENTRY TssEntry  OPTIONAL 
)

Definition at line 765 of file cpu.c.

767{
768 PUCHAR p;
769
770 /* Make sure the GDT Entry is valid */
771 if (TssEntry)
772 {
773 /* Set the Limit */
774 TssEntry->LimitLow = sizeof(KTSS) - 1;
775 TssEntry->HighWord.Bits.LimitHi = 0;
776 }
777
778 /* Now clear the I/O Map */
779 ASSERT(IOPM_COUNT == 1);
780 RtlFillMemory(Tss->IoMaps[0].IoMap, IOPM_FULL_SIZE, 0xFF);
781
782 /* Initialize Interrupt Direction Maps */
783 p = (PUCHAR)(Tss->IoMaps[0].DirectionMap);
785
786 /* Add DPMI support for interrupts */
787 p[0] = 4;
788 p[3] = 0x18;
789 p[4] = 0x18;
790
791 /* Initialize the default Interrupt Direction Map */
792 p = Tss->IntDirectionMap;
793 RtlZeroMemory(Tss->IntDirectionMap, IOPM_DIRECTION_MAP_SIZE);
794
795 /* Add DPMI support */
796 p[0] = 4;
797 p[3] = 0x18;
798 p[4] = 0x18;
799}
GLfloat GLfloat p
Definition: glext.h:8902
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
#define KTSS
Definition: ketypes.h:995
#define IOPM_FULL_SIZE
Definition: ketypes.h:229
#define IOPM_DIRECTION_MAP_SIZE
Definition: ketypes.h:231
#define IOPM_COUNT
Definition: ketypes.h:227
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by Ki386InitializeTss().

◆ KiIsNpxErrataPresent()

BOOLEAN NTAPI KiIsNpxErrataPresent ( VOID  )

Definition at line 1179 of file cpu.c.

1180{
1181 static double Value1 = 4195835.0, Value2 = 3145727.0;
1182 INT ErrataPresent;
1183 ULONG Cr0;
1184
1185 /* Interrupts have to be disabled here. */
1187
1188 /* Read CR0 and remove FPU flags */
1189 Cr0 = __readcr0();
1190 __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
1191
1192 /* Initialize FPU state */
1193 Ke386FnInit();
1194
1195 /* Multiply the magic values and divide, we should get the result back */
1196#ifdef __GNUC__
1197 __asm__ __volatile__
1198 (
1199 "fldl %1\n\t"
1200 "fdivl %2\n\t"
1201 "fmull %2\n\t"
1202 "fldl %1\n\t"
1203 "fsubp\n\t"
1204 "fistpl %0\n\t"
1205 : "=m" (ErrataPresent)
1206 : "m" (Value1),
1207 "m" (Value2)
1208 );
1209#else
1210 __asm
1211 {
1212 fld Value1
1213 fdiv Value2
1214 fmul Value2
1215 fld Value1
1216 fsubp st(1), st(0)
1217 fistp ErrataPresent
1218 };
1219#endif
1220
1221 /* Restore CR0 */
1222 __writecr0(Cr0);
1223
1224 /* Return if there's an errata */
1225 return ErrataPresent != 0;
1226}
#define EFLAGS_INTERRUPT_MASK
Definition: SystemCall.c:11
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tsub %rbp, %rax\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tsub $32, %rsp\n" "\t.seh_stackalloc 32\n" "\t.seh_endprologue\n" "\tsub %rax, %rdx\n" "\tmov %rdx, %rbp\n" "\tjmp *%r8\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $32, %rsp\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")
int32_t INT
Definition: typedefs.h:58

Referenced by KiVerifyCpuFeatures().

◆ KiLoadFastSyscallMachineSpecificRegisters()

ULONG_PTR NTAPI KiLoadFastSyscallMachineSpecificRegisters ( IN ULONG_PTR  Context)

Definition at line 1017 of file cpu.c.

1018{
1019 /* Set CS and ESP */
1020 __writemsr(0x174, KGDT_R0_CODE);
1021 __writemsr(0x175, (ULONG_PTR)KeGetCurrentPrcb()->DpcStack);
1022
1023 /* Set LSTAR */
1025 return 0;
1026}
VOID __cdecl KiFastCallEntry(VOID)

Referenced by KiRestoreFastSyscallReturnState().

◆ KiRestoreFastSyscallReturnState()

VOID NTAPI KiRestoreFastSyscallReturnState ( VOID  )

Definition at line 1031 of file cpu.c.

1032{
1033 /* Check if the CPU Supports fast system call */
1035 {
1036 /* Check if it has been disabled */
1038 {
1039 /* Disable fast system call */
1040 KeFeatureBits &= ~KF_FAST_SYSCALL;
1042 DPRINT1("Support for SYSENTER disabled.\n");
1043 }
1044 else
1045 {
1046 /* Do an IPI to enable it */
1048
1049 /* It's enabled, so use the proper exit stub */
1051 DPRINT("Support for SYSENTER detected.\n");
1052 }
1053 }
1054 else
1055 {
1056 /* Use the IRET handler */
1058 DPRINT1("No support for SYSENTER detected.\n");
1059 }
1060}
ULONG_PTR NTAPI KeIpiGenericCall(_In_ PKIPI_BROADCAST_WORKER Function, _In_ ULONG_PTR Argument)
Definition: ipi.c:44
ULONG KiFastSystemCallDisable
Definition: cpu.c:28
ULONG_PTR NTAPI KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context)
Definition: cpu.c:1017
#define DPRINT
Definition: sndvol32.h:73
DECLSPEC_NORETURN VOID FASTCALL KiSystemCallTrapReturn(IN PKTRAP_FRAME TrapFrame)
DECLSPEC_NORETURN VOID FASTCALL KiSystemCallSysExitReturn(IN PKTRAP_FRAME TrapFrame)
PFAST_SYSTEM_CALL_EXIT KiFastCallExitHandler
Definition: traphdlr.c:56

Referenced by KiInitMachineDependent().

◆ KiRestoreProcessorControlState()

VOID NTAPI KiRestoreProcessorControlState ( PKPROCESSOR_STATE  ProcessorState)

Definition at line 936 of file cpu.c.

937{
938 PKGDTENTRY TssEntry;
939
940 //
941 // Restore the CR registers
942 //
943 __writecr0(ProcessorState->SpecialRegisters.Cr0);
944 Ke386SetCr2(ProcessorState->SpecialRegisters.Cr2);
945 __writecr3(ProcessorState->SpecialRegisters.Cr3);
946 if (KeFeatureBits & KF_CR4) __writecr4(ProcessorState->SpecialRegisters.Cr4);
947
948 //
949 // Restore the DR registers
950 //
951 __writedr(0, ProcessorState->SpecialRegisters.KernelDr0);
952 __writedr(1, ProcessorState->SpecialRegisters.KernelDr1);
953 __writedr(2, ProcessorState->SpecialRegisters.KernelDr2);
954 __writedr(3, ProcessorState->SpecialRegisters.KernelDr3);
955 __writedr(6, ProcessorState->SpecialRegisters.KernelDr6);
956 __writedr(7, ProcessorState->SpecialRegisters.KernelDr7);
957
958 //
959 // Restore GDT and IDT
960 //
962 __lidt(&ProcessorState->SpecialRegisters.Idtr.Limit);
963
964 //
965 // Clear the busy flag so we don't crash if we reload the same selector
966 //
967 TssEntry = (PKGDTENTRY)(ProcessorState->SpecialRegisters.Gdtr.Base +
968 ProcessorState->SpecialRegisters.Tr);
969 TssEntry->HighWord.Bytes.Flags1 &= ~0x2;
970
971 //
972 // Restore TSS and LDT
973 //
974 Ke386SetTr(ProcessorState->SpecialRegisters.Tr);
975 Ke386SetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr);
976}
#define Ke386SetGlobalDescriptorTable
Definition: intrin_i.h:453
__INTRIN_INLINE void __writedr(unsigned reg, unsigned int value)
Definition: intrin_x86.h:1935
ULONG Base
Definition: ketypes.h:450
USHORT Limit
Definition: ketypes.h:449
KSPECIAL_REGISTERS SpecialRegisters
Definition: ketypes.h:604
ULONG64 KernelDr1
Definition: ketypes.h:575
ULONG64 KernelDr2
Definition: ketypes.h:576
ULONG64 KernelDr0
Definition: ketypes.h:574
KDESCRIPTOR Gdtr
Definition: ketypes.h:580
KDESCRIPTOR Idtr
Definition: ketypes.h:581
ULONG64 KernelDr7
Definition: ketypes.h:579
ULONG64 KernelDr6
Definition: ketypes.h:578
ULONG64 KernelDr3
Definition: ketypes.h:577

◆ KiSaveProcessorControlState()

VOID NTAPI KiSaveProcessorControlState ( OUT PKPROCESSOR_STATE  ProcessorState)

Definition at line 980 of file cpu.c.

981{
982 /* Save the CR registers */
983 ProcessorState->SpecialRegisters.Cr0 = __readcr0();
984 ProcessorState->SpecialRegisters.Cr2 = __readcr2();
985 ProcessorState->SpecialRegisters.Cr3 = __readcr3();
986 ProcessorState->SpecialRegisters.Cr4 = (KeFeatureBits & KF_CR4) ?
987 __readcr4() : 0;
988
989 /* Save the DR registers */
990 ProcessorState->SpecialRegisters.KernelDr0 = __readdr(0);
991 ProcessorState->SpecialRegisters.KernelDr1 = __readdr(1);
992 ProcessorState->SpecialRegisters.KernelDr2 = __readdr(2);
993 ProcessorState->SpecialRegisters.KernelDr3 = __readdr(3);
994 ProcessorState->SpecialRegisters.KernelDr6 = __readdr(6);
995 ProcessorState->SpecialRegisters.KernelDr7 = __readdr(7);
996 __writedr(7, 0);
997
998 /* Save GDT, IDT, LDT and TSS */
999 Ke386GetGlobalDescriptorTable(&ProcessorState->SpecialRegisters.Gdtr.Limit);
1000 __sidt(&ProcessorState->SpecialRegisters.Idtr.Limit);
1001 ProcessorState->SpecialRegisters.Tr = Ke386GetTr();
1002 Ke386GetLocalDescriptorTable(&ProcessorState->SpecialRegisters.Ldtr);
1003}
#define Ke386GetGlobalDescriptorTable
Definition: intrin_i.h:452
#define Ke386GetLocalDescriptorTable
Definition: intrin_i.h:454
__INTRIN_INLINE unsigned int __readdr(unsigned int reg)
Definition: intrin_x86.h:1902
__INTRIN_INLINE unsigned long __readcr2(void)
Definition: intrin_x86.h:1811

Referenced by KdpCommandString(), KdpReport(), KdpSymbol(), KeBugCheckWithTf(), KiInitializeKernel(), and KiSystemStartupBootStack().

◆ KiSaveProcessorState()

VOID NTAPI KiSaveProcessorState ( IN PKTRAP_FRAME  TrapFrame,
IN PKEXCEPTION_FRAME  ExceptionFrame 
)

Definition at line 1158 of file cpu.c.

1160{
1161 PKPRCB Prcb = KeGetCurrentPrcb();
1162
1163 //
1164 // Save full context
1165 //
1169
1170 //
1171 // Save control registers
1172 //
1174}
#define CONTEXT_DEBUG_REGISTERS
Definition: nt_native.h:1373
#define CONTEXT_FULL
Definition: nt_native.h:1375
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: context.c:169
ULONG ContextFlags
Definition: nt_native.h:1426
KPROCESSOR_STATE ProcessorState
Definition: ketypes.h:652
CONTEXT ContextFrame
Definition: ketypes.h:605

◆ KiSetCR0Bits()

VOID NTAPI KiSetCR0Bits ( VOID  )

Definition at line 748 of file cpu.c.

749{
750 ULONG Cr0;
751
752 /* Save current CR0 */
753 Cr0 = __readcr0();
754
755 /* If this is a 486, enable Write-Protection */
756 if (KeGetCurrentPrcb()->CpuType > 3) Cr0 |= CR0_WP;
757
758 /* Set new Cr0 */
759 __writecr0(Cr0);
760}
#define CR0_WP
Definition: asm.h:251

Referenced by KiInitMachineDependent().

◆ KiSetProcessorType()

VOID NTAPI KiSetProcessorType ( VOID  )

Definition at line 162 of file cpu.c.

163{
164 CPU_INFO CpuInfo;
165 CPU_SIGNATURE CpuSignature;
166 BOOLEAN ExtendModel;
167 ULONG Stepping, Type;
168
169 /* Do CPUID 1 now */
170 KiCpuId(&CpuInfo, 1);
171
172 /*
173 * Get the Stepping and Type. The stepping contains both the
174 * Model and the Step, while the Type contains the returned Family.
175 *
176 * For the stepping, we convert this: zzzzzzxy into this: x0y
177 */
178 CpuSignature.AsULONG = CpuInfo.Eax;
179 Stepping = CpuSignature.Model;
180 ExtendModel = (CpuSignature.Family == 15);
181#if ( (NTDDI_VERSION >= NTDDI_WINXPSP2) && (NTDDI_VERSION < NTDDI_WS03) ) || (NTDDI_VERSION >= NTDDI_WS03SP1)
182 if (CpuSignature.Family == 6)
183 {
184 ULONG Vendor = KiGetCpuVendor();
185 ExtendModel |= (Vendor == CPU_INTEL);
186#if (NTDDI_VERSION >= NTDDI_WIN8)
187 ExtendModel |= (Vendor == CPU_CENTAUR);
188#endif
189 }
190#endif
191 if (ExtendModel)
192 {
193 /* Add ExtendedModel to distinguish from non-extended values. */
194 Stepping |= (CpuSignature.ExtendedModel << 4);
195 }
196 Stepping = (Stepping << 8) | CpuSignature.Step;
197 Type = CpuSignature.Family;
198 if (CpuSignature.Family == 15)
199 {
200 /* Add ExtendedFamily to distinguish from non-extended values.
201 * It must not be larger than 0xF0 to avoid overflow. */
202 Type += min(CpuSignature.ExtendedFamily, 0xF0);
203 }
204
205 /* Save them in the PRCB */
206 KeGetCurrentPrcb()->CpuID = TRUE;
207 KeGetCurrentPrcb()->CpuType = (UCHAR)Type;
208 KeGetCurrentPrcb()->CpuStep = (USHORT)Stepping;
209}
Type
Definition: Type.h:7
#define min(a, b)
Definition: monoChain.cc:55
ULONG ExtendedFamily
Definition: cpu.c:49
ULONG Model
Definition: cpu.c:45
ULONG Family
Definition: cpu.c:46
ULONG AsULONG
Definition: cpu.c:52
ULONG Step
Definition: cpu.c:44
ULONG ExtendedModel
Definition: cpu.c:48

Referenced by KiInitializeCpu(), and KiVerifyCpuFeatures().

◆ setCx86()

static __inline void setCx86 ( UCHAR  reg,
UCHAR  data 
)
static

Definition at line 99 of file cpu.c.

100{
103}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950

Referenced by KiGetFeatureBits().

Variable Documentation

◆ CmpAmdID

const CHAR CmpAmdID[] = "AuthenticAMD"
static

Definition at line 59 of file cpu.c.

◆ CmpCentaurID

const CHAR CmpCentaurID[] = "CentaurHauls"
static

Definition at line 62 of file cpu.c.

◆ CmpCyrixID

const CHAR CmpCyrixID[] = "CyrixInstead"
static

Definition at line 60 of file cpu.c.

Referenced by KiGetCpuVendor().

◆ CmpIntelID

const CHAR CmpIntelID[] = "GenuineIntel"
static

Definition at line 58 of file cpu.c.

◆ CmpRiseID

const CHAR CmpRiseID[] = "RiseRiseRise"
static

Definition at line 63 of file cpu.c.

Referenced by KiGetCpuVendor().

◆ CmpTransmetaID

const CHAR CmpTransmetaID[] = "GenuineTMx86"
static

Definition at line 61 of file cpu.c.

Referenced by KiGetCpuVendor().

◆ Ke386NoExecute

ULONG Ke386NoExecute = FALSE

Definition at line 36 of file cpu.c.

Referenced by ProtectToPTE().

◆ Ke386Pae

◆ KeDcacheFlushCount

ULONG KeDcacheFlushCount = 0

Definition at line 38 of file cpu.c.

◆ KeI386CpuStep

ULONG KeI386CpuStep

Definition at line 27 of file cpu.c.

Referenced by KiInitializeKernel(), and KiInitializeKernelMachineDependent().

◆ KeI386CpuType

ULONG KeI386CpuType

Definition at line 26 of file cpu.c.

Referenced by KiInitializeKernel(), and KiInitializeKernelMachineDependent().

◆ KeI386FxsrPresent

◆ KeI386MachineType

ULONG KeI386MachineType

Definition at line 34 of file cpu.c.

◆ KeI386NpxPresent

ULONG KeI386NpxPresent = TRUE

Definition at line 29 of file cpu.c.

Referenced by CmpInitializeMachineDependentConfiguration().

◆ KeI386XMMIPresent

ULONG KeI386XMMIPresent = 0

Definition at line 32 of file cpu.c.

Referenced by KiInitializeKernel().

◆ KeIcacheFlushCount

ULONG KeIcacheFlushCount = 0

Definition at line 39 of file cpu.c.

◆ KeLargestCacheLine

ULONG KeLargestCacheLine = 0x40

Definition at line 37 of file cpu.c.

◆ KePrefetchNTAGranularity

ULONG KePrefetchNTAGranularity = 32

Definition at line 41 of file cpu.c.

Referenced by KiGetCacheInformation().

◆ KiDmaIoCoherency

ULONG KiDmaIoCoherency = 0

Definition at line 40 of file cpu.c.

◆ KiDoubleFaultTSS

UCHAR KiDoubleFaultTSS[KTSS_IO_MAPS]

Definition at line 20 of file cpu.c.

Referenced by Ki386InitializeTss().

◆ KiFastCallCopyDoneOnce

BOOLEAN KiFastCallCopyDoneOnce

Definition at line 52 of file cpu.c.

◆ KiFastSystemCallDisable

ULONG KiFastSystemCallDisable = 0

Definition at line 28 of file cpu.c.

Referenced by KiRestoreFastSyscallReturnState().

◆ KiI386PentiumLockErrataPresent

BOOLEAN KiI386PentiumLockErrataPresent

Definition at line 42 of file cpu.c.

Referenced by KiGetFeatureBits(), KiInitMachineDependent(), and MiInitMachineDependent().

◆ KiMXCsrMask

ULONG KiMXCsrMask = 0

Definition at line 30 of file cpu.c.

Referenced by KeContextToTrapFrame(), and KiInitMachineDependent().

◆ KiNMITSS

UCHAR KiNMITSS[KTSS_IO_MAPS]

Definition at line 23 of file cpu.c.

Referenced by Ki386InitializeTss().

◆ KiSMTProcessorsPresent

BOOLEAN KiSMTProcessorsPresent

Definition at line 43 of file cpu.c.

◆ KiSystemCallExitAdjust

UCHAR KiSystemCallExitAdjust

Definition at line 46 of file cpu.c.

◆ KiSystemCallExitAdjusted

UCHAR KiSystemCallExitAdjusted

Definition at line 49 of file cpu.c.

◆ KiTbFlushTimeStamp

volatile LONG KiTbFlushTimeStamp

Definition at line 55 of file cpu.c.

◆ MxcsrFeatureMask

ULONG MxcsrFeatureMask = 0

Definition at line 31 of file cpu.c.