ReactOS 0.4.17-dev-683-g0dafdc5
cpu.c File Reference
#include <ntoskrnl.h>
#include <xmmintrin.h>
#include <debug.h>
Include dependency graph for cpu.c:

Go to the source code of this file.

Macros

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

Functions

static __inline UCHAR getCx86 (UCHAR reg)
 
static __inline void setCx86 (UCHAR reg, UCHAR data)
 
static ULONG KiGetCpuVendor (VOID)
 
VOID NTAPI KiSetProcessorType (VOID)
 
ULONG64 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)
 
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
 

Macro Definition Documentation

◆ CX86_CCR1

#define CX86_CCR1   0xc1

Definition at line 63 of file cpu.c.

◆ FXSAVE_ALIGN

#define FXSAVE_ALIGN   15

Definition at line 58 of file cpu.c.

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file cpu.c.

Function Documentation

◆ getCx86()

static __inline UCHAR getCx86 ( UCHAR  reg)
static

Definition at line 68 of file cpu.c.

69{
71 return READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)0x23);
72}
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 809 of file cpu.c.

810{
811
812#if !defined(_GLOBAL_PAGES_ARE_AWESOME_)
813
814 /* Flush the TLB by resetting CR3 */
816
817#else
818
819 /* Check if global pages are enabled */
821 {
822 ULONG Cr4;
823
824 /* Disable PGE (Note: may not have been enabled yet) */
825 Cr4 = __readcr4();
826 __writecr4(Cr4 & ~CR4_PGE);
827
828 /* Flush everything */
830
831 /* Re-enable PGE */
832 __writecr4(Cr4);
833 }
834 else
835 {
836 /* No global pages, resetting CR3 is enough */
838 }
839
840#endif
841
842}
ULONG64 KeFeatureBits
Definition: krnlinit.c:22
__INTRIN_INLINE unsigned long __readcr3(void)
Definition: intrin_x86.h:1850
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1857
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1826
__INTRIN_INLINE void __writecr4(unsigned int Data)
Definition: intrin_x86.h:1831
#define CR4_PGE
Definition: ketypes.h:161
#define KF_GLOBAL_PAGE
Definition: ketypes.h:35
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 1500 of file cpu.c.

1502{
1503 KIRQL OldIrql;
1504#ifdef CONFIG_SMP
1505 KAFFINITY TargetAffinity;
1506 PKPRCB Prcb = KeGetCurrentPrcb();
1507#endif
1508
1509 /* Raise the IRQL for the TB Flush */
1511
1512#ifdef CONFIG_SMP
1513 /* FIXME: Use KiTbFlushTimeStamp to synchronize TB flush */
1514
1515 /* Get the current processor affinity, and exclude ourselves */
1516 TargetAffinity = KeActiveProcessors;
1517 TargetAffinity &= ~Prcb->SetMember;
1518
1519 /* Make sure this is MP */
1520 if (TargetAffinity)
1521 {
1522 /* Send an IPI TB flush to the other processors */
1523 KiIpiSendPacket(TargetAffinity,
1525 NULL,
1526 0,
1527 NULL);
1528 }
1529#endif
1530
1531 /* Flush the TB for the Current CPU, and update the flush stamp */
1533
1534#ifdef CONFIG_SMP
1535 /* If this is MP, wait for the other processors to finish */
1536 if (TargetAffinity)
1537 {
1538 /* Sanity check */
1539 ASSERT(Prcb == KeGetCurrentPrcb());
1540
1541 /* FIXME: TODO */
1542 ASSERTMSG("Not yet implemented\n", FALSE);
1543 }
1544#endif
1545
1546 /* Update the flush stamp and return to original IRQL */
1549}
#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:196
#define ASSERT(a)
Definition: mode.c:44
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1197
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
KAFFINITY KeActiveProcessors
Definition: processor.c:16
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:437
volatile LONG KiTbFlushTimeStamp
Definition: cpu.c:34
VOID NTAPI KiFlushTargetEntireTb(IN PKIPI_CONTEXT PacketContext, IN PVOID Ignored1, IN PVOID Ignored2, IN PVOID Ignored3)
Definition: cpu.c:1483
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

◆ KeGetRecommendedSharedDataAlignment()

ULONG NTAPI KeGetRecommendedSharedDataAlignment ( VOID  )

Definition at line 1475 of file cpu.c.

1476{
1477 /* Return the global variable */
1478 return KeLargestCacheLine;
1479}
ULONG KeLargestCacheLine
Definition: cpu.c:29

◆ KeInvalidateAllCaches()

BOOLEAN NTAPI KeInvalidateAllCaches ( VOID  )

Definition at line 1056 of file cpu.c.

1057{
1058 /* Only supported on Pentium Pro and higher */
1059 if (KeI386CpuType < 6) return FALSE;
1060
1061 /* Invalidate all caches */
1062 __wbinvd();
1063 return TRUE;
1064}
#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().

◆ 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 1399 of file cpu.c.

1401{
1403
1404 /* Sanity checks */
1405 ASSERT(Save);
1408
1409 /* Cache the saved FS context */
1410 FsContext = *((PVOID *) Save);
1411
1412 /*
1413 * We have to restore the regular saved FPU
1414 * state. For this we must first do some
1415 * validation checks so that we are sure
1416 * ourselves the state context is saved
1417 * properly. Check if we are in the same
1418 * calling thread.
1419 */
1420 if (FsContext->CurrentThread != KeGetCurrentThread())
1421 {
1422 /*
1423 * This isn't the thread that saved the
1424 * FPU state context, crash the system!
1425 */
1426 KeBugCheckEx(INVALID_FLOATING_POINT_STATE,
1427 0x2,
1428 (ULONG_PTR)FsContext->CurrentThread,
1430 0);
1431 }
1432
1433 /* Are we under the same NPX interrupt level? */
1434 if (FsContext->CurrentThread->Header.NpxIrql != KeGetCurrentIrql())
1435 {
1436 /* The interrupt level has changed, crash the system! */
1437 KeBugCheckEx(INVALID_FLOATING_POINT_STATE,
1438 0x1,
1439 (ULONG_PTR)FsContext->CurrentThread->Header.NpxIrql,
1441 0);
1442 }
1443
1444 /* Disable interrupts */
1445 _disable();
1446
1447 /*
1448 * The saved FPU state context is valid,
1449 * it's time to restore the state. First,
1450 * clear FPU exceptions now.
1451 */
1452 Ke386ClearFpExceptions();
1453
1454 /* Restore the state */
1455 Ke386RestoreFpuState(FsContext->PfxSaveArea);
1456
1457 /* Give the saved NPX IRQL back to the NPX thread */
1458 FsContext->CurrentThread->Header.NpxIrql = FsContext->OldNpxIrql;
1459
1460 /* Enable interrupts back */
1461 _enable();
1462
1463 /* We're done, free the allocated area and context */
1466
1467 return STATUS_SUCCESS;
1468}
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
#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
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
ULONG KeI386NpxPresent
Definition: cpu.c:29
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
#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 1273 of file cpu.c.

1275{
1277 PFX_SAVE_AREA FxSaveAreaFrame;
1278 PKPRCB CurrentPrcb;
1279
1280 /* Sanity checks */
1281 ASSERT(Save);
1284
1285 /* Initialize the floating point context */
1287 sizeof(FLOATING_SAVE_CONTEXT),
1289 if (!FsContext)
1290 {
1291 /* Bail out if we failed */
1293 }
1294
1295 /*
1296 * Allocate some memory pool for the buffer. The size
1297 * of this allocated buffer is the FX area plus the
1298 * alignment requirement needed for FXSAVE as a 16-byte
1299 * aligned pointer is compulsory in order to save the
1300 * FPU state.
1301 */
1303 sizeof(FX_SAVE_AREA) + FXSAVE_ALIGN,
1305 if (!FsContext->Buffer)
1306 {
1307 /* Bail out if we failed */
1310 }
1311
1312 /*
1313 * Now cache the allocated buffer into the save area
1314 * and align the said area to a 16-byte boundary. Why
1315 * do we have to do this is because of ExAllocate function.
1316 * We gave the necessary alignment requirement in the pool
1317 * allocation size although the function will always return
1318 * a 8-byte aligned pointer. Aligning the given pointer directly
1319 * can cause issues when freeing it from memory afterwards. With
1320 * that said, we have to cache the buffer to the area so that we
1321 * do not touch or mess the allocated buffer any further.
1322 */
1323 FsContext->PfxSaveArea = ALIGN_UP_POINTER_BY(FsContext->Buffer, 16);
1324
1325 /* Disable interrupts and get the current processor control region */
1326 _disable();
1327 CurrentPrcb = KeGetCurrentPrcb();
1328
1329 /* Store the current thread to context */
1330 FsContext->CurrentThread = KeGetCurrentThread();
1331
1332 /*
1333 * Save the previous NPX thread state registers (aka Numeric
1334 * Processor eXtension) into the current context so that
1335 * we are informing the scheduler the current FPU state
1336 * belongs to this thread.
1337 */
1338 if (FsContext->CurrentThread != CurrentPrcb->NpxThread)
1339 {
1340 if ((CurrentPrcb->NpxThread != NULL) &&
1341 (CurrentPrcb->NpxThread->NpxState == NPX_STATE_LOADED))
1342 {
1343 /* Get the FX frame */
1344 FxSaveAreaFrame = KiGetThreadNpxArea(CurrentPrcb->NpxThread);
1345
1346 /* Save the FPU state */
1347 Ke386SaveFpuState(FxSaveAreaFrame);
1348
1349 /* NPX thread has lost its state */
1350 CurrentPrcb->NpxThread->NpxState = NPX_STATE_NOT_LOADED;
1351 FxSaveAreaFrame->NpxSavedCpu = 0;
1352 }
1353
1354 /* The new NPX thread is the current thread */
1355 CurrentPrcb->NpxThread = FsContext->CurrentThread;
1356 }
1357
1358 /* Perform the save */
1359 Ke386SaveFpuState(FsContext->PfxSaveArea);
1360
1361 /* Store the NPX IRQL */
1362 FsContext->OldNpxIrql = FsContext->CurrentThread->Header.NpxIrql;
1363
1364 /* Set the current IRQL to NPX */
1365 FsContext->CurrentThread->Header.NpxIrql = KeGetCurrentIrql();
1366
1367 /* Initialize the FPU */
1368 Ke386FnInit();
1369
1370 /* Enable interrupts back */
1371 _enable();
1372
1373 /* Give the saved FPU context to the caller */
1374 *((PVOID *) Save) = FsContext;
1375 return STATUS_SUCCESS;
1376}
#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:769
#define FXSAVE_ALIGN
Definition: cpu.c:58
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 1567 of file cpu.c.

1568{
1569 /* Capture the context */
1570 RtlCaptureContext(&State->ContextFrame);
1571
1572 /* Capture the control state */
1574}
NTSYSAPI VOID NTAPI RtlCaptureContext(_Out_ PCONTEXT ContextRecord)
VOID NTAPI KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
Definition: cpu.c:487

◆ KeSetDmaIoCoherency()

VOID NTAPI KeSetDmaIoCoherency ( IN ULONG  Coherency)

Definition at line 1556 of file cpu.c.

1557{
1558 /* Save the coherency globally */
1559 KiDmaIoCoherency = Coherency;
1560}
ULONG KiDmaIoCoherency
Definition: cpu.c:30

◆ Ki386EnableDE()

ULONG_PTR NTAPI Ki386EnableDE ( IN ULONG_PTR  Context)

Definition at line 975 of file cpu.c.

976{
977 /* Enable DE */
979 return 0;
980}
#define CR4_DE
Definition: ketypes.h:157

Referenced by KiInitMachineDependent().

◆ Ki386EnableFxsr()

ULONG_PTR NTAPI Ki386EnableFxsr ( IN ULONG_PTR  Context)

Definition at line 985 of file cpu.c.

986{
987 /* Enable FXSR */
989 return 0;
990}
#define CR4_FXSR
Definition: ketypes.h:162

Referenced by KiInitMachineDependent().

◆ Ki386EnableXMMIExceptions()

ULONG_PTR NTAPI Ki386EnableXMMIExceptions ( IN ULONG_PTR  Context)

Definition at line 995 of file cpu.c.

996{
997 PKIDTENTRY IdtEntry;
998
999 /* Get the IDT Entry for Interrupt 0x13 */
1000 IdtEntry = &((PKIPCR)KeGetPcr())->IDT[0x13];
1001
1002 /* Set it up */
1003 IdtEntry->Selector = KGDT_R0_CODE;
1004 IdtEntry->Offset = ((ULONG_PTR)KiTrap13 & 0xFFFF);
1005 IdtEntry->ExtendedOffset = ((ULONG_PTR)KiTrap13 >> 16) & 0xFFFF;
1006 ((PKIDT_ACCESS)&IdtEntry->Access)->Dpl = 0;
1007 ((PKIDT_ACCESS)&IdtEntry->Access)->Present = 1;
1008 ((PKIDT_ACCESS)&IdtEntry->Access)->SegmentType = I386_INTERRUPT_GATE;
1009
1010 /* Enable XMMI exceptions */
1012 return 0;
1013}
#define ULONG_PTR
Definition: config.h:101
#define CR4_XMMEXCPT
Definition: ketypes.h:163
struct _KIPCR * PKIPCR
#define I386_INTERRUPT_GATE
Definition: ketypes.h:118
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 729 of file cpu.c.

732{
733 PKGDTENTRY TssEntry, TaskGateEntry;
734
735 /* Initialize the boot TSS. */
736 TssEntry = &Gdt[KGDT_TSS / sizeof(KGDTENTRY)];
737 TssEntry->HighWord.Bits.Type = I386_TSS;
738 TssEntry->HighWord.Bits.Pres = 1;
739 TssEntry->HighWord.Bits.Dpl = 0;
740 KiInitializeTSS2(Tss, TssEntry);
741 KiInitializeTSS(Tss);
742
743 /* Load the task register */
744 Ke386SetTr(KGDT_TSS);
745
746 /* Setup the Task Gate for Double Fault Traps */
747 TaskGateEntry = (PKGDTENTRY)&Idt[8];
748 TaskGateEntry->HighWord.Bits.Type = I386_TASK_GATE;
749 TaskGateEntry->HighWord.Bits.Pres = 1;
750 TaskGateEntry->HighWord.Bits.Dpl = 0;
751 ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_DF_TSS;
752
753 /* Initialize the TSS used for handling double faults. */
754 Tss = (PKTSS)KiDoubleFaultTSS;
755 KiInitializeTSS(Tss);
756 Tss->CR3 = __readcr3();
757 Tss->Esp0 = KiDoubleFaultStack;
758 Tss->Esp = KiDoubleFaultStack;
759 Tss->Eip = PtrToUlong(KiTrap08);
760 Tss->Cs = KGDT_R0_CODE;
761 Tss->Fs = KGDT_R0_PCR;
762 Tss->Ss = Ke386GetSs();
763 Tss->Es = KGDT_R3_DATA | RPL_MASK;
764 Tss->Ds = KGDT_R3_DATA | RPL_MASK;
765
766 /* Setup the Double Trap TSS entry in the GDT */
767 TssEntry = &Gdt[KGDT_DF_TSS / sizeof(KGDTENTRY)];
768 TssEntry->HighWord.Bits.Type = I386_TSS;
769 TssEntry->HighWord.Bits.Pres = 1;
770 TssEntry->HighWord.Bits.Dpl = 0;
771 TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF);
772 TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16);
773 TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
774 TssEntry->LimitLow = KTSS_IO_MAPS;
775
776 /* Now setup the NMI Task Gate */
777 TaskGateEntry = (PKGDTENTRY)&Idt[2];
778 TaskGateEntry->HighWord.Bits.Type = I386_TASK_GATE;
779 TaskGateEntry->HighWord.Bits.Pres = 1;
780 TaskGateEntry->HighWord.Bits.Dpl = 0;
781 ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_NMI_TSS;
782
783 /* Initialize the actual TSS */
784 Tss = (PKTSS)KiNMITSS;
785 KiInitializeTSS(Tss);
786 Tss->CR3 = __readcr3();
787 Tss->Esp0 = KiDoubleFaultStack;
788 Tss->Esp = KiDoubleFaultStack;
789 Tss->Eip = PtrToUlong(KiTrap02);
790 Tss->Cs = KGDT_R0_CODE;
791 Tss->Fs = KGDT_R0_PCR;
792 Tss->Ss = Ke386GetSs();
793 Tss->Es = KGDT_R3_DATA | RPL_MASK;
794 Tss->Ds = KGDT_R3_DATA | RPL_MASK;
795
796 /* And its associated TSS Entry */
797 TssEntry = &Gdt[KGDT_NMI_TSS / sizeof(KGDTENTRY)];
798 TssEntry->HighWord.Bits.Type = I386_TSS;
799 TssEntry->HighWord.Bits.Pres = 1;
800 TssEntry->HighWord.Bits.Dpl = 0;
801 TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF);
802 TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16);
803 TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
804 TssEntry->LimitLow = KTSS_IO_MAPS;
805}
#define KGDT_R3_DATA
#define RPL_MASK
#define PtrToUlong(u)
Definition: config.h:107
#define PKIDTENTRY
Definition: ketypes.h:585
#define I386_TASK_GATE
Definition: ketypes.h:114
#define I386_TSS
Definition: ketypes.h:115
#define PKTSS
Definition: ketypes.h:1034
#define PKGDTENTRY
Definition: ketypes.h:543
#define KGDTENTRY
Definition: ketypes.h:542
#define KTSS_IO_MAPS
Definition: asm.h:84
#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:713
VOID NTAPI KiInitializeTSS2(IN PKTSS Tss, IN PKGDTENTRY TssEntry OPTIONAL)
Definition: cpu.c:675
UCHAR KiNMITSS[KTSS_IO_MAPS]
Definition: cpu.c:23
unsigned short USHORT
Definition: pedump.c:61
struct _KGDTENTRY::@2708::@2710 Bits
USHORT BaseLow
Definition: ketypes.h:390
USHORT LimitLow
Definition: ketypes.h:389
struct _KGDTENTRY::@2708::@2709 Bytes
union _KGDTENTRY::@2708 HighWord
unsigned char UCHAR
Definition: typedefs.h:53

Referenced by KiSystemStartup().

◆ KiCoprocessorError()

VOID NTAPI KiCoprocessorError ( VOID  )

Definition at line 1231 of file cpu.c.

1232{
1233 PFX_SAVE_AREA NpxArea;
1234
1235 /* Get the FPU area */
1237
1238 /* Set CR0_TS */
1239 NpxArea->Cr0NpxState = CR0_TS;
1241}
__INTRIN_INLINE unsigned long __readcr0(void)
Definition: intrin_x86.h:1836
__INTRIN_INLINE void __writecr0(unsigned int Data)
Definition: intrin_x86.h:1821
#define CR0_TS
Definition: ketypes.h:142
ULONG Cr0NpxState
Definition: ketypes.h:505

◆ KiFlushNPXState()

VOID NTAPI KiFlushNPXState ( IN PFLOATING_SAVE_AREA  SaveArea)

Definition at line 1140 of file cpu.c.

1141{
1142 ULONG EFlags, Cr0;
1143 PKTHREAD Thread, NpxThread;
1144 PFX_SAVE_AREA FxSaveArea;
1145
1146 /* Save volatiles and disable interrupts */
1147 EFlags = __readeflags();
1148 _disable();
1149
1150 /* Save the PCR and get the current thread */
1152
1153 /* Check if we're already loaded */
1154 if (Thread->NpxState != NPX_STATE_LOADED)
1155 {
1156 /* If there's nothing to load, quit */
1157 if (!SaveArea)
1158 {
1159 /* Restore interrupt state and return */
1160 __writeeflags(EFlags);
1161 return;
1162 }
1163
1164 /* Need FXSR support for this */
1166
1167 /* Check for sane CR0 */
1168 Cr0 = __readcr0();
1169 if (Cr0 & (CR0_MP | CR0_TS | CR0_EM))
1170 {
1171 /* Mask out FPU flags */
1172 __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
1173 }
1174
1175 /* Get the NPX thread and check its FPU state */
1176 NpxThread = KeGetCurrentPrcb()->NpxThread;
1177 if ((NpxThread) && (NpxThread->NpxState == NPX_STATE_LOADED))
1178 {
1179 /* Get the FX frame and store the state there */
1180 FxSaveArea = KiGetThreadNpxArea(NpxThread);
1181 Ke386FxSave(FxSaveArea);
1182
1183 /* NPX thread has lost its state */
1184 NpxThread->NpxState = NPX_STATE_NOT_LOADED;
1185 }
1186
1187 /* Now load NPX state from the NPX area */
1188 FxSaveArea = KiGetThreadNpxArea(Thread);
1189 Ke386FxStore(FxSaveArea);
1190 }
1191 else
1192 {
1193 /* Check for sane CR0 */
1194 Cr0 = __readcr0();
1195 if (Cr0 & (CR0_MP | CR0_TS | CR0_EM))
1196 {
1197 /* Mask out FPU flags */
1198 __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
1199 }
1200
1201 /* Get FX frame */
1202 FxSaveArea = KiGetThreadNpxArea(Thread);
1203 Thread->NpxState = NPX_STATE_NOT_LOADED;
1204
1205 /* Save state if supported by CPU */
1206 if (KeI386FxsrPresent) Ke386FxSave(FxSaveArea);
1207 }
1208
1209 /* Now save the FN state wherever it was requested */
1210 if (SaveArea) Ke386FnSave(SaveArea);
1211
1212 /* Clear NPX thread */
1213 KeGetCurrentPrcb()->NpxThread = NULL;
1214
1215 /* Add the CR0 from the NPX frame */
1216 Cr0 |= NPX_STATE_NOT_LOADED;
1217 Cr0 |= FxSaveArea->Cr0NpxState;
1218 __writecr0(Cr0);
1219
1220 /* Restore interrupt state */
1221 __writeeflags(EFlags);
1222}
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1701
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1706
#define CR0_MP
Definition: ketypes.h:140
#define CR0_EM
Definition: ketypes.h:141
ULONG KeI386FxsrPresent
Definition: cpu.c:33
ULONG64 NpxState
Definition: ketypes.h:2215

◆ KiFlushTargetEntireTb()

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

Definition at line 1483 of file cpu.c.

1487{
1488 /* Signal this packet as done */
1489 KiIpiSignalPacketDone(PacketContext);
1490
1491 /* Flush the TB for the Current CPU */
1493}
VOID FASTCALL KiIpiSignalPacketDone(IN PKIPI_CONTEXT PacketContext)
Definition: ipi.c:57

Referenced by KeFlushEntireTb().

◆ KiGetCacheInformation()

VOID NTAPI KiGetCacheInformation ( VOID  )

Definition at line 395 of file cpu.c.

396{
397 PKIPCR Pcr = (PKIPCR)KeGetPcr();
398 CPU_INFO CpuInfo;
399 ULONG CacheRequests = 0, i;
400 ULONG CurrentRegister;
401 UCHAR RegisterByte, Associativity = 0;
402 ULONG Size, CacheLine = 64, CurrentSize = 0;
403 BOOLEAN FirstPass = TRUE;
404
405 /* Set default L2 size */
406 Pcr->SecondLevelCacheSize = 0;
407
408 /* Check the Vendor ID */
409 switch (KiGetCpuVendor())
410 {
411 /* Handle Intel case */
412 case CPU_INTEL:
413
414 /* Check if we support CPUID 2 */
415 KiCpuId(&CpuInfo, 0);
416 if (CpuInfo.Eax >= 2)
417 {
418 /* We need to loop for the number of times CPUID will tell us to */
419 do
420 {
421 /* Do the CPUID call */
422 KiCpuId(&CpuInfo, 2);
423
424 /* Check if it was the first call */
425 if (FirstPass)
426 {
427 /*
428 * The number of times to loop is the first byte. Read
429 * it and then destroy it so we don't get confused.
430 */
431 CacheRequests = CpuInfo.Eax & 0xFF;
432 CpuInfo.Eax &= 0xFFFFFF00;
433
434 /* Don't go over this again */
435 FirstPass = FALSE;
436 }
437
438 /* Loop all 4 registers */
439 for (i = 0; i < 4; i++)
440 {
441 /* Get the current register */
442 CurrentRegister = CpuInfo.AsUINT32[i];
443
444 /*
445 * If the upper bit is set, then this register should
446 * be skipped.
447 */
448 if (CurrentRegister & 0x80000000) continue;
449
450 /* Keep looping for every byte inside this register */
451 while (CurrentRegister)
452 {
453 /* Read a byte, skip a byte. */
454 RegisterByte = (UCHAR)(CurrentRegister & 0xFF);
455 CurrentRegister >>= 8;
456 if (!RegisterByte) continue;
457
458 Size = 0;
459 switch (RegisterByte)
460 {
461 case 0x06:
462 case 0x08:
464 break;
465 case 0x09:
467 break;
468 case 0x0a:
469 case 0x0c:
471 break;
472 case 0x0d:
473 case 0x0e:
475 break;
476 case 0x1d:
477 Size = 128 * 1024;
478 Associativity = 2;
479 break;
480 case 0x21:
481 Size = 256 * 1024;
482 Associativity = 8;
483 break;
484 case 0x24:
485 Size = 1024 * 1024;
486 Associativity = 16;
487 break;
488 case 0x2c:
489 case 0x30:
491 break;
492 case 0x41:
493 case 0x42:
494 case 0x43:
495 case 0x44:
496 case 0x45:
497 Size = (1 << (RegisterByte - 0x41)) * 128 * 1024;
498 Associativity = 4;
499 break;
500 case 0x48:
501 Size = 3 * 1024 * 1024;
502 Associativity = 12;
503 break;
504 case 0x49:
505 Size = 4 * 1024 * 1024;
506 Associativity = 16;
507 break;
508 case 0x4e:
509 Size = 6 * 1024 * 1024;
510 Associativity = 24;
511 break;
512 case 0x60:
513 case 0x66:
514 case 0x67:
515 case 0x68:
517 break;
518 case 0x78:
519 Size = 1024 * 1024;
520 Associativity = 4;
521 break;
522 case 0x79:
523 case 0x7a:
524 case 0x7b:
525 case 0x7c:
526 case 0x7d:
527 Size = (1 << (RegisterByte - 0x79)) * 128 * 1024;
528 Associativity = 8;
529 break;
530 case 0x7f:
531 Size = 512 * 1024;
532 Associativity = 2;
533 break;
534 case 0x80:
535 Size = 512 * 1024;
536 Associativity = 8;
537 break;
538 case 0x82:
539 case 0x83:
540 case 0x84:
541 case 0x85:
542 Size = (1 << (RegisterByte - 0x82)) * 256 * 1024;
543 Associativity = 8;
544 break;
545 case 0x86:
546 Size = 512 * 1024;
547 Associativity = 4;
548 break;
549 case 0x87:
550 Size = 1024 * 1024;
551 Associativity = 8;
552 break;
553 case 0xf0:
555 break;
556 case 0xf1:
558 break;
559 }
560 if (Size && (Size / Associativity) > CurrentSize)
561 {
562 /* Set the L2 Cache Size and Associativity */
563 CurrentSize = Size / Associativity;
565 Pcr->SecondLevelCacheAssociativity = Associativity;
566 }
567 }
568 }
569 } while (--CacheRequests);
570 }
571 break;
572
573 case CPU_AMD:
574
575 /* Check if we support CPUID 0x80000005 */
576 KiCpuId(&CpuInfo, 0x80000000);
577 if (CpuInfo.Eax >= 0x80000005)
578 {
579 /* Get L1 size first */
580 KiCpuId(&CpuInfo, 0x80000005);
581 KePrefetchNTAGranularity = CpuInfo.Ecx & 0xFF;
582
583 /* Check if we support CPUID 0x80000006 */
584 KiCpuId(&CpuInfo, 0x80000000);
585 if (CpuInfo.Eax >= 0x80000006)
586 {
587 /* Get 2nd level cache and tlb size */
588 KiCpuId(&CpuInfo, 0x80000006);
589
590 /* Cache line size */
591 CacheLine = CpuInfo.Ecx & 0xFF;
592
593 /* Hardcode associativity */
594 RegisterByte = (CpuInfo.Ecx >> 12) & 0xFF;
595 switch (RegisterByte)
596 {
597 case 2:
598 Associativity = 2;
599 break;
600
601 case 4:
602 Associativity = 4;
603 break;
604
605 case 6:
606 Associativity = 8;
607 break;
608
609 case 8:
610 case 15:
611 Associativity = 16;
612 break;
613
614 default:
615 Associativity = 1;
616 break;
617 }
618
619 /* Compute size */
620 Size = (CpuInfo.Ecx >> 16) << 10;
621
622 /* Hack for Model 6, Steping 300 */
623 if ((KeGetCurrentPrcb()->CpuType == 6) &&
624 (KeGetCurrentPrcb()->CpuStep == 0x300))
625 {
626 /* Stick 64K in there */
627 Size = 64 * 1024;
628 }
629
630 /* Set the L2 Cache Size and associativity */
632 Pcr->SecondLevelCacheAssociativity = Associativity;
633 }
634 }
635 break;
636
637 case CPU_CYRIX:
638 case CPU_TRANSMETA:
639 case CPU_CENTAUR:
640 case CPU_RISE:
641
642 /* FIXME */
643 break;
644 }
645
646 /* Set the cache line */
647 if (CacheLine > KeLargestCacheLine) KeLargestCacheLine = CacheLine;
648 DPRINT1("Prefetch Cache: %lu bytes\tL2 Cache: %lu bytes\tL2 Cache Line: %lu bytes\tL2 Cache Associativity: %lu\n",
653}
unsigned char BOOLEAN
Definition: actypes.h:127
#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:100
@ CPU_AMD
Definition: ketypes.h:99
@ 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 KePrefetchNTAGranularity
Definition: cpu.c:41
static ULONG KiGetCpuVendor(VOID)
Definition: cpu.c:87
ULONG SecondLevelCacheSize
Definition: ketypes.h:995
UCHAR SecondLevelCacheAssociativity
Definition: ketypes.h:986
ULONG Eax
Definition: ketypes.h:401
UINT32 AsUINT32[4]
Definition: ketypes.h:398
ULONG Ecx
Definition: ketypes.h:403
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539

Referenced by KiInitializeKernel(), and KiSystemStartupBootStack().

◆ KiGetCpuVendor()

static ULONG KiGetCpuVendor ( VOID  )
static

Definition at line 87 of file cpu.c.

88{
89 ASSERT(KeGetCurrentPrcb()->VendorString[0] != 0);
90 return KiIdentifyCpuVendor(KeGetCurrentPrcb()->VendorString);
91}
CPU_VENDORS NTAPI KiIdentifyCpuVendor(_In_reads_z_(CPU_VENDOR_STR_LEN) const CHAR VendorString[CPU_VENDOR_STR_LEN])
Identify the CPU vendor by the vendor string.
Definition: cpuinfo.c:55

Referenced by KiGetCacheInformation(), and KiGetFeatureBits().

◆ KiGetFeatureBits()

ULONG64 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 116 of file cpu.c.

117{
118 PKPRCB Prcb = KeGetCurrentPrcb();
119 ULONG Vendor;
120 ULONG64 FeatureBits = KF_WORKING_PTE;
121 CPU_INFO CpuInfo, DummyCpuInfo;
122 UCHAR Ccr1;
123 BOOLEAN ExtendedCPUID = TRUE;
124 ULONG CpuFeatures = 0;
125
126 /* Get the Vendor ID */
127 Vendor = KiGetCpuVendor();
128
129 /* Make sure we got a valid vendor ID at least. */
130 if (!Vendor) return FeatureBits;
131
132 /* Get the CPUID Info. Features are in Reg[3]. */
133 KiCpuId(&CpuInfo, 1);
134
135 /* Set the initial APIC ID */
136 Prcb->InitialApicId = (UCHAR)(CpuInfo.Ebx >> 24);
137
138 switch (Vendor)
139 {
140 /* Intel CPUs */
141 case CPU_INTEL:
142
143 /* Check if it's a P6 */
144 if (Prcb->CpuType == 6)
145 {
146 /* Perform the special sequence to get the MicroCode Signature */
147 __writemsr(0x8B, 0);
148 KiCpuId(&DummyCpuInfo, 1);
149 Prcb->UpdateSignature.QuadPart = __readmsr(0x8B);
150 }
151 else if (Prcb->CpuType == 5)
152 {
153 /* On P5, enable workaround for the LOCK errata. */
155 }
156
157 /* Check for broken P6 with bad SMP PTE implementation */
158 if (((CpuInfo.Eax & 0x0FF0) == 0x0610 && (CpuInfo.Eax & 0x000F) <= 0x9) ||
159 ((CpuInfo.Eax & 0x0FF0) == 0x0630 && (CpuInfo.Eax & 0x000F) <= 0x4))
160 {
161 /* Remove support for correct PTE support. */
162 FeatureBits &= ~KF_WORKING_PTE;
163 }
164
165 /* Check if the CPU is too old to support SYSENTER */
166 if ((Prcb->CpuType < 6) ||
167 ((Prcb->CpuType == 6) && (Prcb->CpuStep < 0x0303)))
168 {
169 /* Disable it */
170 CpuInfo.Edx &= ~0x800;
171 }
172
173 break;
174
175 /* AMD CPUs */
176 case CPU_AMD:
177
178 /* Check if this is a K5 or K6. (family 5) */
179 if ((CpuInfo.Eax & 0x0F00) == 0x0500)
180 {
181 /* Get the Model Number */
182 switch (CpuInfo.Eax & 0x00F0)
183 {
184 /* Model 1: K5 - 5k86 (initial models) */
185 case 0x0010:
186
187 /* Check if this is Step 0 or 1. They don't support PGE */
188 if ((CpuInfo.Eax & 0x000F) > 0x03) break;
189
190 /* Model 0: K5 - SSA5 */
191 case 0x0000:
192
193 /* Model 0 doesn't support PGE at all. */
194 CpuInfo.Edx &= ~0x2000;
195 break;
196
197 /* Model 8: K6-2 */
198 case 0x0080:
199
200 /* K6-2, Step 8 and over have support for MTRR. */
201 if ((CpuInfo.Eax & 0x000F) >= 0x8) FeatureBits |= KF_AMDK6MTRR;
202 break;
203
204 /* Model 9: K6-III
205 Model D: K6-2+, K6-III+ */
206 case 0x0090:
207 case 0x00D0:
208
209 FeatureBits |= KF_AMDK6MTRR;
210 break;
211 }
212 }
213 else if((CpuInfo.Eax & 0x0F00) < 0x0500)
214 {
215 /* Families below 5 don't support PGE, PSE or CMOV at all */
216 CpuInfo.Edx &= ~(0x08 | 0x2000 | 0x8000);
217
218 /* They also don't support advanced CPUID functions. */
219 ExtendedCPUID = FALSE;
220 }
221
222 break;
223
224 /* Cyrix CPUs */
225 case CPU_CYRIX:
226
227 /* Workaround the "COMA" bug on 6x family of Cyrix CPUs */
228 if (Prcb->CpuType == 6 &&
229 Prcb->CpuStep <= 1)
230 {
231 /* Get CCR1 value */
232 Ccr1 = getCx86(CX86_CCR1);
233
234 /* Enable the NO_LOCK bit */
235 Ccr1 |= 0x10;
236
237 /* Set the new CCR1 value */
238 setCx86(CX86_CCR1, Ccr1);
239 }
240
241 break;
242
243 /* Transmeta CPUs */
244 case CPU_TRANSMETA:
245
246 /* Enable CMPXCHG8B if the family (>= 5), model and stepping (>= 4.2) support it */
247 if ((CpuInfo.Eax & 0x0FFF) >= 0x0542)
248 {
249 __writemsr(0x80860004, __readmsr(0x80860004) | 0x0100);
250 FeatureBits |= KF_CMPXCHG8B;
251 }
252
253 break;
254
255 /* Centaur, IDT, Rise and VIA CPUs */
256 case CPU_CENTAUR:
257 case CPU_RISE:
258
259 /* These CPUs don't report the presence of CMPXCHG8B through CPUID.
260 However, this feature exists and operates properly without any additional steps. */
261 FeatureBits |= KF_CMPXCHG8B;
262
263 break;
264 }
265
266 /* Get some features from ECX */
267 if (CpuInfo.Ecx & X86_FEATURE_SSE3) FeatureBits |= KF_SSE3;
268 if (CpuInfo.Ecx & X86_FEATURE_SSSE3) FeatureBits |= KF_SSSE3;
269 if (CpuInfo.Ecx & X86_FEATURE_SSE4_1) FeatureBits |= KF_SSE4_1;
270 if (CpuInfo.Ecx & X86_FEATURE_SSE4_2) FeatureBits |= KF_SSE4_2;
271 if (CpuInfo.Ecx & X86_FEATURE_XSAVE) FeatureBits |= KF_XSTATE;
272 if (CpuInfo.Ecx & X86_FEATURE_RDRAND) FeatureBits |= KF_RDRAND;
273
274 /* Set the current features */
275 CpuFeatures = CpuInfo.Edx;
276
277 /* Convert all CPUID Feature bits into our format */
278 if (CpuFeatures & X86_FEATURE_VME) FeatureBits |= KF_V86_VIS | KF_CR4;
279 if (CpuFeatures & X86_FEATURE_PSE) FeatureBits |= KF_LARGE_PAGE | KF_CR4;
280 if (CpuFeatures & X86_FEATURE_TSC) FeatureBits |= KF_RDTSC;
281 if (CpuFeatures & X86_FEATURE_CX8) FeatureBits |= KF_CMPXCHG8B;
282 if (CpuFeatures & X86_FEATURE_SYSCALL) FeatureBits |= KF_FAST_SYSCALL;
283 if (CpuFeatures & X86_FEATURE_MTRR) FeatureBits |= KF_MTRR;
284 if (CpuFeatures & X86_FEATURE_PGE) FeatureBits |= KF_GLOBAL_PAGE | KF_CR4;
285 if (CpuFeatures & X86_FEATURE_CMOV) FeatureBits |= KF_CMOV;
286 if (CpuFeatures & X86_FEATURE_PAT) FeatureBits |= KF_PAT;
287 if (CpuFeatures & X86_FEATURE_DS) FeatureBits |= KF_DTS;
288 if (CpuFeatures & X86_FEATURE_MMX) FeatureBits |= KF_MMX;
289 if (CpuFeatures & X86_FEATURE_FXSR) FeatureBits |= KF_FXSR;
290 if (CpuFeatures & X86_FEATURE_SSE) FeatureBits |= KF_XMMI;
291 if (CpuFeatures & X86_FEATURE_SSE2) FeatureBits |= KF_XMMI64;
292
293 /* Check if the CPU has hyper-threading */
294 if (CpuFeatures & X86_FEATURE_HT)
295 {
296 /* Set the number of logical CPUs */
297 Prcb->LogicalProcessorsPerPhysicalProcessor = (UCHAR)(CpuInfo.Ebx >> 16);
299 {
300 /* We're on dual-core */
302 }
303 }
304 else
305 {
306 /* We only have a single CPU */
308 }
309
310 /* Check if CPUID 0x80000000 is supported */
311 if (ExtendedCPUID)
312 {
313 /* Do the call */
314 KiCpuId(&CpuInfo, 0x80000000);
315 if ((CpuInfo.Eax & 0xffffff00) == 0x80000000)
316 {
317 /* Check if CPUID 0x80000001 is supported */
318 if (CpuInfo.Eax >= 0x80000001)
319 {
320 /* Check which extended features are available. */
321 KiCpuId(&CpuInfo, 0x80000001);
322
323 /* Check if NX-bit is supported */
324 if (CpuInfo.Edx & X86_FEATURE_NX) FeatureBits |= KF_NX_BIT;
325
326 /* Now handle each features for each CPU Vendor */
327 switch (Vendor)
328 {
329 case CPU_AMD:
330 case CPU_CENTAUR:
331 if (CpuInfo.Edx & 0x80000000) FeatureBits |= KF_3DNOW;
332 break;
333 }
334 }
335 }
336 }
337
338 /* Return the Feature Bits */
339 return FeatureBits;
340}
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
unsigned __int64 ULONG64
Definition: imports.h:198
#define KF_SSE4_2
Definition: ketypes.h:74
#define KF_SSSE3
Definition: ketypes.h:72
#define KF_MTRR
Definition: ketypes.h:37
#define KF_XSTATE
Definition: ketypes.h:55
#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_SSE4_1
Definition: ketypes.h:73
#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_RDRAND
Definition: ketypes.h:64
#define KF_LARGE_PAGE
Definition: ketypes.h:36
#define KF_XMMI
Definition: ketypes.h:44
#define KF_MMX
Definition: ketypes.h:39
#define KF_SSE3
Definition: ketypes.h:51
#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_XSAVE
Definition: ke.h:60
#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_SSE3
Definition: ke.h:50
#define X86_FEATURE_PAT
Definition: ke.h:41
#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_SSSE3
Definition: ke.h:53
#define X86_FEATURE_FXSR
Definition: ke.h:44
#define X86_FEATURE_MTRR
Definition: ke.h:38
#define X86_FEATURE_RDRAND
Definition: ke.h:31
#define X86_FEATURE_SSE4_2
Definition: ke.h:29
#define X86_FEATURE_SSE4_1
Definition: ke.h:28
BOOLEAN KiSMTProcessorsPresent
Definition: cpu.c:31
#define CX86_CCR1
Definition: cpu.c:63
static __inline void setCx86(UCHAR reg, UCHAR data)
Definition: cpu.c:76
static __inline UCHAR getCx86(UCHAR reg)
Definition: cpu.c:68
BOOLEAN KiI386PentiumLockErrataPresent
Definition: cpu.c:42
CHAR CpuType
Definition: ketypes.h:684
USHORT CpuStep
Definition: ketypes.h:689
UCHAR LogicalProcessorsPerPhysicalProcessor
Definition: ketypes.h:759
ULONG InitialApicId
Definition: ketypes.h:721
LARGE_INTEGER UpdateSignature
Definition: ketypes.h:904
ULONG Ebx
Definition: ketypes.h:402
ULONG Edx
Definition: ketypes.h:404
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by KiInitializeCpu(), and KiVerifyCpuFeatures().

◆ KiI386PentiumLockErrataFixup()

VOID NTAPI KiI386PentiumLockErrataFixup ( VOID  )

Definition at line 1018 of file cpu.c.

1019{
1020 KDESCRIPTOR IdtDescriptor = {0, 0, 0};
1021 PKIDTENTRY NewIdt, NewIdt2;
1022 PMMPTE PointerPte;
1023
1024 /* Allocate memory for a new IDT */
1025 NewIdt = ExAllocatePool(NonPagedPool, 2 * PAGE_SIZE);
1026
1027 /* Put everything after the first 7 entries on a new page */
1028 NewIdt2 = (PVOID)((ULONG_PTR)NewIdt + PAGE_SIZE - (7 * sizeof(KIDTENTRY)));
1029
1030 /* Disable interrupts */
1031 _disable();
1032
1033 /* Get the current IDT and copy it */
1034 __sidt(&IdtDescriptor.Limit);
1035 RtlCopyMemory(NewIdt2,
1036 (PVOID)IdtDescriptor.Base,
1037 IdtDescriptor.Limit + 1);
1038 IdtDescriptor.Base = (ULONG)NewIdt2;
1039
1040 /* Set the new IDT */
1041 __lidt(&IdtDescriptor.Limit);
1042 ((PKIPCR)KeGetPcr())->IDT = NewIdt2;
1043
1044 /* Restore interrupts */
1045 _enable();
1046
1047 /* Set the first 7 entries as read-only to produce a fault */
1048 PointerPte = MiAddressToPte(NewIdt);
1049 ASSERT(PointerPte->u.Hard.Write == 1);
1050 PointerPte->u.Hard.Write = 0;
1051 KeInvalidateTlbEntry(NewIdt);
1052}
#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:2059
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2064
#define KIDTENTRY
Definition: ketypes.h:584
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:274
#define MiAddressToPte(x)
Definition: mm.h:145
PVOID Base
Definition: ketypes.h:591
USHORT Limit
Definition: ketypes.h:590
ULONG64 Write
Definition: mmtypes.h:170
union _MMPTE::@2559 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 918 of file cpu.c.

919{
920 /* Set the Machine Type we got from NTLDR */
922}
ULONG KeI386MachineType
Definition: cpu.c:34
NTSYSAPI PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:28
ULONG MachineType
Definition: arc.h:713
union _LOADER_PARAMETER_BLOCK::@3668 u
I386_LOADER_BLOCK I386
Definition: arc.h:861

◆ KiInitializeTSS()

VOID NTAPI KiInitializeTSS ( IN PKTSS  Tss)

Definition at line 713 of file cpu.c.

714{
715 /* Set an invalid map base */
716 Tss->IoMapBase = KiComputeIopmOffset(IO_ACCESS_MAP_NONE);
717
718 /* Disable traps during Task Switches */
719 Tss->Flags = 0;
720
721 /* Set LDT and Ring 0 SS */
722 Tss->LDT = 0;
723 Tss->Ss0 = KGDT_R0_DATA;
724}
#define KiComputeIopmOffset(MapNumber)
Definition: ketypes.h:363
#define IO_ACCESS_MAP_NONE
Definition: ketypes.h:361
#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 675 of file cpu.c.

677{
678 PUCHAR p;
679
680 /* Make sure the GDT Entry is valid */
681 if (TssEntry)
682 {
683 /* Set the Limit */
684 TssEntry->LimitLow = sizeof(KTSS) - 1;
685 TssEntry->HighWord.Bits.LimitHi = 0;
686 }
687
688 /* Now clear the I/O Map */
689 ASSERT(IOPM_COUNT == 1);
690 RtlFillMemory(Tss->IoMaps[0].IoMap, IOPM_FULL_SIZE, 0xFF);
691
692 /* Initialize Interrupt Direction Maps */
693 p = (PUCHAR)(Tss->IoMaps[0].DirectionMap);
695
696 /* Add DPMI support for interrupts */
697 p[0] = 4;
698 p[3] = 0x18;
699 p[4] = 0x18;
700
701 /* Initialize the default Interrupt Direction Map */
702 p = Tss->IntDirectionMap;
703 RtlZeroMemory(Tss->IntDirectionMap, IOPM_DIRECTION_MAP_SIZE);
704
705 /* Add DPMI support */
706 p[0] = 4;
707 p[3] = 0x18;
708 p[4] = 0x18;
709}
GLfloat GLfloat p
Definition: glext.h:8902
#define KTSS
Definition: ketypes.h:1033
#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 RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:603
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by Ki386InitializeTss().

◆ KiIsNpxErrataPresent()

BOOLEAN NTAPI KiIsNpxErrataPresent ( VOID  )

Definition at line 1089 of file cpu.c.

1090{
1091 static double Value1 = 4195835.0, Value2 = 3145727.0;
1092 INT ErrataPresent;
1093 ULONG Cr0;
1094
1095 /* Interrupts have to be disabled here. */
1097
1098 /* Read CR0 and remove FPU flags */
1099 Cr0 = __readcr0();
1100 __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
1101
1102 /* Initialize FPU state */
1103 Ke386FnInit();
1104
1105 /* Multiply the magic values and divide, we should get the result back */
1106#ifdef __GNUC__
1107 __asm__ __volatile__
1108 (
1109 "fldl %1\n\t"
1110 "fdivl %2\n\t"
1111 "fmull %2\n\t"
1112 "fldl %1\n\t"
1113 "fsubp\n\t"
1114 "fistpl %0\n\t"
1115 : "=m" (ErrataPresent)
1116 : "m" (Value1),
1117 "m" (Value2)
1118 );
1119#else
1120 __asm
1121 {
1122 fld Value1
1123 fdiv Value2
1124 fmul Value2
1125 fld Value1
1126 fsubp st(1), st(0)
1127 fistp ErrataPresent
1128 };
1129#endif
1130
1131 /* Restore CR0 */
1132 __writecr0(Cr0);
1133
1134 /* Return if there's an errata */
1135 return ErrataPresent != 0;
1136}
#define EFLAGS_INTERRUPT_MASK
__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" "\tpush %rbx\n" "\t.seh_pushreg %rbx\n" "\tpush %rdi\n" "\t.seh_pushreg %rdi\n" "\tpush %rsi\n" "\t.seh_pushreg %rsi\n" "\tpush %r12\n" "\t.seh_pushreg %r12\n" "\tpush %r13\n" "\t.seh_pushreg %r13\n" "\tpush %r14\n" "\t.seh_pushreg %r14\n" "\tpush %r15\n" "\t.seh_pushreg %r15\n" "\tsub $40, %rsp\n" "\t.seh_stackalloc 40\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 $40, %rsp\n" "\tpop %r15\n" "\tpop %r14\n" "\tpop %r13\n" "\tpop %r12\n" "\tpop %rsi\n" "\tpop %rdi\n" "\tpop %rbx\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 927 of file cpu.c.

928{
929 /* Set CS and ESP */
930 __writemsr(0x174, KGDT_R0_CODE);
931 __writemsr(0x175, (ULONG_PTR)KeGetCurrentPrcb()->DpcStack);
932
933 /* Set LSTAR */
935 return 0;
936}
VOID __cdecl KiFastCallEntry(VOID)

Referenced by KiRestoreFastSyscallReturnState().

◆ KiRestoreFastSyscallReturnState()

VOID NTAPI KiRestoreFastSyscallReturnState ( VOID  )

Definition at line 941 of file cpu.c.

942{
943 /* Check if the CPU Supports fast system call */
945 {
946 /* Check if it has been disabled */
948 {
949 /* Disable fast system call */
950 KeFeatureBits &= ~KF_FAST_SYSCALL;
952 DPRINT1("Support for SYSENTER disabled.\n");
953 }
954 else
955 {
956 /* Do an IPI to enable it */
958
959 /* It's enabled, so use the proper exit stub */
961 DPRINT("Support for SYSENTER detected.\n");
962 }
963 }
964 else
965 {
966 /* Use the IRET handler */
968 DPRINT1("No support for SYSENTER detected.\n");
969 }
970}
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:927
#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 846 of file cpu.c.

847{
848 PKGDTENTRY TssEntry;
849
850 //
851 // Restore the CR registers
852 //
853 __writecr0(ProcessorState->SpecialRegisters.Cr0);
854 Ke386SetCr2(ProcessorState->SpecialRegisters.Cr2);
855 __writecr3(ProcessorState->SpecialRegisters.Cr3);
856 if (KeFeatureBits & KF_CR4) __writecr4(ProcessorState->SpecialRegisters.Cr4);
857
858 //
859 // Restore the DR registers
860 //
861 __writedr(0, ProcessorState->SpecialRegisters.KernelDr0);
862 __writedr(1, ProcessorState->SpecialRegisters.KernelDr1);
863 __writedr(2, ProcessorState->SpecialRegisters.KernelDr2);
864 __writedr(3, ProcessorState->SpecialRegisters.KernelDr3);
865 __writedr(6, ProcessorState->SpecialRegisters.KernelDr6);
866 __writedr(7, ProcessorState->SpecialRegisters.KernelDr7);
867
868 //
869 // Restore GDT and IDT
870 //
872 __lidt(&ProcessorState->SpecialRegisters.Idtr.Limit);
873
874 //
875 // Clear the busy flag so we don't crash if we reload the same selector
876 //
877 TssEntry = (PKGDTENTRY)(ProcessorState->SpecialRegisters.Gdtr.Base +
878 ProcessorState->SpecialRegisters.Tr);
879 TssEntry->HighWord.Bytes.Flags1 &= ~0x2;
880
881 //
882 // Restore TSS and LDT
883 //
884 Ke386SetTr(ProcessorState->SpecialRegisters.Tr);
885 Ke386SetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr);
886}
#define Ke386SetGlobalDescriptorTable
Definition: intrin_i.h:453
__INTRIN_INLINE void __writedr(unsigned reg, unsigned int value)
Definition: intrin_x86.h:1967
ULONG Base
Definition: ketypes.h:450
USHORT Limit
Definition: ketypes.h:449
KSPECIAL_REGISTERS SpecialRegisters
Definition: ketypes.h:635
ULONG64 KernelDr1
Definition: ketypes.h:606
ULONG64 KernelDr2
Definition: ketypes.h:607
ULONG64 KernelDr0
Definition: ketypes.h:605
KDESCRIPTOR Gdtr
Definition: ketypes.h:611
KDESCRIPTOR Idtr
Definition: ketypes.h:612
ULONG64 KernelDr7
Definition: ketypes.h:610
ULONG64 KernelDr6
Definition: ketypes.h:609
ULONG64 KernelDr3
Definition: ketypes.h:608

◆ KiSaveProcessorControlState()

VOID NTAPI KiSaveProcessorControlState ( OUT PKPROCESSOR_STATE  ProcessorState)

Definition at line 890 of file cpu.c.

891{
892 /* Save the CR registers */
893 ProcessorState->SpecialRegisters.Cr0 = __readcr0();
894 ProcessorState->SpecialRegisters.Cr2 = __readcr2();
895 ProcessorState->SpecialRegisters.Cr3 = __readcr3();
896 ProcessorState->SpecialRegisters.Cr4 = (KeFeatureBits & KF_CR4) ?
897 __readcr4() : 0;
898
899 /* Save the DR registers */
900 ProcessorState->SpecialRegisters.KernelDr0 = __readdr(0);
901 ProcessorState->SpecialRegisters.KernelDr1 = __readdr(1);
902 ProcessorState->SpecialRegisters.KernelDr2 = __readdr(2);
903 ProcessorState->SpecialRegisters.KernelDr3 = __readdr(3);
904 ProcessorState->SpecialRegisters.KernelDr6 = __readdr(6);
905 ProcessorState->SpecialRegisters.KernelDr7 = __readdr(7);
906 __writedr(7, 0);
907
908 /* Save GDT, IDT, LDT and TSS */
909 Ke386GetGlobalDescriptorTable(&ProcessorState->SpecialRegisters.Gdtr.Limit);
910 __sidt(&ProcessorState->SpecialRegisters.Idtr.Limit);
911 ProcessorState->SpecialRegisters.Tr = Ke386GetTr();
912 Ke386GetLocalDescriptorTable(&ProcessorState->SpecialRegisters.Ldtr);
913}
#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:1934
__INTRIN_INLINE unsigned long __readcr2(void)
Definition: intrin_x86.h:1843

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

◆ KiSaveProcessorState()

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

Definition at line 1068 of file cpu.c.

1070{
1071 PKPRCB Prcb = KeGetCurrentPrcb();
1072
1073 //
1074 // Save full context
1075 //
1079
1080 //
1081 // Save control registers
1082 //
1084}
#define CONTEXT_DEBUG_REGISTERS
Definition: nt_native.h:1376
#define CONTEXT_FULL
Definition: nt_native.h:1378
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:1429
KPROCESSOR_STATE ProcessorState
Definition: ketypes.h:683
CONTEXT ContextFrame
Definition: ketypes.h:636

◆ KiSetCR0Bits()

VOID NTAPI KiSetCR0Bits ( VOID  )

Definition at line 658 of file cpu.c.

659{
660 ULONG Cr0;
661
662 /* Save current CR0 */
663 Cr0 = __readcr0();
664
665 /* If this is a 486, enable Write-Protection */
666 if (KeGetCurrentPrcb()->CpuType > 3) Cr0 |= CR0_WP;
667
668 /* Set new Cr0 */
669 __writecr0(Cr0);
670}
#define CR0_WP
Definition: ketypes.h:145

Referenced by KiInitMachineDependent().

◆ KiSetProcessorType()

VOID NTAPI KiSetProcessorType ( VOID  )

Definition at line 96 of file cpu.c.

97{
98 PKPRCB Prcb = KeGetCurrentPrcb();
99 USHORT Family, Model, Stepping;
100
101 /* Get the CPU vendor string */
103
104 /* Get the family, model and stepping */
105 KiGetCpuSignature(&Family, &Model, &Stepping);
106
107 /* Save them in the PRCB */
108 Prcb->CpuID = TRUE;
109 Prcb->CpuType = (UCHAR)Family;
110 Prcb->CpuStep = ((Model << 8) | Stepping);
111}
VOID NTAPI KiGetCpuSignature(_Out_ PUSHORT Family, _Out_ PUSHORT Model, _Out_ PUSHORT Stepping)
Get the CPU signature.
Definition: cpuinfo.c:118
VOID NTAPI KiGetCpuVendorString(_Out_writes_z_(CPU_VENDOR_STR_LEN) CHAR VendorString[CPU_VENDOR_STR_LEN])
Get the CPUID information for a given CPU.
Definition: cpuinfo.c:24
static int Family
Definition: ping.c:62
CHAR CpuID
Definition: ketypes.h:685
UCHAR VendorString[13]
Definition: ketypes.h:901

Referenced by KiInitializeCpu(), and KiVerifyCpuFeatures().

◆ setCx86()

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

Definition at line 76 of file cpu.c.

77{
80}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950

Referenced by KiGetFeatureBits().

Variable Documentation

◆ 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.

Referenced by CmpInitializeHardwareConfiguration().

◆ 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.