ReactOS 0.4.15-dev-7958-gcd0bb1a
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#define NDEBUG
13#include <debug.h>
14
15#include <xmmintrin.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/* CPU Signatures */
58static const CHAR CmpIntelID[] = "GenuineIntel";
59static const CHAR CmpAmdID[] = "AuthenticAMD";
60static const CHAR CmpCyrixID[] = "CyrixInstead";
61static const CHAR CmpTransmetaID[] = "GenuineTMx86";
62static const CHAR CmpCentaurID[] = "CentaurHauls";
63static const CHAR CmpRiseID[] = "RiseRiseRise";
64
65typedef union _CPU_SIGNATURE
66{
67 struct
68 {
69 ULONG Step : 4;
70 ULONG Model : 4;
71 ULONG Family : 4;
72 ULONG Unused : 4;
75 ULONG Unused2 : 4;
76 };
79
80/* FX area alignment size */
81#define FXSAVE_ALIGN 15
82
83/* SUPPORT ROUTINES FOR MSVC COMPATIBILITY ***********************************/
84
85/* NSC/Cyrix CPU configuration register index */
86#define CX86_CCR1 0xc1
87
88/* NSC/Cyrix CPU indexed register access macros */
89static __inline
92{
94 return READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)0x23);
95}
96
97static __inline
98void
100{
103}
104
105/* FUNCTIONS *****************************************************************/
106
107CODE_SEG("INIT")
108ULONG
109NTAPI
111{
112 PKPRCB Prcb = KeGetCurrentPrcb();
113 CPU_INFO CpuInfo;
114
115 /* Get the Vendor ID */
116 KiCpuId(&CpuInfo, 0);
117
118 /* Copy it to the PRCB and null-terminate it */
119 *(ULONG*)&Prcb->VendorString[0] = CpuInfo.Ebx;
120 *(ULONG*)&Prcb->VendorString[4] = CpuInfo.Edx;
121 *(ULONG*)&Prcb->VendorString[8] = CpuInfo.Ecx;
122 Prcb->VendorString[12] = 0;
123
124 /* Now check the CPU Type */
126 {
127 return CPU_INTEL;
128 }
129 else if (!strcmp(Prcb->VendorString, CmpAmdID))
130 {
131 return CPU_AMD;
132 }
133 else if (!strcmp(Prcb->VendorString, CmpCyrixID))
134 {
135 DPRINT1("Cyrix CPU support not fully tested!\n");
136 return CPU_CYRIX;
137 }
138 else if (!strcmp(Prcb->VendorString, CmpTransmetaID))
139 {
140 DPRINT1("Transmeta CPU support not fully tested!\n");
141 return CPU_TRANSMETA;
142 }
143 else if (!strcmp(Prcb->VendorString, CmpCentaurID))
144 {
145 DPRINT1("Centaur CPU support not fully tested!\n");
146 return CPU_CENTAUR;
147 }
148 else if (!strcmp(Prcb->VendorString, CmpRiseID))
149 {
150 DPRINT1("Rise CPU support not fully tested!\n");
151 return CPU_RISE;
152 }
153
154 /* Unknown CPU */
155 DPRINT1("%s CPU support not fully tested!\n", Prcb->VendorString);
156 return CPU_UNKNOWN;
157}
158
159CODE_SEG("INIT")
160VOID
161NTAPI
163{
164 CPU_INFO CpuInfo;
165 CPU_SIGNATURE CpuSignature;
166 BOOLEAN ExtendModel;
167 ULONG Stepping, Type;
168
169 /* Do CPUID 1 now */
170 KiCpuId(&CpuInfo, 1);
171
172 /*
173 * Get the Stepping and Type. The stepping contains both the
174 * Model and the Step, while the Type contains the returned Family.
175 *
176 * For the stepping, we convert this: zzzzzzxy into this: x0y
177 */
178 CpuSignature.AsULONG = CpuInfo.Eax;
179 Stepping = CpuSignature.Model;
180 ExtendModel = (CpuSignature.Family == 15);
181#if ( (NTDDI_VERSION >= NTDDI_WINXPSP2) && (NTDDI_VERSION < NTDDI_WS03) ) || (NTDDI_VERSION >= NTDDI_WS03SP1)
182 if (CpuSignature.Family == 6)
183 {
184 ULONG Vendor = KiGetCpuVendor();
185 ExtendModel |= (Vendor == CPU_INTEL);
186#if (NTDDI_VERSION >= NTDDI_WIN8)
187 ExtendModel |= (Vendor == CPU_CENTAUR);
188#endif
189 }
190#endif
191 if (ExtendModel)
192 {
193 /* Add ExtendedModel to distinguish from non-extended values. */
194 Stepping |= (CpuSignature.ExtendedModel << 4);
195 }
196 Stepping = (Stepping << 8) | CpuSignature.Step;
197 Type = CpuSignature.Family;
198 if (CpuSignature.Family == 15)
199 {
200 /* Add ExtendedFamily to distinguish from non-extended values.
201 * It must not be larger than 0xF0 to avoid overflow. */
202 Type += min(CpuSignature.ExtendedFamily, 0xF0);
203 }
204
205 /* Save them in the PRCB */
206 KeGetCurrentPrcb()->CpuID = TRUE;
207 KeGetCurrentPrcb()->CpuType = (UCHAR)Type;
208 KeGetCurrentPrcb()->CpuStep = (USHORT)Stepping;
209}
210
211CODE_SEG("INIT")
212ULONG
213NTAPI
215{
216 PKPRCB Prcb = KeGetCurrentPrcb();
217 ULONG Vendor;
218 ULONG FeatureBits = KF_WORKING_PTE;
219 CPU_INFO CpuInfo, DummyCpuInfo;
220 UCHAR Ccr1;
221 BOOLEAN ExtendedCPUID = TRUE;
222 ULONG CpuFeatures = 0;
223
224 /* Get the Vendor ID */
225 Vendor = KiGetCpuVendor();
226
227 /* Make sure we got a valid vendor ID at least. */
228 if (!Vendor) return FeatureBits;
229
230 /* Get the CPUID Info. Features are in Reg[3]. */
231 KiCpuId(&CpuInfo, 1);
232
233 /* Set the initial APIC ID */
234 Prcb->InitialApicId = (UCHAR)(CpuInfo.Ebx >> 24);
235
236 switch (Vendor)
237 {
238 /* Intel CPUs */
239 case CPU_INTEL:
240
241 /* Check if it's a P6 */
242 if (Prcb->CpuType == 6)
243 {
244 /* Perform the special sequence to get the MicroCode Signature */
245 __writemsr(0x8B, 0);
246 KiCpuId(&DummyCpuInfo, 1);
247 Prcb->UpdateSignature.QuadPart = __readmsr(0x8B);
248 }
249 else if (Prcb->CpuType == 5)
250 {
251 /* On P5, enable workaround for the LOCK errata. */
253 }
254
255 /* Check for broken P6 with bad SMP PTE implementation */
256 if (((CpuInfo.Eax & 0x0FF0) == 0x0610 && (CpuInfo.Eax & 0x000F) <= 0x9) ||
257 ((CpuInfo.Eax & 0x0FF0) == 0x0630 && (CpuInfo.Eax & 0x000F) <= 0x4))
258 {
259 /* Remove support for correct PTE support. */
260 FeatureBits &= ~KF_WORKING_PTE;
261 }
262
263 /* Check if the CPU is too old to support SYSENTER */
264 if ((Prcb->CpuType < 6) ||
265 ((Prcb->CpuType == 6) && (Prcb->CpuStep < 0x0303)))
266 {
267 /* Disable it */
268 CpuInfo.Edx &= ~0x800;
269 }
270
271 break;
272
273 /* AMD CPUs */
274 case CPU_AMD:
275
276 /* Check if this is a K5 or K6. (family 5) */
277 if ((CpuInfo.Eax & 0x0F00) == 0x0500)
278 {
279 /* Get the Model Number */
280 switch (CpuInfo.Eax & 0x00F0)
281 {
282 /* Model 1: K5 - 5k86 (initial models) */
283 case 0x0010:
284
285 /* Check if this is Step 0 or 1. They don't support PGE */
286 if ((CpuInfo.Eax & 0x000F) > 0x03) break;
287
288 /* Model 0: K5 - SSA5 */
289 case 0x0000:
290
291 /* Model 0 doesn't support PGE at all. */
292 CpuInfo.Edx &= ~0x2000;
293 break;
294
295 /* Model 8: K6-2 */
296 case 0x0080:
297
298 /* K6-2, Step 8 and over have support for MTRR. */
299 if ((CpuInfo.Eax & 0x000F) >= 0x8) FeatureBits |= KF_AMDK6MTRR;
300 break;
301
302 /* Model 9: K6-III
303 Model D: K6-2+, K6-III+ */
304 case 0x0090:
305 case 0x00D0:
306
307 FeatureBits |= KF_AMDK6MTRR;
308 break;
309 }
310 }
311 else if((CpuInfo.Eax & 0x0F00) < 0x0500)
312 {
313 /* Families below 5 don't support PGE, PSE or CMOV at all */
314 CpuInfo.Edx &= ~(0x08 | 0x2000 | 0x8000);
315
316 /* They also don't support advanced CPUID functions. */
317 ExtendedCPUID = FALSE;
318 }
319
320 break;
321
322 /* Cyrix CPUs */
323 case CPU_CYRIX:
324
325 /* Workaround the "COMA" bug on 6x family of Cyrix CPUs */
326 if (Prcb->CpuType == 6 &&
327 Prcb->CpuStep <= 1)
328 {
329 /* Get CCR1 value */
330 Ccr1 = getCx86(CX86_CCR1);
331
332 /* Enable the NO_LOCK bit */
333 Ccr1 |= 0x10;
334
335 /* Set the new CCR1 value */
336 setCx86(CX86_CCR1, Ccr1);
337 }
338
339 break;
340
341 /* Transmeta CPUs */
342 case CPU_TRANSMETA:
343
344 /* Enable CMPXCHG8B if the family (>= 5), model and stepping (>= 4.2) support it */
345 if ((CpuInfo.Eax & 0x0FFF) >= 0x0542)
346 {
347 __writemsr(0x80860004, __readmsr(0x80860004) | 0x0100);
348 FeatureBits |= KF_CMPXCHG8B;
349 }
350
351 break;
352
353 /* Centaur, IDT, Rise and VIA CPUs */
354 case CPU_CENTAUR:
355 case CPU_RISE:
356
357 /* These CPUs don't report the presence of CMPXCHG8B through CPUID.
358 However, this feature exists and operates properly without any additional steps. */
359 FeatureBits |= KF_CMPXCHG8B;
360
361 break;
362 }
363
364 /* Set the current features */
365 CpuFeatures = CpuInfo.Edx;
366
367 /* Convert all CPUID Feature bits into our format */
368 if (CpuFeatures & X86_FEATURE_VME) FeatureBits |= KF_V86_VIS | KF_CR4;
369 if (CpuFeatures & X86_FEATURE_PSE) FeatureBits |= KF_LARGE_PAGE | KF_CR4;
370 if (CpuFeatures & X86_FEATURE_TSC) FeatureBits |= KF_RDTSC;
371 if (CpuFeatures & X86_FEATURE_CX8) FeatureBits |= KF_CMPXCHG8B;
372 if (CpuFeatures & X86_FEATURE_SYSCALL) FeatureBits |= KF_FAST_SYSCALL;
373 if (CpuFeatures & X86_FEATURE_MTTR) FeatureBits |= KF_MTRR;
374 if (CpuFeatures & X86_FEATURE_PGE) FeatureBits |= KF_GLOBAL_PAGE | KF_CR4;
375 if (CpuFeatures & X86_FEATURE_CMOV) FeatureBits |= KF_CMOV;
376 if (CpuFeatures & X86_FEATURE_PAT) FeatureBits |= KF_PAT;
377 if (CpuFeatures & X86_FEATURE_DS) FeatureBits |= KF_DTS;
378 if (CpuFeatures & X86_FEATURE_MMX) FeatureBits |= KF_MMX;
379 if (CpuFeatures & X86_FEATURE_FXSR) FeatureBits |= KF_FXSR;
380 if (CpuFeatures & X86_FEATURE_SSE) FeatureBits |= KF_XMMI;
381 if (CpuFeatures & X86_FEATURE_SSE2) FeatureBits |= KF_XMMI64;
382
383 /* Check if the CPU has hyper-threading */
384 if (CpuFeatures & X86_FEATURE_HT)
385 {
386 /* Set the number of logical CPUs */
387 Prcb->LogicalProcessorsPerPhysicalProcessor = (UCHAR)(CpuInfo.Ebx >> 16);
389 {
390 /* We're on dual-core */
392 }
393 }
394 else
395 {
396 /* We only have a single CPU */
398 }
399
400 /* Check if CPUID 0x80000000 is supported */
401 if (ExtendedCPUID)
402 {
403 /* Do the call */
404 KiCpuId(&CpuInfo, 0x80000000);
405 if ((CpuInfo.Eax & 0xffffff00) == 0x80000000)
406 {
407 /* Check if CPUID 0x80000001 is supported */
408 if (CpuInfo.Eax >= 0x80000001)
409 {
410 /* Check which extended features are available. */
411 KiCpuId(&CpuInfo, 0x80000001);
412
413 /* Check if NX-bit is supported */
414 if (CpuInfo.Edx & X86_FEATURE_NX) FeatureBits |= KF_NX_BIT;
415
416 /* Now handle each features for each CPU Vendor */
417 switch (Vendor)
418 {
419 case CPU_AMD:
420 case CPU_CENTAUR:
421 if (CpuInfo.Edx & 0x80000000) FeatureBits |= KF_3DNOW;
422 break;
423 }
424 }
425 }
426 }
427
428 /* Return the Feature Bits */
429 return FeatureBits;
430}
431
432#if DBG
433CODE_SEG("INIT")
434VOID
435KiReportCpuFeatures(VOID)
436{
437 ULONG CpuFeatures = 0;
438 CPU_INFO CpuInfo;
439
440 if (KiGetCpuVendor())
441 {
442 KiCpuId(&CpuInfo, 1);
443 CpuFeatures = CpuInfo.Edx;
444 }
445
446 DPRINT1("Supported CPU features: ");
447
448#define print_kf_bit(kf_value) if (KeFeatureBits & kf_value) DbgPrint(#kf_value " ")
449 print_kf_bit(KF_V86_VIS);
450 print_kf_bit(KF_RDTSC);
451 print_kf_bit(KF_CR4);
452 print_kf_bit(KF_CMOV);
453 print_kf_bit(KF_GLOBAL_PAGE);
454 print_kf_bit(KF_LARGE_PAGE);
455 print_kf_bit(KF_MTRR);
456 print_kf_bit(KF_CMPXCHG8B);
457 print_kf_bit(KF_MMX);
458 print_kf_bit(KF_WORKING_PTE);
459 print_kf_bit(KF_PAT);
460 print_kf_bit(KF_FXSR);
461 print_kf_bit(KF_FAST_SYSCALL);
462 print_kf_bit(KF_XMMI);
463 print_kf_bit(KF_3DNOW);
464 print_kf_bit(KF_AMDK6MTRR);
465 print_kf_bit(KF_XMMI64);
466 print_kf_bit(KF_DTS);
467 print_kf_bit(KF_NX_BIT);
468 print_kf_bit(KF_NX_DISABLED);
469 print_kf_bit(KF_NX_ENABLED);
470#undef print_kf_bit
471
472#define print_cf(cpu_flag) if (CpuFeatures & cpu_flag) DbgPrint(#cpu_flag " ")
473 print_cf(X86_FEATURE_PAE);
474 print_cf(X86_FEATURE_APIC);
475 print_cf(X86_FEATURE_HT);
476#undef print_cf
477
478 DbgPrint("\n");
479}
480#endif // DBG
481
482CODE_SEG("INIT")
483VOID
484NTAPI
486{
487 PKIPCR Pcr = (PKIPCR)KeGetPcr();
488 CPU_INFO CpuInfo;
489 ULONG CacheRequests = 0, i;
490 ULONG CurrentRegister;
491 UCHAR RegisterByte, Associativity = 0;
492 ULONG Size, CacheLine = 64, CurrentSize = 0;
493 BOOLEAN FirstPass = TRUE;
494
495 /* Set default L2 size */
496 Pcr->SecondLevelCacheSize = 0;
497
498 /* Check the Vendor ID */
499 switch (KiGetCpuVendor())
500 {
501 /* Handle Intel case */
502 case CPU_INTEL:
503
504 /* Check if we support CPUID 2 */
505 KiCpuId(&CpuInfo, 0);
506 if (CpuInfo.Eax >= 2)
507 {
508 /* We need to loop for the number of times CPUID will tell us to */
509 do
510 {
511 /* Do the CPUID call */
512 KiCpuId(&CpuInfo, 2);
513
514 /* Check if it was the first call */
515 if (FirstPass)
516 {
517 /*
518 * The number of times to loop is the first byte. Read
519 * it and then destroy it so we don't get confused.
520 */
521 CacheRequests = CpuInfo.Eax & 0xFF;
522 CpuInfo.Eax &= 0xFFFFFF00;
523
524 /* Don't go over this again */
525 FirstPass = FALSE;
526 }
527
528 /* Loop all 4 registers */
529 for (i = 0; i < 4; i++)
530 {
531 /* Get the current register */
532 CurrentRegister = CpuInfo.AsUINT32[i];
533
534 /*
535 * If the upper bit is set, then this register should
536 * be skipped.
537 */
538 if (CurrentRegister & 0x80000000) continue;
539
540 /* Keep looping for every byte inside this register */
541 while (CurrentRegister)
542 {
543 /* Read a byte, skip a byte. */
544 RegisterByte = (UCHAR)(CurrentRegister & 0xFF);
545 CurrentRegister >>= 8;
546 if (!RegisterByte) continue;
547
548 Size = 0;
549 switch (RegisterByte)
550 {
551 case 0x06:
552 case 0x08:
554 break;
555 case 0x09:
557 break;
558 case 0x0a:
559 case 0x0c:
561 break;
562 case 0x0d:
563 case 0x0e:
565 break;
566 case 0x1d:
567 Size = 128 * 1024;
568 Associativity = 2;
569 break;
570 case 0x21:
571 Size = 256 * 1024;
572 Associativity = 8;
573 break;
574 case 0x24:
575 Size = 1024 * 1024;
576 Associativity = 16;
577 break;
578 case 0x2c:
579 case 0x30:
581 break;
582 case 0x41:
583 case 0x42:
584 case 0x43:
585 case 0x44:
586 case 0x45:
587 Size = (1 << (RegisterByte - 0x41)) * 128 * 1024;
588 Associativity = 4;
589 break;
590 case 0x48:
591 Size = 3 * 1024 * 1024;
592 Associativity = 12;
593 break;
594 case 0x49:
595 Size = 4 * 1024 * 1024;
596 Associativity = 16;
597 break;
598 case 0x4e:
599 Size = 6 * 1024 * 1024;
600 Associativity = 24;
601 break;
602 case 0x60:
603 case 0x66:
604 case 0x67:
605 case 0x68:
607 break;
608 case 0x78:
609 Size = 1024 * 1024;
610 Associativity = 4;
611 break;
612 case 0x79:
613 case 0x7a:
614 case 0x7b:
615 case 0x7c:
616 case 0x7d:
617 Size = (1 << (RegisterByte - 0x79)) * 128 * 1024;
618 Associativity = 8;
619 break;
620 case 0x7f:
621 Size = 512 * 1024;
622 Associativity = 2;
623 break;
624 case 0x80:
625 Size = 512 * 1024;
626 Associativity = 8;
627 break;
628 case 0x82:
629 case 0x83:
630 case 0x84:
631 case 0x85:
632 Size = (1 << (RegisterByte - 0x82)) * 256 * 1024;
633 Associativity = 8;
634 break;
635 case 0x86:
636 Size = 512 * 1024;
637 Associativity = 4;
638 break;
639 case 0x87:
640 Size = 1024 * 1024;
641 Associativity = 8;
642 break;
643 case 0xf0:
645 break;
646 case 0xf1:
648 break;
649 }
650 if (Size && (Size / Associativity) > CurrentSize)
651 {
652 /* Set the L2 Cache Size and Associativity */
653 CurrentSize = Size / Associativity;
655 Pcr->SecondLevelCacheAssociativity = Associativity;
656 }
657 }
658 }
659 } while (--CacheRequests);
660 }
661 break;
662
663 case CPU_AMD:
664
665 /* Check if we support CPUID 0x80000005 */
666 KiCpuId(&CpuInfo, 0x80000000);
667 if (CpuInfo.Eax >= 0x80000005)
668 {
669 /* Get L1 size first */
670 KiCpuId(&CpuInfo, 0x80000005);
671 KePrefetchNTAGranularity = CpuInfo.Ecx & 0xFF;
672
673 /* Check if we support CPUID 0x80000006 */
674 KiCpuId(&CpuInfo, 0x80000000);
675 if (CpuInfo.Eax >= 0x80000006)
676 {
677 /* Get 2nd level cache and tlb size */
678 KiCpuId(&CpuInfo, 0x80000006);
679
680 /* Cache line size */
681 CacheLine = CpuInfo.Ecx & 0xFF;
682
683 /* Hardcode associativity */
684 RegisterByte = (CpuInfo.Ecx >> 12) & 0xFF;
685 switch (RegisterByte)
686 {
687 case 2:
688 Associativity = 2;
689 break;
690
691 case 4:
692 Associativity = 4;
693 break;
694
695 case 6:
696 Associativity = 8;
697 break;
698
699 case 8:
700 case 15:
701 Associativity = 16;
702 break;
703
704 default:
705 Associativity = 1;
706 break;
707 }
708
709 /* Compute size */
710 Size = (CpuInfo.Ecx >> 16) << 10;
711
712 /* Hack for Model 6, Steping 300 */
713 if ((KeGetCurrentPrcb()->CpuType == 6) &&
714 (KeGetCurrentPrcb()->CpuStep == 0x300))
715 {
716 /* Stick 64K in there */
717 Size = 64 * 1024;
718 }
719
720 /* Set the L2 Cache Size and associativity */
722 Pcr->SecondLevelCacheAssociativity = Associativity;
723 }
724 }
725 break;
726
727 case CPU_CYRIX:
728 case CPU_TRANSMETA:
729 case CPU_CENTAUR:
730 case CPU_RISE:
731
732 /* FIXME */
733 break;
734 }
735
736 /* Set the cache line */
737 if (CacheLine > KeLargestCacheLine) KeLargestCacheLine = CacheLine;
738 DPRINT1("Prefetch Cache: %lu bytes\tL2 Cache: %lu bytes\tL2 Cache Line: %lu bytes\tL2 Cache Associativity: %lu\n",
743}
744
745CODE_SEG("INIT")
746VOID
747NTAPI
749{
750 ULONG Cr0;
751
752 /* Save current CR0 */
753 Cr0 = __readcr0();
754
755 /* If this is a 486, enable Write-Protection */
756 if (KeGetCurrentPrcb()->CpuType > 3) Cr0 |= CR0_WP;
757
758 /* Set new Cr0 */
759 __writecr0(Cr0);
760}
761
762CODE_SEG("INIT")
763VOID
764NTAPI
766 IN PKGDTENTRY TssEntry OPTIONAL)
767{
768 PUCHAR p;
769
770 /* Make sure the GDT Entry is valid */
771 if (TssEntry)
772 {
773 /* Set the Limit */
774 TssEntry->LimitLow = sizeof(KTSS) - 1;
775 TssEntry->HighWord.Bits.LimitHi = 0;
776 }
777
778 /* Now clear the I/O Map */
779 ASSERT(IOPM_COUNT == 1);
780 RtlFillMemory(Tss->IoMaps[0].IoMap, IOPM_FULL_SIZE, 0xFF);
781
782 /* Initialize Interrupt Direction Maps */
783 p = (PUCHAR)(Tss->IoMaps[0].DirectionMap);
785
786 /* Add DPMI support for interrupts */
787 p[0] = 4;
788 p[3] = 0x18;
789 p[4] = 0x18;
790
791 /* Initialize the default Interrupt Direction Map */
792 p = Tss->IntDirectionMap;
793 RtlZeroMemory(Tss->IntDirectionMap, IOPM_DIRECTION_MAP_SIZE);
794
795 /* Add DPMI support */
796 p[0] = 4;
797 p[3] = 0x18;
798 p[4] = 0x18;
799}
800
801VOID
802NTAPI
804{
805 /* Set an invalid map base */
806 Tss->IoMapBase = KiComputeIopmOffset(IO_ACCESS_MAP_NONE);
807
808 /* Disable traps during Task Switches */
809 Tss->Flags = 0;
810
811 /* Set LDT and Ring 0 SS */
812 Tss->LDT = 0;
813 Tss->Ss0 = KGDT_R0_DATA;
814}
815
816CODE_SEG("INIT")
817VOID
820 IN PKIDTENTRY Idt,
821 IN PKGDTENTRY Gdt)
822{
823 PKGDTENTRY TssEntry, TaskGateEntry;
824
825 /* Initialize the boot TSS. */
826 TssEntry = &Gdt[KGDT_TSS / sizeof(KGDTENTRY)];
827 TssEntry->HighWord.Bits.Type = I386_TSS;
828 TssEntry->HighWord.Bits.Pres = 1;
829 TssEntry->HighWord.Bits.Dpl = 0;
830 KiInitializeTSS2(Tss, TssEntry);
831 KiInitializeTSS(Tss);
832
833 /* Load the task register */
834 Ke386SetTr(KGDT_TSS);
835
836 /* Setup the Task Gate for Double Fault Traps */
837 TaskGateEntry = (PKGDTENTRY)&Idt[8];
838 TaskGateEntry->HighWord.Bits.Type = I386_TASK_GATE;
839 TaskGateEntry->HighWord.Bits.Pres = 1;
840 TaskGateEntry->HighWord.Bits.Dpl = 0;
841 ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_DF_TSS;
842
843 /* Initialize the TSS used for handling double faults. */
844 Tss = (PKTSS)KiDoubleFaultTSS;
845 KiInitializeTSS(Tss);
846 Tss->CR3 = __readcr3();
847 Tss->Esp0 = KiDoubleFaultStack;
848 Tss->Esp = KiDoubleFaultStack;
849 Tss->Eip = PtrToUlong(KiTrap08);
850 Tss->Cs = KGDT_R0_CODE;
851 Tss->Fs = KGDT_R0_PCR;
852 Tss->Ss = Ke386GetSs();
853 Tss->Es = KGDT_R3_DATA | RPL_MASK;
854 Tss->Ds = KGDT_R3_DATA | RPL_MASK;
855
856 /* Setup the Double Trap TSS entry in the GDT */
857 TssEntry = &Gdt[KGDT_DF_TSS / sizeof(KGDTENTRY)];
858 TssEntry->HighWord.Bits.Type = I386_TSS;
859 TssEntry->HighWord.Bits.Pres = 1;
860 TssEntry->HighWord.Bits.Dpl = 0;
861 TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF);
862 TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16);
863 TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
864 TssEntry->LimitLow = KTSS_IO_MAPS;
865
866 /* Now setup the NMI Task Gate */
867 TaskGateEntry = (PKGDTENTRY)&Idt[2];
868 TaskGateEntry->HighWord.Bits.Type = I386_TASK_GATE;
869 TaskGateEntry->HighWord.Bits.Pres = 1;
870 TaskGateEntry->HighWord.Bits.Dpl = 0;
871 ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_NMI_TSS;
872
873 /* Initialize the actual TSS */
874 Tss = (PKTSS)KiNMITSS;
875 KiInitializeTSS(Tss);
876 Tss->CR3 = __readcr3();
877 Tss->Esp0 = KiDoubleFaultStack;
878 Tss->Esp = KiDoubleFaultStack;
879 Tss->Eip = PtrToUlong(KiTrap02);
880 Tss->Cs = KGDT_R0_CODE;
881 Tss->Fs = KGDT_R0_PCR;
882 Tss->Ss = Ke386GetSs();
883 Tss->Es = KGDT_R3_DATA | RPL_MASK;
884 Tss->Ds = KGDT_R3_DATA | RPL_MASK;
885
886 /* And its associated TSS Entry */
887 TssEntry = &Gdt[KGDT_NMI_TSS / sizeof(KGDTENTRY)];
888 TssEntry->HighWord.Bits.Type = I386_TSS;
889 TssEntry->HighWord.Bits.Pres = 1;
890 TssEntry->HighWord.Bits.Dpl = 0;
891 TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF);
892 TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16);
893 TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
894 TssEntry->LimitLow = KTSS_IO_MAPS;
895}
896
897VOID
898NTAPI
900{
901
902#if !defined(_GLOBAL_PAGES_ARE_AWESOME_)
903
904 /* Flush the TLB by resetting CR3 */
906
907#else
908
909 /* Check if global pages are enabled */
911 {
912 ULONG Cr4;
913
914 /* Disable PGE (Note: may not have been enabled yet) */
915 Cr4 = __readcr4();
916 __writecr4(Cr4 & ~CR4_PGE);
917
918 /* Flush everything */
920
921 /* Re-enable PGE */
922 __writecr4(Cr4);
923 }
924 else
925 {
926 /* No global pages, resetting CR3 is enough */
928 }
929
930#endif
931
932}
933
934VOID
935NTAPI
937{
938 PKGDTENTRY TssEntry;
939
940 //
941 // Restore the CR registers
942 //
943 __writecr0(ProcessorState->SpecialRegisters.Cr0);
944 Ke386SetCr2(ProcessorState->SpecialRegisters.Cr2);
945 __writecr3(ProcessorState->SpecialRegisters.Cr3);
946 if (KeFeatureBits & KF_CR4) __writecr4(ProcessorState->SpecialRegisters.Cr4);
947
948 //
949 // Restore the DR registers
950 //
951 __writedr(0, ProcessorState->SpecialRegisters.KernelDr0);
952 __writedr(1, ProcessorState->SpecialRegisters.KernelDr1);
953 __writedr(2, ProcessorState->SpecialRegisters.KernelDr2);
954 __writedr(3, ProcessorState->SpecialRegisters.KernelDr3);
955 __writedr(6, ProcessorState->SpecialRegisters.KernelDr6);
956 __writedr(7, ProcessorState->SpecialRegisters.KernelDr7);
957
958 //
959 // Restore GDT and IDT
960 //
962 __lidt(&ProcessorState->SpecialRegisters.Idtr.Limit);
963
964 //
965 // Clear the busy flag so we don't crash if we reload the same selector
966 //
967 TssEntry = (PKGDTENTRY)(ProcessorState->SpecialRegisters.Gdtr.Base +
968 ProcessorState->SpecialRegisters.Tr);
969 TssEntry->HighWord.Bytes.Flags1 &= ~0x2;
970
971 //
972 // Restore TSS and LDT
973 //
974 Ke386SetTr(ProcessorState->SpecialRegisters.Tr);
975 Ke386SetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr);
976}
977
978VOID
979NTAPI
981{
982 /* Save the CR registers */
983 ProcessorState->SpecialRegisters.Cr0 = __readcr0();
984 ProcessorState->SpecialRegisters.Cr2 = __readcr2();
985 ProcessorState->SpecialRegisters.Cr3 = __readcr3();
986 ProcessorState->SpecialRegisters.Cr4 = (KeFeatureBits & KF_CR4) ?
987 __readcr4() : 0;
988
989 /* Save the DR registers */
990 ProcessorState->SpecialRegisters.KernelDr0 = __readdr(0);
991 ProcessorState->SpecialRegisters.KernelDr1 = __readdr(1);
992 ProcessorState->SpecialRegisters.KernelDr2 = __readdr(2);
993 ProcessorState->SpecialRegisters.KernelDr3 = __readdr(3);
994 ProcessorState->SpecialRegisters.KernelDr6 = __readdr(6);
995 ProcessorState->SpecialRegisters.KernelDr7 = __readdr(7);
996 __writedr(7, 0);
997
998 /* Save GDT, IDT, LDT and TSS */
999 Ke386GetGlobalDescriptorTable(&ProcessorState->SpecialRegisters.Gdtr.Limit);
1000 __sidt(&ProcessorState->SpecialRegisters.Idtr.Limit);
1001 ProcessorState->SpecialRegisters.Tr = Ke386GetTr();
1002 Ke386GetLocalDescriptorTable(&ProcessorState->SpecialRegisters.Ldtr);
1003}
1004
1005CODE_SEG("INIT")
1006VOID
1007NTAPI
1009{
1010 /* Set the Machine Type we got from NTLDR */
1012}
1013
1014CODE_SEG("INIT")
1016NTAPI
1018{
1019 /* Set CS and ESP */
1020 __writemsr(0x174, KGDT_R0_CODE);
1021 __writemsr(0x175, (ULONG_PTR)KeGetCurrentPrcb()->DpcStack);
1022
1023 /* Set LSTAR */
1025 return 0;
1026}
1027
1028CODE_SEG("INIT")
1029VOID
1030NTAPI
1032{
1033 /* Check if the CPU Supports fast system call */
1035 {
1036 /* Check if it has been disabled */
1038 {
1039 /* Disable fast system call */
1040 KeFeatureBits &= ~KF_FAST_SYSCALL;
1042 DPRINT1("Support for SYSENTER disabled.\n");
1043 }
1044 else
1045 {
1046 /* Do an IPI to enable it */
1048
1049 /* It's enabled, so use the proper exit stub */
1051 DPRINT("Support for SYSENTER detected.\n");
1052 }
1053 }
1054 else
1055 {
1056 /* Use the IRET handler */
1058 DPRINT1("No support for SYSENTER detected.\n");
1059 }
1060}
1061
1062CODE_SEG("INIT")
1064NTAPI
1066{
1067 /* Enable DE */
1069 return 0;
1070}
1071
1072CODE_SEG("INIT")
1074NTAPI
1076{
1077 /* Enable FXSR */
1079 return 0;
1080}
1081
1082CODE_SEG("INIT")
1084NTAPI
1086{
1087 PKIDTENTRY IdtEntry;
1088
1089 /* Get the IDT Entry for Interrupt 0x13 */
1090 IdtEntry = &((PKIPCR)KeGetPcr())->IDT[0x13];
1091
1092 /* Set it up */
1093 IdtEntry->Selector = KGDT_R0_CODE;
1094 IdtEntry->Offset = ((ULONG_PTR)KiTrap13 & 0xFFFF);
1095 IdtEntry->ExtendedOffset = ((ULONG_PTR)KiTrap13 >> 16) & 0xFFFF;
1096 ((PKIDT_ACCESS)&IdtEntry->Access)->Dpl = 0;
1097 ((PKIDT_ACCESS)&IdtEntry->Access)->Present = 1;
1098 ((PKIDT_ACCESS)&IdtEntry->Access)->SegmentType = I386_INTERRUPT_GATE;
1099
1100 /* Enable XMMI exceptions */
1102 return 0;
1103}
1104
1105CODE_SEG("INIT")
1106VOID
1107NTAPI
1109{
1110 KDESCRIPTOR IdtDescriptor = {0, 0, 0};
1111 PKIDTENTRY NewIdt, NewIdt2;
1112 PMMPTE PointerPte;
1113
1114 /* Allocate memory for a new IDT */
1115 NewIdt = ExAllocatePool(NonPagedPool, 2 * PAGE_SIZE);
1116
1117 /* Put everything after the first 7 entries on a new page */
1118 NewIdt2 = (PVOID)((ULONG_PTR)NewIdt + PAGE_SIZE - (7 * sizeof(KIDTENTRY)));
1119
1120 /* Disable interrupts */
1121 _disable();
1122
1123 /* Get the current IDT and copy it */
1124 __sidt(&IdtDescriptor.Limit);
1125 RtlCopyMemory(NewIdt2,
1126 (PVOID)IdtDescriptor.Base,
1127 IdtDescriptor.Limit + 1);
1128 IdtDescriptor.Base = (ULONG)NewIdt2;
1129
1130 /* Set the new IDT */
1131 __lidt(&IdtDescriptor.Limit);
1132 ((PKIPCR)KeGetPcr())->IDT = NewIdt2;
1133
1134 /* Restore interrupts */
1135 _enable();
1136
1137 /* Set the first 7 entries as read-only to produce a fault */
1138 PointerPte = MiAddressToPte(NewIdt);
1139 ASSERT(PointerPte->u.Hard.Write == 1);
1140 PointerPte->u.Hard.Write = 0;
1141 KeInvalidateTlbEntry(NewIdt);
1142}
1143
1144BOOLEAN
1145NTAPI
1147{
1148 /* Only supported on Pentium Pro and higher */
1149 if (KeI386CpuType < 6) return FALSE;
1150
1151 /* Invalidate all caches */
1152 __wbinvd();
1153 return TRUE;
1154}
1155
1156VOID
1157NTAPI
1159 IN PKEXCEPTION_FRAME ExceptionFrame)
1160{
1161 PKPRCB Prcb = KeGetCurrentPrcb();
1162
1163 //
1164 // Save full context
1165 //
1169
1170 //
1171 // Save control registers
1172 //
1174}
1175
1176CODE_SEG("INIT")
1177BOOLEAN
1178NTAPI
1180{
1181 static double Value1 = 4195835.0, Value2 = 3145727.0;
1182 INT ErrataPresent;
1183 ULONG Cr0;
1184
1185 /* Interrupts have to be disabled here. */
1187
1188 /* Read CR0 and remove FPU flags */
1189 Cr0 = __readcr0();
1190 __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
1191
1192 /* Initialize FPU state */
1193 Ke386FnInit();
1194
1195 /* Multiply the magic values and divide, we should get the result back */
1196#ifdef __GNUC__
1197 __asm__ __volatile__
1198 (
1199 "fldl %1\n\t"
1200 "fdivl %2\n\t"
1201 "fmull %2\n\t"
1202 "fldl %1\n\t"
1203 "fsubp\n\t"
1204 "fistpl %0\n\t"
1205 : "=m" (ErrataPresent)
1206 : "m" (Value1),
1207 "m" (Value2)
1208 );
1209#else
1210 __asm
1211 {
1212 fld Value1
1213 fdiv Value2
1214 fmul Value2
1215 fld Value1
1216 fsubp st(1), st(0)
1217 fistp ErrataPresent
1218 };
1219#endif
1220
1221 /* Restore CR0 */
1222 __writecr0(Cr0);
1223
1224 /* Return if there's an errata */
1225 return ErrataPresent != 0;
1226}
1227
1228VOID
1229NTAPI
1231{
1232 ULONG EFlags, Cr0;
1233 PKTHREAD Thread, NpxThread;
1234 PFX_SAVE_AREA FxSaveArea;
1235
1236 /* Save volatiles and disable interrupts */
1237 EFlags = __readeflags();
1238 _disable();
1239
1240 /* Save the PCR and get the current thread */
1242
1243 /* Check if we're already loaded */
1244 if (Thread->NpxState != NPX_STATE_LOADED)
1245 {
1246 /* If there's nothing to load, quit */
1247 if (!SaveArea)
1248 {
1249 /* Restore interrupt state and return */
1250 __writeeflags(EFlags);
1251 return;
1252 }
1253
1254 /* Need FXSR support for this */
1256
1257 /* Check for sane CR0 */
1258 Cr0 = __readcr0();
1259 if (Cr0 & (CR0_MP | CR0_TS | CR0_EM))
1260 {
1261 /* Mask out FPU flags */
1262 __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
1263 }
1264
1265 /* Get the NPX thread and check its FPU state */
1266 NpxThread = KeGetCurrentPrcb()->NpxThread;
1267 if ((NpxThread) && (NpxThread->NpxState == NPX_STATE_LOADED))
1268 {
1269 /* Get the FX frame and store the state there */
1270 FxSaveArea = KiGetThreadNpxArea(NpxThread);
1271 Ke386FxSave(FxSaveArea);
1272
1273 /* NPX thread has lost its state */
1274 NpxThread->NpxState = NPX_STATE_NOT_LOADED;
1275 }
1276
1277 /* Now load NPX state from the NPX area */
1278 FxSaveArea = KiGetThreadNpxArea(Thread);
1279 Ke386FxStore(FxSaveArea);
1280 }
1281 else
1282 {
1283 /* Check for sane CR0 */
1284 Cr0 = __readcr0();
1285 if (Cr0 & (CR0_MP | CR0_TS | CR0_EM))
1286 {
1287 /* Mask out FPU flags */
1288 __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
1289 }
1290
1291 /* Get FX frame */
1292 FxSaveArea = KiGetThreadNpxArea(Thread);
1293 Thread->NpxState = NPX_STATE_NOT_LOADED;
1294
1295 /* Save state if supported by CPU */
1296 if (KeI386FxsrPresent) Ke386FxSave(FxSaveArea);
1297 }
1298
1299 /* Now save the FN state wherever it was requested */
1300 if (SaveArea) Ke386FnSave(SaveArea);
1301
1302 /* Clear NPX thread */
1303 KeGetCurrentPrcb()->NpxThread = NULL;
1304
1305 /* Add the CR0 from the NPX frame */
1306 Cr0 |= NPX_STATE_NOT_LOADED;
1307 Cr0 |= FxSaveArea->Cr0NpxState;
1308 __writecr0(Cr0);
1309
1310 /* Restore interrupt state */
1311 __writeeflags(EFlags);
1312}
1313
1314/* PUBLIC FUNCTIONS **********************************************************/
1315
1316/*
1317 * @implemented
1318 */
1319VOID
1320NTAPI
1322{
1323 PFX_SAVE_AREA NpxArea;
1324
1325 /* Get the FPU area */
1327
1328 /* Set CR0_TS */
1329 NpxArea->Cr0NpxState = CR0_TS;
1331}
1332
1358#if defined(__clang__)
1359__attribute__((__target__("sse")))
1360#endif
1362NTAPI
1365{
1367 PFX_SAVE_AREA FxSaveAreaFrame;
1368 PKPRCB CurrentPrcb;
1369
1370 /* Sanity checks */
1371 ASSERT(Save);
1374
1375 /* Initialize the floating point context */
1377 sizeof(FLOATING_SAVE_CONTEXT),
1379 if (!FsContext)
1380 {
1381 /* Bail out if we failed */
1383 }
1384
1385 /*
1386 * Allocate some memory pool for the buffer. The size
1387 * of this allocated buffer is the FX area plus the
1388 * alignment requirement needed for FXSAVE as a 16-byte
1389 * aligned pointer is compulsory in order to save the
1390 * FPU state.
1391 */
1393 sizeof(FX_SAVE_AREA) + FXSAVE_ALIGN,
1395 if (!FsContext->Buffer)
1396 {
1397 /* Bail out if we failed */
1400 }
1401
1402 /*
1403 * Now cache the allocated buffer into the save area
1404 * and align the said area to a 16-byte boundary. Why
1405 * do we have to do this is because of ExAllocate function.
1406 * We gave the necessary alignment requirement in the pool
1407 * allocation size although the function will always return
1408 * a 8-byte aligned pointer. Aligning the given pointer directly
1409 * can cause issues when freeing it from memory afterwards. With
1410 * that said, we have to cache the buffer to the area so that we
1411 * do not touch or mess the allocated buffer any further.
1412 */
1413 FsContext->PfxSaveArea = ALIGN_UP_POINTER_BY(FsContext->Buffer, 16);
1414
1415 /* Disable interrupts and get the current processor control region */
1416 _disable();
1417 CurrentPrcb = KeGetCurrentPrcb();
1418
1419 /* Store the current thread to context */
1420 FsContext->CurrentThread = KeGetCurrentThread();
1421
1422 /*
1423 * Save the previous NPX thread state registers (aka Numeric
1424 * Processor eXtension) into the current context so that
1425 * we are informing the scheduler the current FPU state
1426 * belongs to this thread.
1427 */
1428 if (FsContext->CurrentThread != CurrentPrcb->NpxThread)
1429 {
1430 if ((CurrentPrcb->NpxThread != NULL) &&
1431 (CurrentPrcb->NpxThread->NpxState == NPX_STATE_LOADED))
1432 {
1433 /* Get the FX frame */
1434 FxSaveAreaFrame = KiGetThreadNpxArea(CurrentPrcb->NpxThread);
1435
1436 /* Save the FPU state */
1437 Ke386SaveFpuState(FxSaveAreaFrame);
1438
1439 /* NPX thread has lost its state */
1440 CurrentPrcb->NpxThread->NpxState = NPX_STATE_NOT_LOADED;
1441 FxSaveAreaFrame->NpxSavedCpu = 0;
1442 }
1443
1444 /* The new NPX thread is the current thread */
1445 CurrentPrcb->NpxThread = FsContext->CurrentThread;
1446 }
1447
1448 /* Perform the save */
1449 Ke386SaveFpuState(FsContext->PfxSaveArea);
1450
1451 /* Store the NPX IRQL */
1452 FsContext->OldNpxIrql = FsContext->CurrentThread->Header.NpxIrql;
1453
1454 /* Set the current IRQL to NPX */
1455 FsContext->CurrentThread->Header.NpxIrql = KeGetCurrentIrql();
1456
1457 /* Initialize the FPU */
1458 Ke386FnInit();
1459
1460 /* Enable interrupts back */
1461 _enable();
1462
1463 /* Give the saved FPU context to the caller */
1464 *((PVOID *) Save) = FsContext;
1465 return STATUS_SUCCESS;
1466}
1467
1484#if defined(__clang__)
1485__attribute__((__target__("sse")))
1486#endif
1488NTAPI
1491{
1493
1494 /* Sanity checks */
1495 ASSERT(Save);
1498
1499 /* Cache the saved FS context */
1500 FsContext = *((PVOID *) Save);
1501
1502 /*
1503 * We have to restore the regular saved FPU
1504 * state. For this we must first do some
1505 * validation checks so that we are sure
1506 * ourselves the state context is saved
1507 * properly. Check if we are in the same
1508 * calling thread.
1509 */
1510 if (FsContext->CurrentThread != KeGetCurrentThread())
1511 {
1512 /*
1513 * This isn't the thread that saved the
1514 * FPU state context, crash the system!
1515 */
1516 KeBugCheckEx(INVALID_FLOATING_POINT_STATE,
1517 0x2,
1518 (ULONG_PTR)FsContext->CurrentThread,
1520 0);
1521 }
1522
1523 /* Are we under the same NPX interrupt level? */
1524 if (FsContext->CurrentThread->Header.NpxIrql != KeGetCurrentIrql())
1525 {
1526 /* The interrupt level has changed, crash the system! */
1527 KeBugCheckEx(INVALID_FLOATING_POINT_STATE,
1528 0x1,
1529 (ULONG_PTR)FsContext->CurrentThread->Header.NpxIrql,
1531 0);
1532 }
1533
1534 /* Disable interrupts */
1535 _disable();
1536
1537 /*
1538 * The saved FPU state context is valid,
1539 * it's time to restore the state. First,
1540 * clear FPU exceptions now.
1541 */
1542 Ke386ClearFpExceptions();
1543
1544 /* Restore the state */
1545 Ke386RestoreFpuState(FsContext->PfxSaveArea);
1546
1547 /* Give the saved NPX IRQL back to the NPX thread */
1548 FsContext->CurrentThread->Header.NpxIrql = FsContext->OldNpxIrql;
1549
1550 /* Enable interrupts back */
1551 _enable();
1552
1553 /* We're done, free the allocated area and context */
1556
1557 return STATUS_SUCCESS;
1558}
1559
1560/*
1561 * @implemented
1562 */
1563ULONG
1564NTAPI
1566{
1567 /* Return the global variable */
1568 return KeLargestCacheLine;
1569}
1570
1571VOID
1572NTAPI
1574 IN PVOID Ignored1,
1575 IN PVOID Ignored2,
1576 IN PVOID Ignored3)
1577{
1578 /* Signal this packet as done */
1579 KiIpiSignalPacketDone(PacketContext);
1580
1581 /* Flush the TB for the Current CPU */
1583}
1584
1585/*
1586 * @implemented
1587 */
1588VOID
1589NTAPI
1591 IN BOOLEAN AllProcessors)
1592{
1593 KIRQL OldIrql;
1594#ifdef CONFIG_SMP
1595 KAFFINITY TargetAffinity;
1596 PKPRCB Prcb = KeGetCurrentPrcb();
1597#endif
1598
1599 /* Raise the IRQL for the TB Flush */
1601
1602#ifdef CONFIG_SMP
1603 /* FIXME: Use KiTbFlushTimeStamp to synchronize TB flush */
1604
1605 /* Get the current processor affinity, and exclude ourselves */
1606 TargetAffinity = KeActiveProcessors;
1607 TargetAffinity &= ~Prcb->SetMember;
1608
1609 /* Make sure this is MP */
1610 if (TargetAffinity)
1611 {
1612 /* Send an IPI TB flush to the other processors */
1613 KiIpiSendPacket(TargetAffinity,
1615 NULL,
1616 0,
1617 NULL);
1618 }
1619#endif
1620
1621 /* Flush the TB for the Current CPU, and update the flush stamp */
1623
1624#ifdef CONFIG_SMP
1625 /* If this is MP, wait for the other processors to finish */
1626 if (TargetAffinity)
1627 {
1628 /* Sanity check */
1629 ASSERT(Prcb == KeGetCurrentPrcb());
1630
1631 /* FIXME: TODO */
1632 ASSERTMSG("Not yet implemented\n", FALSE);
1633 }
1634#endif
1635
1636 /* Update the flush stamp and return to original IRQL */
1639}
1640
1641/*
1642 * @implemented
1643 */
1644VOID
1645NTAPI
1647{
1648 /* Save the coherency globally */
1649 KiDmaIoCoherency = Coherency;
1650}
1651
1652/*
1653 * @implemented
1654 */
1656NTAPI
1658{
1659 PAGED_CODE();
1660
1661 /* Simply return the number of active processors */
1662 return KeActiveProcessors;
1663}
1664
1665/*
1666 * @implemented
1667 */
1668VOID
1669__cdecl
1671{
1672 /* Capture the context */
1673 RtlCaptureContext(&State->ContextFrame);
1674
1675 /* Capture the control state */
1677}
#define PAGED_CODE()
#define CODE_SEG(...)
unsigned char BOOLEAN
#define EFLAGS_INTERRUPT_MASK
Definition: SystemCall.c:11
Type
Definition: Type.h:7
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define __cdecl
Definition: accygwin.h:79
@ Invalid
Definition: asmpp.cpp:30
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define __attribute__(x)
Definition: wpp_private.h:207
ULONG_PTR KAFFINITY
Definition: compat.h:85
#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 RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:599
#define InterlockedExchangeAdd
Definition: interlocked.h:181
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
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:1818
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1669
__INTRIN_INLINE void __lidt(void *Source)
Definition: intrin_x86.h:2018
__INTRIN_INLINE unsigned int __readdr(unsigned int reg)
Definition: intrin_x86.h:1902
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1825
__INTRIN_INLINE unsigned long __readcr0(void)
Definition: intrin_x86.h:1804
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1674
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1794
__INTRIN_INLINE unsigned long __readcr2(void)
Definition: intrin_x86.h:1811
__INTRIN_INLINE void __writecr0(unsigned int Data)
Definition: intrin_x86.h:1789
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2023
__INTRIN_INLINE void __writecr4(unsigned int Data)
Definition: intrin_x86.h:1799
__INTRIN_INLINE void __writedr(unsigned reg, unsigned int value)
Definition: intrin_x86.h:1935
#define KeSaveFloatingPointState(x)
Definition: kmixer.h:32
#define KeRestoreFloatingPointState(x)
Definition: kmixer.h:33
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
if(dx< 0)
Definition: linetemp.h:194
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define min(a, b)
Definition: monoChain.cc:55
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define CR0_WP
Definition: asm.h:251
#define CR0_MP
Definition: asm.h:246
#define CR0_EM
Definition: asm.h:247
#define CR0_TS
Definition: asm.h:248
#define KIDTENTRY
Definition: ketypes.h:564
#define KiComputeIopmOffset(MapNumber)
Definition: ketypes.h:346
#define CR4_PGE
Definition: ketypes.h:152
#define KF_MTRR
Definition: ketypes.h:37
#define KTSS
Definition: ketypes.h:1006
#define IO_ACCESS_MAP_NONE
Definition: ketypes.h:344
#define CR4_XMMEXCPT
Definition: ketypes.h:154
#define PKIDTENTRY
Definition: ketypes.h:565
#define KF_DTS
Definition: ketypes.h:40
#define I386_TASK_GATE
Definition: ketypes.h:120
#define I386_TSS
Definition: ketypes.h:121
#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:1161
#define KF_CMOV
Definition: ketypes.h:34
#define KF_AMDK6MTRR
Definition: ketypes.h:46
#define PKTSS
Definition: ketypes.h:1007
#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:523
#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:148
#define KF_FXSR
Definition: ketypes.h:42
@ CPU_INTEL
Definition: ketypes.h:106
@ CPU_UNKNOWN
Definition: ketypes.h:104
@ CPU_AMD
Definition: ketypes.h:105
#define KF_LARGE_PAGE
Definition: ketypes.h:36
#define KF_XMMI
Definition: ketypes.h:44
#define CR4_FXSR
Definition: ketypes.h:153
#define KGDTENTRY
Definition: ketypes.h:522
#define KF_MMX
Definition: ketypes.h:39
#define KF_PAT
Definition: ketypes.h:41
#define RPL_MASK
Definition: ketypes.h:130
#define I386_INTERRUPT_GATE
Definition: ketypes.h:124
struct _KIDT_ACCESS * PKIDT_ACCESS
#define KF_GLOBAL_PAGE
Definition: ketypes.h:35
#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:229
#define KGDT_R3_DATA
Definition: ketypes.h:126
#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:231
#define KGDT_DF_TSS
Definition: ketypes.h:132
#define KGDT_R0_CODE
Definition: ketypes.h:123
#define IOPM_COUNT
Definition: ketypes.h:227
#define KGDT_R0_DATA
Definition: ketypes.h:124
NTSYSAPI VOID NTAPI RtlCaptureContext(_Out_ PCONTEXT ContextRecord)
#define CONTEXT_DEBUG_REGISTERS
Definition: nt_native.h:1373
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define FASTCALL
Definition: nt_native.h:50
#define CONTEXT_FULL
Definition: nt_native.h:1375
#define X86_FEATURE_TSC
Definition: ke.h:34
#define X86_FEATURE_HT
Definition: ke.h:47
#define X86_FEATURE_SSE2
Definition: ke.h:46
#define X86_FEATURE_SSE
Definition: ke.h:45
#define X86_FEATURE_PGE
Definition: ke.h:39
#define X86_FEATURE_DS
Definition: ke.h:42
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:264
#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_PAT
Definition: ke.h:41
#define X86_FEATURE_MTTR
Definition: ke.h:38
#define X86_FEATURE_CMOV
Definition: ke.h:40
#define X86_FEATURE_CX8
Definition: ke.h:36
#define X86_FEATURE_SYSCALL
Definition: ke.h:37
#define X86_FEATURE_NX
Definition: ke.h:63
#define X86_FEATURE_FXSR
Definition: ke.h:44
VOID __cdecl KiTrap13(VOID)
VOID __cdecl KiTrap02(VOID)
VOID __cdecl KiTrap08(VOID)
#define X86_FEATURE_APIC
Definition: ke.h:33
VOID __cdecl KiFastCallEntry(VOID)
FORCEINLINE PFX_SAVE_AREA KiGetThreadNpxArea(IN PKTHREAD Thread)
Definition: ke.h:712
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: context.c:169
KAFFINITY KeActiveProcessors
Definition: krnlinit.c:23
ULONG KeFeatureBits
Definition: krnlinit.c:22
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 KeGetRecommendedSharedDataAlignment(VOID)
Definition: cpu.c:710
VOID NTAPI KiRestoreProcessorControlState(PKPROCESSOR_STATE ProcessorState)
Definition: cpu.c:534
ULONG KeI386NpxPresent
Definition: cpu.c:27
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:526
VOID NTAPI KiSetProcessorType(VOID)
Definition: cpu.c:99
ULONG KeI386MachineType
Definition: cpu.c:26
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:652
ULONG KeLargestCacheLine
Definition: cpu.c:28
VOID __cdecl KeSaveStateForHibernate(IN PKPROCESSOR_STATE State)
Definition: cpu.c:721
BOOLEAN KiSMTProcessorsPresent
Definition: cpu.c:30
ULONG64 NTAPI KiGetFeatureBits(VOID)
Evaluates the KeFeatureFlag bits for the current CPU.
Definition: cpu.c:165
BOOLEAN NTAPI KeInvalidateAllCaches(VOID)
Definition: cpu.c:698
ULONG NTAPI KiGetCpuVendor(VOID)
Definition: cpu.c:59
volatile LONG KiTbFlushTimeStamp
Definition: cpu.c:33
VOID NTAPI KiSaveProcessorState(_In_ PKTRAP_FRAME TrapFrame, _In_ PKEXCEPTION_FRAME ExceptionFrame)
Definition: cpu.c:617
VOID NTAPI KeSetDmaIoCoherency(IN ULONG Coherency)
Definition: cpu.c:735
ULONG KeI386CpuType
Definition: cpu.c:24
VOID NTAPI KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
Definition: cpu.c:576
static const CHAR CmpIntelID[]
Definition: cpu.c:36
static const CHAR CmpAmdID[]
Definition: cpu.c:37
static const CHAR CmpCentaurID[]
Definition: cpu.c:38
ULONG KiDmaIoCoherency
Definition: cpu.c:29
VOID NTAPI KiGetCacheInformation(VOID)
Definition: cpu.c:418
union _CPU_SIGNATURE CPU_SIGNATURE
KAFFINITY NTAPI KeQueryActiveProcessors(VOID)
Definition: cpu.c:672
ULONG KeI386CpuStep
Definition: cpu.c:25
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:1008
VOID FASTCALL Ki386InitializeTss(IN PKTSS Tss, IN PKIDTENTRY Idt, IN PKGDTENTRY Gdt)
Definition: cpu.c:819
static const CHAR CmpTransmetaID[]
Definition: cpu.c:61
ULONG KeI386XMMIPresent
Definition: cpu.c:32
#define CX86_CCR1
Definition: cpu.c:86
ULONG KiFastSystemCallDisable
Definition: cpu.c:28
#define FXSAVE_ALIGN
Definition: cpu.c:81
VOID NTAPI KiInitializeTSS(IN PKTSS Tss)
Definition: cpu.c:803
VOID NTAPI KiInitializeTSS2(IN PKTSS Tss, IN PKGDTENTRY TssEntry OPTIONAL)
Definition: cpu.c:765
ULONG KePrefetchNTAGranularity
Definition: cpu.c:41
VOID NTAPI KiCoprocessorError(VOID)
Definition: cpu.c:1321
VOID NTAPI KiI386PentiumLockErrataFixup(VOID)
Definition: cpu.c:1108
static __inline void setCx86(UCHAR reg, UCHAR data)
Definition: cpu.c:99
BOOLEAN NTAPI KiIsNpxErrataPresent(VOID)
Definition: cpu.c:1179
ULONG_PTR NTAPI Ki386EnableXMMIExceptions(IN ULONG_PTR Context)
Definition: cpu.c:1085
ULONG_PTR NTAPI KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context)
Definition: cpu.c:1017
ULONG_PTR NTAPI Ki386EnableFxsr(IN ULONG_PTR Context)
Definition: cpu.c:1075
VOID NTAPI KiFlushNPXState(IN PFLOATING_SAVE_AREA SaveArea)
Definition: cpu.c:1230
VOID NTAPI KiRestoreFastSyscallReturnState(VOID)
Definition: cpu.c:1031
static __inline UCHAR getCx86(UCHAR reg)
Definition: cpu.c:91
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:748
static const CHAR CmpRiseID[]
Definition: cpu.c:63
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:1573
ULONG KeI386FxsrPresent
Definition: cpu.c:33
static const CHAR CmpCyrixID[]
Definition: cpu.c:60
UCHAR KiSystemCallExitAdjusted
Definition: cpu.c:49
UCHAR KiSystemCallExitAdjust
Definition: cpu.c:46
ULONG_PTR NTAPI Ki386EnableDE(IN ULONG_PTR Context)
Definition: cpu.c:1065
UCHAR KiNMITSS[KTSS_IO_MAPS]
Definition: cpu.c:23
#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
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tsub $32, %rsp\n" "\t.seh_stackalloc 32\n" "\t.seh_endprologue\n" "\tmov %rdx, %rbp\n" "\tjmp *%rax\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $32, %rsp\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
ULONG ContextFlags
Definition: nt_native.h:1426
ULONG Base
Definition: ketypes.h:450
USHORT Limit
Definition: ketypes.h:449
ULONG NpxSavedCpu
Definition: ketypes.h:504
ULONG Cr0NpxState
Definition: ketypes.h:505
ULONG MachineType
Definition: arc.h:454
PVOID Base
Definition: ketypes.h:571
USHORT Limit
Definition: ketypes.h:570
union _KGDTENTRY::@2447 HighWord
struct _KGDTENTRY::@2447::@2449 Bits
USHORT BaseLow
Definition: ketypes.h:390
USHORT LimitLow
Definition: ketypes.h:389
struct _KGDTENTRY::@2447::@2448 Bytes
USHORT Offset
Definition: ketypes.h:440
USHORT Selector
Definition: ketypes.h:441
USHORT Access
Definition: ketypes.h:442
USHORT ExtendedOffset
Definition: ketypes.h:443
ULONG SecondLevelCacheSize
Definition: ketypes.h:968
UCHAR SecondLevelCacheAssociativity
Definition: ketypes.h:959
UCHAR VendorString[13]
Definition: ketypes.h:881
CHAR CpuType
Definition: ketypes.h:664
USHORT CpuStep
Definition: ketypes.h:669
UCHAR LogicalProcessorsPerPhysicalProcessor
Definition: ketypes.h:759
ULONG InitialApicId
Definition: ketypes.h:701
LARGE_INTEGER UpdateSignature
Definition: ketypes.h:884
KPROCESSOR_STATE ProcessorState
Definition: ketypes.h:663
struct _KTHREAD * NpxThread
Definition: ketypes.h:567
KSPECIAL_REGISTERS SpecialRegisters
Definition: ketypes.h:615
CONTEXT ContextFrame
Definition: ketypes.h:616
ULONG64 KernelDr0
Definition: ketypes.h:585
ULONG64 KernelDr7
Definition: ketypes.h:590
KDESCRIPTOR Gdtr
Definition: ketypes.h:591
ULONG64 KernelDr2
Definition: ketypes.h:587
KDESCRIPTOR Idtr
Definition: ketypes.h:592
ULONG64 KernelDr1
Definition: ketypes.h:586
ULONG64 KernelDr3
Definition: ketypes.h:588
ULONG64 KernelDr6
Definition: ketypes.h:589
ULONG64 NpxState
Definition: ketypes.h:2068
Definition: ketypes.h:844
union _LOADER_PARAMETER_BLOCK::@3379 u
I386_LOADER_BLOCK I386
Definition: arc.h:562
ULONG64 Write
Definition: mmtypes.h:170
union _MMPTE::@2330 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#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
#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:382
ULONG Eax
Definition: ketypes.h:381
UINT32 AsUINT32[4]
Definition: ketypes.h:378
ULONG Ecx
Definition: ketypes.h:383
ULONG Edx
Definition: ketypes.h:384
ULONG Unused
Definition: cpu.c:47
ULONG ExtendedFamily
Definition: cpu.c:49
ULONG Model
Definition: cpu.c:45
ULONG Unused2
Definition: cpu.c:50
ULONG Family
Definition: cpu.c:46
ULONG AsULONG
Definition: cpu.c:52
ULONG Step
Definition: cpu.c:44
ULONG ExtendedModel
Definition: cpu.c:48
LONGLONG QuadPart
Definition: typedefs.h:114
static int Save(const char **args)
Definition: vfdcmd.c:1851
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175