ReactOS 0.4.17-dev-1190-g4c812f4
cpu.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ke/i386/cpu.c
5 * PURPOSE: Routines for CPU-level support
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9/* INCLUDES *****************************************************************/
10
11#include <ntoskrnl.h>
12#include <xmmintrin.h>
13
14#define NDEBUG
15#include <debug.h>
16
17/* GLOBALS *******************************************************************/
18
19/* The TSS to use for Double Fault Traps (INT 0x9) */
21
22/* The TSS to use for NMI Fault Traps (INT 0x2) */
24
25/* CPU Features and Flags */
44
45/* The distance between SYSEXIT and IRETD return modes */
47
48/* The offset that was applied -- either 0 or the value above */
50
51/* Whether the adjustment was already done once */
53
54/* Flush data */
56
57/* FX area alignment size */
58#define FXSAVE_ALIGN 15
59
60/* SUPPORT ROUTINES FOR MSVC COMPATIBILITY ***********************************/
61
62/* NSC/Cyrix CPU configuration register index */
63#define CX86_CCR1 0xc1
64
65/* NSC/Cyrix CPU indexed register access macros */
66static __inline
69{
71 return READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)0x23);
72}
73
74static __inline
75void
77{
80}
81
82/* FUNCTIONS *****************************************************************/
83
84CODE_SEG("INIT")
85static
88{
89 ASSERT(KeGetCurrentPrcb()->VendorString[0] != 0);
90 return KiIdentifyCpuVendor(KeGetCurrentPrcb()->VendorString);
91}
92
93CODE_SEG("INIT")
94VOID
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}
112
113CODE_SEG("INIT")
115NTAPI
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}
341
342#if DBG
343CODE_SEG("INIT")
344VOID
345KiReportCpuFeatures(VOID)
346{
347 ULONG CpuFeatures = 0;
348 CPU_INFO CpuInfo;
349
350 if (KiGetCpuVendor())
351 {
352 KiCpuId(&CpuInfo, 1);
353 CpuFeatures = CpuInfo.Edx;
354 }
355
356 DPRINT1("Supported CPU features:");
357
358#define print_kf_bit(kf_value) if (KeFeatureBits & kf_value) DbgPrint(" " #kf_value)
359 print_kf_bit(KF_V86_VIS);
360 print_kf_bit(KF_RDTSC);
361 print_kf_bit(KF_CR4);
362 print_kf_bit(KF_CMOV);
363 print_kf_bit(KF_GLOBAL_PAGE);
364 print_kf_bit(KF_LARGE_PAGE);
365 print_kf_bit(KF_MTRR);
366 print_kf_bit(KF_CMPXCHG8B);
367 print_kf_bit(KF_MMX);
368 print_kf_bit(KF_WORKING_PTE);
369 print_kf_bit(KF_PAT);
370 print_kf_bit(KF_FXSR);
371 print_kf_bit(KF_FAST_SYSCALL);
372 print_kf_bit(KF_XMMI);
373 print_kf_bit(KF_3DNOW);
374 print_kf_bit(KF_AMDK6MTRR);
375 print_kf_bit(KF_XMMI64);
376 print_kf_bit(KF_DTS);
377 print_kf_bit(KF_NX_BIT);
378 print_kf_bit(KF_NX_DISABLED);
379 print_kf_bit(KF_NX_ENABLED);
380#undef print_kf_bit
381
382#define print_cf(cpu_flag) if (CpuFeatures & cpu_flag) DbgPrint(" " #cpu_flag)
383 print_cf(X86_FEATURE_PAE);
384 print_cf(X86_FEATURE_APIC);
385 print_cf(X86_FEATURE_HT);
386#undef print_cf
387
388 DbgPrint("\n");
389}
390#endif // DBG
391
392CODE_SEG("INIT")
393VOID
394NTAPI
396{
397 PKIPCR Pcr = (PKIPCR)KeGetPcr();
398 ULONG CacheCount;
399
400 /* Set default L2 size */
401 Pcr->SecondLevelCacheSize = 0;
402
403#if (NTDDI_VERSION >= NTDDI_VISTA)
404 /* Retrieve the cache descriptors */
405 PKPRCB Prcb = KeGetCurrentPrcb();
406 CacheCount = KiGetCpuCacheDescriptors(Prcb->Cache,
407 ARRAYSIZE(Prcb->Cache),
409 Prcb->CacheCount = CacheCount;
410#else
411 /* Retrieve the cache descriptors */
412 CACHE_DESCRIPTOR CacheDescriptors[5];
413 CacheCount = KiGetCpuCacheDescriptors(CacheDescriptors,
414 ARRAYSIZE(CacheDescriptors),
416#endif
417
418 /* Loop the descriptors to find the L2 cache size */
419 for (ULONG i = 0; i < CacheCount; i++)
420 {
421 KeLargestCacheLine = max(KeLargestCacheLine, CacheDescriptors[i].LineSize);
422 if ((CacheDescriptors[i].Level == 1) && (CacheDescriptors[i].Type != CacheInstruction))
423 {
424 KePrefetchNTAGranularity = CacheDescriptors[i].LineSize;
425 }
426 else if (CacheDescriptors[i].Level == 2)
427 {
428 Pcr->SecondLevelCacheSize = CacheDescriptors[i].Size;
429 Pcr->SecondLevelCacheAssociativity = CacheDescriptors[i].Associativity;
430 }
431 }
432
433 /* Set the cache line */
434 DPRINT1("Prefetch Cache: %lu bytes\tL2 Cache: %lu bytes\tL2 Cache Line: %lu bytes\tL2 Cache Associativity: %lu\n",
439}
440
441CODE_SEG("INIT")
442VOID
443NTAPI
445{
446 ULONG Cr0;
447
448 /* Save current CR0 */
449 Cr0 = __readcr0();
450
451 /* If this is a 486, enable Write-Protection */
452 if (KeGetCurrentPrcb()->CpuType > 3) Cr0 |= CR0_WP;
453
454 /* Set new Cr0 */
455 __writecr0(Cr0);
456}
457
458CODE_SEG("INIT")
459VOID
460NTAPI
462 IN PKGDTENTRY TssEntry OPTIONAL)
463{
464 PUCHAR p;
465
466 /* Make sure the GDT Entry is valid */
467 if (TssEntry)
468 {
469 /* Set the Limit */
470 TssEntry->LimitLow = sizeof(KTSS) - 1;
471 TssEntry->HighWord.Bits.LimitHi = 0;
472 }
473
474 /* Now clear the I/O Map */
475 ASSERT(IOPM_COUNT == 1);
476 RtlFillMemory(Tss->IoMaps[0].IoMap, IOPM_FULL_SIZE, 0xFF);
477
478 /* Initialize Interrupt Direction Maps */
479 p = (PUCHAR)(Tss->IoMaps[0].DirectionMap);
481
482 /* Add DPMI support for interrupts */
483 p[0] = 4;
484 p[3] = 0x18;
485 p[4] = 0x18;
486
487 /* Initialize the default Interrupt Direction Map */
488 p = Tss->IntDirectionMap;
489 RtlZeroMemory(Tss->IntDirectionMap, IOPM_DIRECTION_MAP_SIZE);
490
491 /* Add DPMI support */
492 p[0] = 4;
493 p[3] = 0x18;
494 p[4] = 0x18;
495}
496
497VOID
498NTAPI
500{
501 /* Set an invalid map base */
502 Tss->IoMapBase = KiComputeIopmOffset(IO_ACCESS_MAP_NONE);
503
504 /* Disable traps during Task Switches */
505 Tss->Flags = 0;
506
507 /* Set LDT and Ring 0 SS */
508 Tss->LDT = 0;
509 Tss->Ss0 = KGDT_R0_DATA;
510}
511
512CODE_SEG("INIT")
513VOID
516 IN PKIDTENTRY Idt,
517 IN PKGDTENTRY Gdt)
518{
519 PKGDTENTRY TssEntry, TaskGateEntry;
520
521 /* Initialize the boot TSS. */
522 TssEntry = &Gdt[KGDT_TSS / sizeof(KGDTENTRY)];
523 TssEntry->HighWord.Bits.Type = I386_TSS;
524 TssEntry->HighWord.Bits.Pres = 1;
525 TssEntry->HighWord.Bits.Dpl = 0;
526 KiInitializeTSS2(Tss, TssEntry);
527 KiInitializeTSS(Tss);
528
529 /* Load the task register */
530 Ke386SetTr(KGDT_TSS);
531
532 /* Setup the Task Gate for Double Fault Traps */
533 TaskGateEntry = (PKGDTENTRY)&Idt[8];
534 TaskGateEntry->HighWord.Bits.Type = I386_TASK_GATE;
535 TaskGateEntry->HighWord.Bits.Pres = 1;
536 TaskGateEntry->HighWord.Bits.Dpl = 0;
537 ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_DF_TSS;
538
539 /* Initialize the TSS used for handling double faults. */
540 Tss = (PKTSS)KiDoubleFaultTSS;
541 KiInitializeTSS(Tss);
542 Tss->CR3 = __readcr3();
543 Tss->Esp0 = KiDoubleFaultStack;
544 Tss->Esp = KiDoubleFaultStack;
545 Tss->Eip = PtrToUlong(KiTrap08);
546 Tss->Cs = KGDT_R0_CODE;
547 Tss->Fs = KGDT_R0_PCR;
548 Tss->Ss = Ke386GetSs();
549 Tss->Es = KGDT_R3_DATA | RPL_MASK;
550 Tss->Ds = KGDT_R3_DATA | RPL_MASK;
551
552 /* Setup the Double Trap TSS entry in the GDT */
553 TssEntry = &Gdt[KGDT_DF_TSS / sizeof(KGDTENTRY)];
554 TssEntry->HighWord.Bits.Type = I386_TSS;
555 TssEntry->HighWord.Bits.Pres = 1;
556 TssEntry->HighWord.Bits.Dpl = 0;
557 TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF);
558 TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16);
559 TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
560 TssEntry->LimitLow = KTSS_IO_MAPS;
561
562 /* Now setup the NMI Task Gate */
563 TaskGateEntry = (PKGDTENTRY)&Idt[2];
564 TaskGateEntry->HighWord.Bits.Type = I386_TASK_GATE;
565 TaskGateEntry->HighWord.Bits.Pres = 1;
566 TaskGateEntry->HighWord.Bits.Dpl = 0;
567 ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_NMI_TSS;
568
569 /* Initialize the actual TSS */
570 Tss = (PKTSS)KiNMITSS;
571 KiInitializeTSS(Tss);
572 Tss->CR3 = __readcr3();
573 Tss->Esp0 = KiDoubleFaultStack;
574 Tss->Esp = KiDoubleFaultStack;
575 Tss->Eip = PtrToUlong(KiTrap02);
576 Tss->Cs = KGDT_R0_CODE;
577 Tss->Fs = KGDT_R0_PCR;
578 Tss->Ss = Ke386GetSs();
579 Tss->Es = KGDT_R3_DATA | RPL_MASK;
580 Tss->Ds = KGDT_R3_DATA | RPL_MASK;
581
582 /* And its associated TSS Entry */
583 TssEntry = &Gdt[KGDT_NMI_TSS / sizeof(KGDTENTRY)];
584 TssEntry->HighWord.Bits.Type = I386_TSS;
585 TssEntry->HighWord.Bits.Pres = 1;
586 TssEntry->HighWord.Bits.Dpl = 0;
587 TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF);
588 TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16);
589 TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
590 TssEntry->LimitLow = KTSS_IO_MAPS;
591}
592
593VOID
594NTAPI
596{
597
598#if !defined(_GLOBAL_PAGES_ARE_AWESOME_)
599
600 /* Flush the TLB by resetting CR3 */
602
603#else
604
605 /* Check if global pages are enabled */
607 {
608 ULONG Cr4;
609
610 /* Disable PGE (Note: may not have been enabled yet) */
611 Cr4 = __readcr4();
612 __writecr4(Cr4 & ~CR4_PGE);
613
614 /* Flush everything */
616
617 /* Re-enable PGE */
618 __writecr4(Cr4);
619 }
620 else
621 {
622 /* No global pages, resetting CR3 is enough */
624 }
625
626#endif
627
628}
629
630VOID
631NTAPI
633{
634 PKGDTENTRY TssEntry;
635
636 //
637 // Restore the CR registers
638 //
639 __writecr0(ProcessorState->SpecialRegisters.Cr0);
640 Ke386SetCr2(ProcessorState->SpecialRegisters.Cr2);
641 __writecr3(ProcessorState->SpecialRegisters.Cr3);
642 if (KeFeatureBits & KF_CR4) __writecr4(ProcessorState->SpecialRegisters.Cr4);
643
644 //
645 // Restore the DR registers
646 //
647 __writedr(0, ProcessorState->SpecialRegisters.KernelDr0);
648 __writedr(1, ProcessorState->SpecialRegisters.KernelDr1);
649 __writedr(2, ProcessorState->SpecialRegisters.KernelDr2);
650 __writedr(3, ProcessorState->SpecialRegisters.KernelDr3);
651 __writedr(6, ProcessorState->SpecialRegisters.KernelDr6);
652 __writedr(7, ProcessorState->SpecialRegisters.KernelDr7);
653
654 //
655 // Restore GDT and IDT
656 //
658 __lidt(&ProcessorState->SpecialRegisters.Idtr.Limit);
659
660 //
661 // Clear the busy flag so we don't crash if we reload the same selector
662 //
663 TssEntry = (PKGDTENTRY)(ProcessorState->SpecialRegisters.Gdtr.Base +
664 ProcessorState->SpecialRegisters.Tr);
665 TssEntry->HighWord.Bytes.Flags1 &= ~0x2;
666
667 //
668 // Restore TSS and LDT
669 //
670 Ke386SetTr(ProcessorState->SpecialRegisters.Tr);
671 Ke386SetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr);
672}
673
674VOID
675NTAPI
677{
678 /* Save the CR registers */
679 ProcessorState->SpecialRegisters.Cr0 = __readcr0();
680 ProcessorState->SpecialRegisters.Cr2 = __readcr2();
681 ProcessorState->SpecialRegisters.Cr3 = __readcr3();
682 ProcessorState->SpecialRegisters.Cr4 = (KeFeatureBits & KF_CR4) ?
683 __readcr4() : 0;
684
685 /* Save the DR registers */
686 ProcessorState->SpecialRegisters.KernelDr0 = __readdr(0);
687 ProcessorState->SpecialRegisters.KernelDr1 = __readdr(1);
688 ProcessorState->SpecialRegisters.KernelDr2 = __readdr(2);
689 ProcessorState->SpecialRegisters.KernelDr3 = __readdr(3);
690 ProcessorState->SpecialRegisters.KernelDr6 = __readdr(6);
691 ProcessorState->SpecialRegisters.KernelDr7 = __readdr(7);
692 __writedr(7, 0);
693
694 /* Save GDT, IDT, LDT and TSS */
695 Ke386GetGlobalDescriptorTable(&ProcessorState->SpecialRegisters.Gdtr.Limit);
696 __sidt(&ProcessorState->SpecialRegisters.Idtr.Limit);
697 ProcessorState->SpecialRegisters.Tr = Ke386GetTr();
698 Ke386GetLocalDescriptorTable(&ProcessorState->SpecialRegisters.Ldtr);
699}
700
701CODE_SEG("INIT")
702VOID
703NTAPI
705{
706 /* Set the Machine Type we got from NTLDR */
708}
709
710CODE_SEG("INIT")
712NTAPI
714{
715 /* Set CS and ESP */
716 __writemsr(0x174, KGDT_R0_CODE);
717 __writemsr(0x175, (ULONG_PTR)KeGetCurrentPrcb()->DpcStack);
718
719 /* Set LSTAR */
721 return 0;
722}
723
724CODE_SEG("INIT")
725VOID
726NTAPI
728{
729 /* Check if the CPU Supports fast system call */
731 {
732 /* Check if it has been disabled */
734 {
735 /* Disable fast system call */
736 KeFeatureBits &= ~KF_FAST_SYSCALL;
738 DPRINT1("Support for SYSENTER disabled.\n");
739 }
740 else
741 {
742 /* Do an IPI to enable it */
744
745 /* It's enabled, so use the proper exit stub */
747 DPRINT("Support for SYSENTER detected.\n");
748 }
749 }
750 else
751 {
752 /* Use the IRET handler */
754 DPRINT1("No support for SYSENTER detected.\n");
755 }
756}
757
758CODE_SEG("INIT")
760NTAPI
762{
763 /* Enable DE */
765 return 0;
766}
767
768CODE_SEG("INIT")
770NTAPI
772{
773 /* Enable FXSR */
775 return 0;
776}
777
778CODE_SEG("INIT")
780NTAPI
782{
783 PKIDTENTRY IdtEntry;
784
785 /* Get the IDT Entry for Interrupt 0x13 */
786 IdtEntry = &((PKIPCR)KeGetPcr())->IDT[0x13];
787
788 /* Set it up */
789 IdtEntry->Selector = KGDT_R0_CODE;
790 IdtEntry->Offset = ((ULONG_PTR)KiTrap13 & 0xFFFF);
791 IdtEntry->ExtendedOffset = ((ULONG_PTR)KiTrap13 >> 16) & 0xFFFF;
792 ((PKIDT_ACCESS)&IdtEntry->Access)->Dpl = 0;
793 ((PKIDT_ACCESS)&IdtEntry->Access)->Present = 1;
794 ((PKIDT_ACCESS)&IdtEntry->Access)->SegmentType = I386_INTERRUPT_GATE;
795
796 /* Enable XMMI exceptions */
798 return 0;
799}
800
801CODE_SEG("INIT")
802VOID
803NTAPI
805{
806 KDESCRIPTOR IdtDescriptor = {0, 0, 0};
807 PKIDTENTRY NewIdt, NewIdt2;
808 PMMPTE PointerPte;
809
810 /* Allocate memory for a new IDT */
812
813 /* Put everything after the first 7 entries on a new page */
814 NewIdt2 = (PVOID)((ULONG_PTR)NewIdt + PAGE_SIZE - (7 * sizeof(KIDTENTRY)));
815
816 /* Disable interrupts */
817 _disable();
818
819 /* Get the current IDT and copy it */
820 __sidt(&IdtDescriptor.Limit);
821 RtlCopyMemory(NewIdt2,
822 (PVOID)IdtDescriptor.Base,
823 IdtDescriptor.Limit + 1);
824 IdtDescriptor.Base = (ULONG)NewIdt2;
825
826 /* Set the new IDT */
827 __lidt(&IdtDescriptor.Limit);
828 ((PKIPCR)KeGetPcr())->IDT = NewIdt2;
829
830 /* Restore interrupts */
831 _enable();
832
833 /* Set the first 7 entries as read-only to produce a fault */
834 PointerPte = MiAddressToPte(NewIdt);
835 ASSERT(PointerPte->u.Hard.Write == 1);
836 PointerPte->u.Hard.Write = 0;
837 KeInvalidateTlbEntry(NewIdt);
838}
839
841NTAPI
843{
844 /* Only supported on Pentium Pro and higher */
845 if (KeI386CpuType < 6) return FALSE;
846
847 /* Invalidate all caches */
848 __wbinvd();
849 return TRUE;
850}
851
852VOID
853NTAPI
855 IN PKEXCEPTION_FRAME ExceptionFrame)
856{
857 PKPRCB Prcb = KeGetCurrentPrcb();
858
859 //
860 // Save full context
861 //
865
866 //
867 // Save control registers
868 //
870}
871
872CODE_SEG("INIT")
874NTAPI
876{
877 static double Value1 = 4195835.0, Value2 = 3145727.0;
878 INT ErrataPresent;
879 ULONG Cr0;
880
881 /* Interrupts have to be disabled here. */
883
884 /* Read CR0 and remove FPU flags */
885 Cr0 = __readcr0();
886 __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
887
888 /* Initialize FPU state */
889 Ke386FnInit();
890
891 /* Multiply the magic values and divide, we should get the result back */
892#ifdef __GNUC__
893 __asm__ __volatile__
894 (
895 "fldl %1\n\t"
896 "fdivl %2\n\t"
897 "fmull %2\n\t"
898 "fldl %1\n\t"
899 "fsubp\n\t"
900 "fistpl %0\n\t"
901 : "=m" (ErrataPresent)
902 : "m" (Value1),
903 "m" (Value2)
904 );
905#else
906 __asm
907 {
908 fld Value1
909 fdiv Value2
910 fmul Value2
911 fld Value1
912 fsubp st(1), st(0)
913 fistp ErrataPresent
914 };
915#endif
916
917 /* Restore CR0 */
918 __writecr0(Cr0);
919
920 /* Return if there's an errata */
921 return ErrataPresent != 0;
922}
923
924VOID
925NTAPI
927{
928 ULONG EFlags, Cr0;
929 PKTHREAD Thread, NpxThread;
930 PFX_SAVE_AREA FxSaveArea;
931
932 /* Save volatiles and disable interrupts */
933 EFlags = __readeflags();
934 _disable();
935
936 /* Save the PCR and get the current thread */
938
939 /* Check if we're already loaded */
940 if (Thread->NpxState != NPX_STATE_LOADED)
941 {
942 /* If there's nothing to load, quit */
943 if (!SaveArea)
944 {
945 /* Restore interrupt state and return */
946 __writeeflags(EFlags);
947 return;
948 }
949
950 /* Need FXSR support for this */
952
953 /* Check for sane CR0 */
954 Cr0 = __readcr0();
955 if (Cr0 & (CR0_MP | CR0_TS | CR0_EM))
956 {
957 /* Mask out FPU flags */
958 __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
959 }
960
961 /* Get the NPX thread and check its FPU state */
962 NpxThread = KeGetCurrentPrcb()->NpxThread;
963 if ((NpxThread) && (NpxThread->NpxState == NPX_STATE_LOADED))
964 {
965 /* Get the FX frame and store the state there */
966 FxSaveArea = KiGetThreadNpxArea(NpxThread);
967 Ke386FxSave(FxSaveArea);
968
969 /* NPX thread has lost its state */
970 NpxThread->NpxState = NPX_STATE_NOT_LOADED;
971 }
972
973 /* Now load NPX state from the NPX area */
974 FxSaveArea = KiGetThreadNpxArea(Thread);
975 Ke386FxStore(FxSaveArea);
976 }
977 else
978 {
979 /* Check for sane CR0 */
980 Cr0 = __readcr0();
981 if (Cr0 & (CR0_MP | CR0_TS | CR0_EM))
982 {
983 /* Mask out FPU flags */
984 __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
985 }
986
987 /* Get FX frame */
988 FxSaveArea = KiGetThreadNpxArea(Thread);
989 Thread->NpxState = NPX_STATE_NOT_LOADED;
990
991 /* Save state if supported by CPU */
992 if (KeI386FxsrPresent) Ke386FxSave(FxSaveArea);
993 }
994
995 /* Now save the FN state wherever it was requested */
996 if (SaveArea) Ke386FnSave(SaveArea);
997
998 /* Clear NPX thread */
999 KeGetCurrentPrcb()->NpxThread = NULL;
1000
1001 /* Add the CR0 from the NPX frame */
1002 Cr0 |= NPX_STATE_NOT_LOADED;
1003 Cr0 |= FxSaveArea->Cr0NpxState;
1004 __writecr0(Cr0);
1005
1006 /* Restore interrupt state */
1007 __writeeflags(EFlags);
1008}
1009
1010/* PUBLIC FUNCTIONS **********************************************************/
1011
1012/*
1013 * @implemented
1014 */
1015VOID
1016NTAPI
1018{
1019 PFX_SAVE_AREA NpxArea;
1020
1021 /* Get the FPU area */
1023
1024 /* Set CR0_TS */
1025 NpxArea->Cr0NpxState = CR0_TS;
1027}
1028
1054#if defined(__clang__)
1055__attribute__((__target__("sse")))
1056#endif
1058NTAPI
1061{
1063 PFX_SAVE_AREA FxSaveAreaFrame;
1064 PKPRCB CurrentPrcb;
1065
1066 /* Sanity checks */
1067 ASSERT(Save);
1070
1071 /* Initialize the floating point context */
1073 sizeof(FLOATING_SAVE_CONTEXT),
1075 if (!FsContext)
1076 {
1077 /* Bail out if we failed */
1079 }
1080
1081 /*
1082 * Allocate some memory pool for the buffer. The size
1083 * of this allocated buffer is the FX area plus the
1084 * alignment requirement needed for FXSAVE as a 16-byte
1085 * aligned pointer is compulsory in order to save the
1086 * FPU state.
1087 */
1089 sizeof(FX_SAVE_AREA) + FXSAVE_ALIGN,
1091 if (!FsContext->Buffer)
1092 {
1093 /* Bail out if we failed */
1096 }
1097
1098 /*
1099 * Now cache the allocated buffer into the save area
1100 * and align the said area to a 16-byte boundary. Why
1101 * do we have to do this is because of ExAllocate function.
1102 * We gave the necessary alignment requirement in the pool
1103 * allocation size although the function will always return
1104 * a 8-byte aligned pointer. Aligning the given pointer directly
1105 * can cause issues when freeing it from memory afterwards. With
1106 * that said, we have to cache the buffer to the area so that we
1107 * do not touch or mess the allocated buffer any further.
1108 */
1109 FsContext->PfxSaveArea = ALIGN_UP_POINTER_BY(FsContext->Buffer, 16);
1110
1111 /* Disable interrupts and get the current processor control region */
1112 _disable();
1113 CurrentPrcb = KeGetCurrentPrcb();
1114
1115 /* Store the current thread to context */
1116 FsContext->CurrentThread = KeGetCurrentThread();
1117
1118 /*
1119 * Save the previous NPX thread state registers (aka Numeric
1120 * Processor eXtension) into the current context so that
1121 * we are informing the scheduler the current FPU state
1122 * belongs to this thread.
1123 */
1124 if (FsContext->CurrentThread != CurrentPrcb->NpxThread)
1125 {
1126 if ((CurrentPrcb->NpxThread != NULL) &&
1127 (CurrentPrcb->NpxThread->NpxState == NPX_STATE_LOADED))
1128 {
1129 /* Get the FX frame */
1130 FxSaveAreaFrame = KiGetThreadNpxArea(CurrentPrcb->NpxThread);
1131
1132 /* Save the FPU state */
1133 Ke386SaveFpuState(FxSaveAreaFrame);
1134
1135 /* NPX thread has lost its state */
1136 CurrentPrcb->NpxThread->NpxState = NPX_STATE_NOT_LOADED;
1137 FxSaveAreaFrame->NpxSavedCpu = 0;
1138 }
1139
1140 /* The new NPX thread is the current thread */
1141 CurrentPrcb->NpxThread = FsContext->CurrentThread;
1142 }
1143
1144 /* Perform the save */
1145 Ke386SaveFpuState(FsContext->PfxSaveArea);
1146
1147 /* Store the NPX IRQL */
1148 FsContext->OldNpxIrql = FsContext->CurrentThread->Header.NpxIrql;
1149
1150 /* Set the current IRQL to NPX */
1151 FsContext->CurrentThread->Header.NpxIrql = KeGetCurrentIrql();
1152
1153 /* Initialize the FPU */
1154 Ke386FnInit();
1155
1156 /* Enable interrupts back */
1157 _enable();
1158
1159 /* Give the saved FPU context to the caller */
1160 *((PVOID *) Save) = FsContext;
1161 return STATUS_SUCCESS;
1162}
1163
1180#if defined(__clang__)
1181__attribute__((__target__("sse")))
1182#endif
1184NTAPI
1187{
1189
1190 /* Sanity checks */
1191 ASSERT(Save);
1194
1195 /* Cache the saved FS context */
1196 FsContext = *((PVOID *) Save);
1197
1198 /*
1199 * We have to restore the regular saved FPU
1200 * state. For this we must first do some
1201 * validation checks so that we are sure
1202 * ourselves the state context is saved
1203 * properly. Check if we are in the same
1204 * calling thread.
1205 */
1206 if (FsContext->CurrentThread != KeGetCurrentThread())
1207 {
1208 /*
1209 * This isn't the thread that saved the
1210 * FPU state context, crash the system!
1211 */
1212 KeBugCheckEx(INVALID_FLOATING_POINT_STATE,
1213 0x2,
1214 (ULONG_PTR)FsContext->CurrentThread,
1216 0);
1217 }
1218
1219 /* Are we under the same NPX interrupt level? */
1220 if (FsContext->CurrentThread->Header.NpxIrql != KeGetCurrentIrql())
1221 {
1222 /* The interrupt level has changed, crash the system! */
1223 KeBugCheckEx(INVALID_FLOATING_POINT_STATE,
1224 0x1,
1225 (ULONG_PTR)FsContext->CurrentThread->Header.NpxIrql,
1227 0);
1228 }
1229
1230 /* Disable interrupts */
1231 _disable();
1232
1233 /*
1234 * The saved FPU state context is valid,
1235 * it's time to restore the state. First,
1236 * clear FPU exceptions now.
1237 */
1238 Ke386ClearFpExceptions();
1239
1240 /* Restore the state */
1241 Ke386RestoreFpuState(FsContext->PfxSaveArea);
1242
1243 /* Give the saved NPX IRQL back to the NPX thread */
1244 FsContext->CurrentThread->Header.NpxIrql = FsContext->OldNpxIrql;
1245
1246 /* Enable interrupts back */
1247 _enable();
1248
1249 /* We're done, free the allocated area and context */
1252
1253 return STATUS_SUCCESS;
1254}
1255
1256/*
1257 * @implemented
1258 */
1259ULONG
1260NTAPI
1262{
1263 /* Return the global variable */
1264 return KeLargestCacheLine;
1265}
1266
1267VOID
1268NTAPI
1270 IN PVOID Ignored1,
1271 IN PVOID Ignored2,
1272 IN PVOID Ignored3)
1273{
1274 /* Signal this packet as done */
1275 KiIpiSignalPacketDone(PacketContext);
1276
1277 /* Flush the TB for the Current CPU */
1279}
1280
1281/*
1282 * @implemented
1283 */
1284VOID
1285NTAPI
1287 IN BOOLEAN AllProcessors)
1288{
1289 KIRQL OldIrql;
1290#ifdef CONFIG_SMP
1291 KAFFINITY TargetAffinity;
1292 PKPRCB Prcb = KeGetCurrentPrcb();
1293#endif
1294
1295 /* Raise the IRQL for the TB Flush */
1297
1298#ifdef CONFIG_SMP
1299 /* FIXME: Use KiTbFlushTimeStamp to synchronize TB flush */
1300
1301 /* Get the current processor affinity, and exclude ourselves */
1302 TargetAffinity = KeActiveProcessors;
1303 TargetAffinity &= ~Prcb->SetMember;
1304
1305 /* Make sure this is MP */
1306 if (TargetAffinity)
1307 {
1308 /* Send an IPI TB flush to the other processors */
1309 KiIpiSendPacket(TargetAffinity,
1311 NULL,
1312 0,
1313 NULL);
1314 }
1315#endif
1316
1317 /* Flush the TB for the Current CPU, and update the flush stamp */
1319
1320#ifdef CONFIG_SMP
1321 /* If this is MP, wait for the other processors to finish */
1322 if (TargetAffinity)
1323 {
1324 /* Sanity check */
1325 ASSERT(Prcb == KeGetCurrentPrcb());
1326
1327 /* FIXME: TODO */
1328 ASSERTMSG("Not yet implemented\n", FALSE);
1329 }
1330#endif
1331
1332 /* Update the flush stamp and return to original IRQL */
1335}
1336
1337/*
1338 * @implemented
1339 */
1340VOID
1341NTAPI
1343{
1344 /* Save the coherency globally */
1345 KiDmaIoCoherency = Coherency;
1346}
1347
1348/*
1349 * @implemented
1350 */
1351VOID
1352__cdecl
1354{
1355 /* Capture the context */
1356 RtlCaptureContext(&State->ContextFrame);
1357
1358 /* Capture the control state */
1360}
#define CODE_SEG(...)
#define EFLAGS_INTERRUPT_MASK
#define KGDT_R3_DATA
#define RPL_MASK
Type
Definition: Type.h:7
#define __inline
Definition: _wctype.cpp:15
unsigned char BOOLEAN
Definition: actypes.h:127
ULONG64 KeFeatureBits
Definition: krnlinit.c:22
@ Invalid
Definition: asmpp.cpp:35
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
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 __attribute__(x)
Definition: btrfs_drv.h:1197
#define ARRAYSIZE(a)
Definition: cat.c:25
_In_ ULONG _In_ UCHAR Level
Definition: dispmprt.h:1329
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
ULONG_PTR KAFFINITY
Definition: compat.h:85
#define __cdecl
Definition: corecrt.h:121
#define ULONG_PTR
Definition: config.h:101
#define PtrToUlong(u)
Definition: config.h:107
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define NonPagedPool
Definition: env_spec_w32.h:307
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Inout_ PLIST_ENTRY _In_ PVOID FsContext
Definition: fltkernel.h:2239
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLfloat GLfloat p
Definition: glext.h:8902
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
KIRQL NTAPI KeRaiseIrqlToSynchLevel(VOID)
Definition: pic.c:156
#define DbgPrint
Definition: hal.h:12
#define KeGetCurrentThread
Definition: hal.h:55
static int reg
Definition: i386-dis.c:1290
#define Ke386GetGlobalDescriptorTable
Definition: intrin_i.h:452
#define Ke386GetLocalDescriptorTable
Definition: intrin_i.h:454
#define Ke386SetGlobalDescriptorTable
Definition: intrin_i.h:453
#define InterlockedExchangeAdd
Definition: interlocked.h:196
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
PPC_QUAL unsigned long long __readmsr()
Definition: intrin_ppc.h:741
PPC_QUAL void __wbinvd(void)
Definition: intrin_ppc.h:759
__INTRIN_INLINE unsigned long __readcr3(void)
Definition: intrin_x86.h:1850
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1701
__INTRIN_INLINE void __lidt(void *Source)
Definition: intrin_x86.h:2059
__INTRIN_INLINE unsigned int __readdr(unsigned int reg)
Definition: intrin_x86.h:1934
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1857
__INTRIN_INLINE unsigned long __readcr0(void)
Definition: intrin_x86.h:1836
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1706
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1826
__INTRIN_INLINE unsigned long __readcr2(void)
Definition: intrin_x86.h:1843
__INTRIN_INLINE void __writecr0(unsigned int Data)
Definition: intrin_x86.h:1821
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2064
__INTRIN_INLINE void __writecr4(unsigned int Data)
Definition: intrin_x86.h:1831
__INTRIN_INLINE void __writedr(unsigned reg, unsigned int value)
Definition: intrin_x86.h:1967
#define KeSaveFloatingPointState(x)
Definition: kmixer.h:32
#define KeRestoreFloatingPointState(x)
Definition: kmixer.h:33
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
unsigned __int64 ULONG64
Definition: imports.h:198
#define KIDTENTRY
Definition: ketypes.h:584
#define KF_SSE4_2
Definition: ketypes.h:74
#define KiComputeIopmOffset(MapNumber)
Definition: ketypes.h:363
#define CR4_PGE
Definition: ketypes.h:161
#define KF_SSSE3
Definition: ketypes.h:72
#define KF_MTRR
Definition: ketypes.h:37
#define CR0_WP
Definition: ketypes.h:145
#define KTSS
Definition: ketypes.h:1033
#define IO_ACCESS_MAP_NONE
Definition: ketypes.h:361
#define CR4_XMMEXCPT
Definition: ketypes.h:163
#define PKIDTENTRY
Definition: ketypes.h:585
#define KF_XSTATE
Definition: ketypes.h:55
#define CR0_MP
Definition: ketypes.h:140
#define KF_DTS
Definition: ketypes.h:40
#define CR0_EM
Definition: ketypes.h:141
#define I386_TASK_GATE
Definition: ketypes.h:114
#define I386_TSS
Definition: ketypes.h:115
#define KF_NX_DISABLED
Definition: ketypes.h:62
#define KF_CR4
Definition: ketypes.h:33
#define KF_XMMI64
Definition: ketypes.h:48
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1197
#define KF_CMOV
Definition: ketypes.h:34
#define KF_AMDK6MTRR
Definition: ketypes.h:46
#define KF_SSE4_1
Definition: ketypes.h:73
#define PKTSS
Definition: ketypes.h:1034
#define KF_CMPXCHG8B
Definition: ketypes.h:38
#define KF_NX_ENABLED
Definition: ketypes.h:63
#define KF_RDTSC
Definition: ketypes.h:32
#define PKGDTENTRY
Definition: ketypes.h:543
#define KF_FAST_SYSCALL
Definition: ketypes.h:43
#define KF_3DNOW
Definition: ketypes.h:45
struct _KIPCR * PKIPCR
#define KF_NX_BIT
Definition: ketypes.h:61
#define CR4_DE
Definition: ketypes.h:157
#define KF_FXSR
Definition: ketypes.h:42
#define KF_RDRAND
Definition: ketypes.h:64
@ CPU_INTEL
Definition: ketypes.h:100
@ CPU_AMD
Definition: ketypes.h:99
#define KF_LARGE_PAGE
Definition: ketypes.h:36
#define KF_XMMI
Definition: ketypes.h:44
#define CR4_FXSR
Definition: ketypes.h:162
#define KGDTENTRY
Definition: ketypes.h:542
#define KF_MMX
Definition: ketypes.h:39
#define KF_SSE3
Definition: ketypes.h:51
#define KF_PAT
Definition: ketypes.h:41
#define I386_INTERRUPT_GATE
Definition: ketypes.h:118
struct _KIDT_ACCESS * PKIDT_ACCESS
#define KF_GLOBAL_PAGE
Definition: ketypes.h:35
#define CR0_TS
Definition: ketypes.h:142
#define NPX_STATE_NOT_LOADED
Definition: asm.h:265
#define KTSS_IO_MAPS
Definition: asm.h:84
#define NPX_STATE_LOADED
Definition: asm.h:266
#define KF_WORKING_PTE
Definition: ketypes.h:39
#define IOPM_FULL_SIZE
Definition: ketypes.h:240
#define KGDT_NMI_TSS
Definition: ketypes.h:133
#define KGDT_TSS
Definition: ketypes.h:127
#define KeGetPcr()
Definition: ketypes.h:81
#define KF_V86_VIS
Definition: ketypes.h:30
@ CPU_RISE
Definition: ketypes.h:96
@ CPU_CENTAUR
Definition: ketypes.h:95
@ CPU_CYRIX
Definition: ketypes.h:92
@ CPU_TRANSMETA
Definition: ketypes.h:93
#define KGDT_R0_PCR
Definition: ketypes.h:128
#define IOPM_DIRECTION_MAP_SIZE
Definition: ketypes.h:242
#define KGDT_DF_TSS
Definition: ketypes.h:132
#define KGDT_R0_CODE
Definition: ketypes.h:123
#define IOPM_COUNT
Definition: ketypes.h:238
#define KGDT_R0_DATA
Definition: ketypes.h:124
NTSYSAPI VOID NTAPI RtlCaptureContext(_Out_ PCONTEXT ContextRecord)
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define CONTEXT_DEBUG_REGISTERS
Definition: nt_native.h:1376
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define FASTCALL
Definition: nt_native.h:50
#define CONTEXT_FULL
Definition: nt_native.h:1378
#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
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:274
#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_PAE
Definition: ke.h:35
#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 MiAddressToPte(x)
Definition: mm.h:144
#define X86_FEATURE_RDRAND
Definition: ke.h:31
VOID __cdecl KiTrap13(VOID)
VOID __cdecl KiTrap02(VOID)
VOID __cdecl KiTrap08(VOID)
#define X86_FEATURE_APIC
Definition: ke.h:41
VOID __cdecl KiFastCallEntry(VOID)
#define X86_FEATURE_SSE4_2
Definition: ke.h:29
FORCEINLINE PFX_SAVE_AREA KiGetThreadNpxArea(IN PKTHREAD Thread)
Definition: ke.h:769
#define X86_FEATURE_SSE4_1
Definition: ke.h:28
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: context.c:169
KAFFINITY KeActiveProcessors
Definition: processor.c:16
VOID FASTCALL KiIpiSignalPacketDone(IN PKIPI_CONTEXT PacketContext)
Definition: ipi.c:57
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
ULONG_PTR KiDoubleFaultStack
Definition: kiinit.c:22
ULONG NTAPI KiGetCpuCacheDescriptors(_Out_writes_(MaxCount) PCACHE_DESCRIPTOR CacheDescriptors, _In_ ULONG MaxCount, _In_ CPU_VENDORS Vendor)
Retrieves cache descriptors for the current CPU.
Definition: cacheinfo.c:484
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
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
ULONG NTAPI KeGetRecommendedSharedDataAlignment(VOID)
Definition: cpu.c:535
VOID NTAPI KiRestoreProcessorControlState(PKPROCESSOR_STATE ProcessorState)
Definition: cpu.c:369
ULONG KeI386NpxPresent
Definition: cpu.c:28
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:361
VOID NTAPI KiSetProcessorType(VOID)
Definition: cpu.c:40
ULONG KeI386MachineType
Definition: cpu.c:27
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:487
ULONG KeLargestCacheLine
Definition: cpu.c:29
VOID __cdecl KeSaveStateForHibernate(IN PKPROCESSOR_STATE State)
Definition: cpu.c:546
BOOLEAN KiSMTProcessorsPresent
Definition: cpu.c:31
ULONG64 NTAPI KiGetFeatureBits(VOID)
Evaluates the KeFeatureFlag bits for the current CPU.
Definition: cpu.c:73
BOOLEAN NTAPI KeInvalidateAllCaches(VOID)
Definition: cpu.c:523
volatile LONG KiTbFlushTimeStamp
Definition: cpu.c:34
VOID NTAPI KiSaveProcessorState(_In_ PKTRAP_FRAME TrapFrame, _In_ PKEXCEPTION_FRAME ExceptionFrame)
Definition: cpu.c:452
VOID NTAPI KeSetDmaIoCoherency(IN ULONG Coherency)
Definition: cpu.c:560
ULONG KeI386CpuType
Definition: cpu.c:25
VOID NTAPI KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
Definition: cpu.c:411
ULONG KiDmaIoCoherency
Definition: cpu.c:30
VOID NTAPI KiGetCacheInformation(VOID)
Definition: cpu.c:334
ULONG KeI386CpuStep
Definition: cpu.c:26
ULONG_PTR NTAPI KeIpiGenericCall(_In_ PKIPI_BROADCAST_WORKER Function, _In_ ULONG_PTR Argument)
Definition: ipi.c:44
ULONG KeDcacheFlushCount
Definition: cpu.c:20
ULONG KeIcacheFlushCount
Definition: cpu.c:19
UCHAR KiDoubleFaultTSS[KTSS_IO_MAPS]
Definition: cpu.c:20
VOID NTAPI KiInitializeMachineType(VOID)
Definition: cpu.c:704
VOID FASTCALL Ki386InitializeTss(IN PKTSS Tss, IN PKIDTENTRY Idt, IN PKGDTENTRY Gdt)
Definition: cpu.c:515
ULONG KeI386XMMIPresent
Definition: cpu.c:32
#define CX86_CCR1
Definition: cpu.c:63
ULONG KiFastSystemCallDisable
Definition: cpu.c:28
#define FXSAVE_ALIGN
Definition: cpu.c:58
VOID NTAPI KiInitializeTSS(IN PKTSS Tss)
Definition: cpu.c:499
VOID NTAPI KiInitializeTSS2(IN PKTSS Tss, IN PKGDTENTRY TssEntry OPTIONAL)
Definition: cpu.c:461
ULONG KePrefetchNTAGranularity
Definition: cpu.c:41
VOID NTAPI KiCoprocessorError(VOID)
Definition: cpu.c:1017
static ULONG KiGetCpuVendor(VOID)
Definition: cpu.c:87
VOID NTAPI KiI386PentiumLockErrataFixup(VOID)
Definition: cpu.c:804
static __inline void setCx86(UCHAR reg, UCHAR data)
Definition: cpu.c:76
BOOLEAN NTAPI KiIsNpxErrataPresent(VOID)
Definition: cpu.c:875
ULONG_PTR NTAPI Ki386EnableXMMIExceptions(IN ULONG_PTR Context)
Definition: cpu.c:781
ULONG_PTR NTAPI KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context)
Definition: cpu.c:713
ULONG_PTR NTAPI Ki386EnableFxsr(IN ULONG_PTR Context)
Definition: cpu.c:771
VOID NTAPI KiFlushNPXState(IN PFLOATING_SAVE_AREA SaveArea)
Definition: cpu.c:926
VOID NTAPI KiRestoreFastSyscallReturnState(VOID)
Definition: cpu.c:727
static __inline UCHAR getCx86(UCHAR reg)
Definition: cpu.c:68
BOOLEAN KiI386PentiumLockErrataPresent
Definition: cpu.c:42
ULONG MxcsrFeatureMask
Definition: cpu.c:31
ULONG KiMXCsrMask
Definition: cpu.c:30
VOID NTAPI KiSetCR0Bits(VOID)
Definition: cpu.c:444
ULONG Ke386Pae
Definition: cpu.c:35
ULONG Ke386NoExecute
Definition: cpu.c:36
BOOLEAN KiFastCallCopyDoneOnce
Definition: cpu.c:52
VOID NTAPI KiFlushTargetEntireTb(IN PKIPI_CONTEXT PacketContext, IN PVOID Ignored1, IN PVOID Ignored2, IN PVOID Ignored3)
Definition: cpu.c:1269
ULONG KeI386FxsrPresent
Definition: cpu.c:33
UCHAR KiSystemCallExitAdjusted
Definition: cpu.c:49
UCHAR KiSystemCallExitAdjust
Definition: cpu.c:46
ULONG_PTR NTAPI Ki386EnableDE(IN ULONG_PTR Context)
Definition: cpu.c:761
UCHAR KiNMITSS[KTSS_IO_MAPS]
Definition: cpu.c:23
NTSYSAPI PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:28
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
static int Family
Definition: ping.c:62
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:603
__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")
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 DPRINT
Definition: sndvol32.h:73
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
UCHAR Associativity
Definition: ketypes.h:52
USHORT LineSize
Definition: ketypes.h:53
ULONG ContextFlags
Definition: nt_native.h:1429
ULONG Base
Definition: ketypes.h:461
USHORT Limit
Definition: ketypes.h:460
ULONG NpxSavedCpu
Definition: ketypes.h:515
ULONG Cr0NpxState
Definition: ketypes.h:516
ULONG MachineType
Definition: arc.h:713
PVOID Base
Definition: ketypes.h:591
USHORT Limit
Definition: ketypes.h:590
struct _KGDTENTRY::@2942::@2944 Bits
USHORT BaseLow
Definition: ketypes.h:401
USHORT LimitLow
Definition: ketypes.h:400
struct _KGDTENTRY::@2942::@2943 Bytes
union _KGDTENTRY::@2942 HighWord
USHORT Offset
Definition: ketypes.h:451
USHORT Selector
Definition: ketypes.h:452
USHORT Access
Definition: ketypes.h:453
USHORT ExtendedOffset
Definition: ketypes.h:454
ULONG SecondLevelCacheSize
Definition: ketypes.h:995
UCHAR SecondLevelCacheAssociativity
Definition: ketypes.h:986
CHAR CpuType
Definition: ketypes.h:684
ULONG CacheCount
Definition: ketypes.h:908
CACHE_DESCRIPTOR Cache[5]
Definition: ketypes.h:907
USHORT CpuStep
Definition: ketypes.h:689
CHAR CpuID
Definition: ketypes.h:685
UCHAR VendorString[13]
Definition: ketypes.h:901
UCHAR LogicalProcessorsPerPhysicalProcessor
Definition: ketypes.h:770
ULONG InitialApicId
Definition: ketypes.h:721
struct _KTHREAD * NpxThread
Definition: ketypes.h:578
LARGE_INTEGER UpdateSignature
Definition: ketypes.h:904
KPROCESSOR_STATE ProcessorState
Definition: ketypes.h:683
KSPECIAL_REGISTERS SpecialRegisters
Definition: ketypes.h:635
CONTEXT ContextFrame
Definition: ketypes.h:636
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
ULONG64 NpxState
Definition: ketypes.h:2215
Definition: ketypes.h:865
I386_LOADER_BLOCK I386
Definition: arc.h:861
union _LOADER_PARAMETER_BLOCK::@4172 u
ULONG64 Write
Definition: mmtypes.h:170
union _MMPTE::@2788 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define max(a, b)
Definition: svc.c:63
#define TAG_FLOATING_POINT_CONTEXT
Definition: tag.h:44
#define TAG_FLOATING_POINT_FX
Definition: tag.h:43
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
unsigned char UCHAR
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ALIGN_UP_POINTER_BY(ptr, align)
Definition: umtypes.h:85
ULONG Ebx
Definition: ketypes.h:402
ULONG Eax
Definition: ketypes.h:401
ULONG Ecx
Definition: ketypes.h:403
ULONG Edx
Definition: ketypes.h:404
LONGLONG QuadPart
Definition: typedefs.h:114
static int Save(const char **args)
Definition: vfdcmd.c:1851
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ CacheInstruction
Definition: ketypes.h:45