TianoCore EDK2 master
Loading...
Searching...
No Matches
BaseXApicLib.c
Go to the documentation of this file.
1
14#include <Register/Amd/Cpuid.h>
15#include <Register/Intel/Msr.h>
17
18#include <Library/BaseLib.h>
19#include <Library/DebugLib.h>
21#include <Library/IoLib.h>
22#include <Library/TimerLib.h>
23#include <Library/PcdLib.h>
24#include <Library/CpuLib.h>
25
26//
27// Library internal functions
28//
29
37BOOLEAN
39 VOID
40 )
41{
42 UINT32 RegEax;
43 UINTN FamilyId;
44
45 AsmCpuid (1, &RegEax, NULL, NULL, NULL);
46 FamilyId = BitFieldRead32 (RegEax, 8, 11);
47 if ((FamilyId == 0x04) || (FamilyId == 0x05)) {
48 //
49 // CPUs with a FamilyId of 0x04 or 0x05 do not support the
50 // Local APIC Base Address MSR
51 //
52 return FALSE;
53 }
54
55 return TRUE;
56}
57
65EFIAPI
67 VOID
68 )
69{
71
73 //
74 // If CPU does not support Local APIC Base Address MSR, then retrieve
75 // Local APIC Base Address from PCD
76 //
77 return PcdGet32 (PcdCpuLocalApicBaseAddress);
78 }
79
81
82 return (UINTN)(LShiftU64 ((UINT64)ApicBaseMsr.Bits.ApicBaseHi, 32)) +
83 (((UINTN)ApicBaseMsr.Bits.ApicBase) << 12);
84}
85
94VOID
95EFIAPI
97 IN UINTN BaseAddress
98 )
99{
100 MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
101
102 ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0);
103
105 //
106 // Ignore set request if the CPU does not support APIC Base Address MSR
107 //
108 return;
109 }
110
111 ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
112
113 ApicBaseMsr.Bits.ApicBase = (UINT32)(BaseAddress >> 12);
114 ApicBaseMsr.Bits.ApicBaseHi = (UINT32)(RShiftU64 ((UINT64)BaseAddress, 32));
115
117}
118
132UINT32
133EFIAPI
135 IN UINTN MmioOffset
136 )
137{
138 ASSERT ((MmioOffset & 0xf) == 0);
139 ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC);
140
141 return MmioRead32 (GetLocalApicBaseAddress () + MmioOffset);
142}
143
158VOID
159EFIAPI
161 IN UINTN MmioOffset,
162 IN UINT32 Value
163 )
164{
165 ASSERT ((MmioOffset & 0xf) == 0);
166 ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC);
167
168 MmioWrite32 (GetLocalApicBaseAddress () + MmioOffset, Value);
169}
170
179VOID
181 IN UINT32 IcrLow,
182 IN UINT32 ApicId
183 )
184{
185 LOCAL_APIC_ICR_LOW IcrLowReg;
186 UINT32 IcrHigh;
187 BOOLEAN InterruptState;
188
189 ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC);
190 ASSERT (ApicId <= 0xff);
191
192 InterruptState = SaveAndDisableInterrupts ();
193
194 //
195 // Save existing contents of ICR high 32 bits
196 //
197 IcrHigh = ReadLocalApicReg (XAPIC_ICR_HIGH_OFFSET);
198
199 //
200 // Wait for DeliveryStatus clear in case a previous IPI
201 // is still being sent
202 //
203 do {
204 IcrLowReg.Uint32 = ReadLocalApicReg (XAPIC_ICR_LOW_OFFSET);
205 } while (IcrLowReg.Bits.DeliveryStatus != 0);
206
207 //
208 // For xAPIC, the act of writing to the low doubleword of the ICR causes the IPI to be sent.
209 //
210 WriteLocalApicReg (XAPIC_ICR_HIGH_OFFSET, ApicId << 24);
211 WriteLocalApicReg (XAPIC_ICR_LOW_OFFSET, IcrLow);
212
213 //
214 // Wait for DeliveryStatus clear again
215 //
216 do {
217 IcrLowReg.Uint32 = ReadLocalApicReg (XAPIC_ICR_LOW_OFFSET);
218 } while (IcrLowReg.Bits.DeliveryStatus != 0);
219
220 //
221 // And restore old contents of ICR high
222 //
223 WriteLocalApicReg (XAPIC_ICR_HIGH_OFFSET, IcrHigh);
224
225 SetInterruptState (InterruptState);
226}
227
228//
229// Library API implementation functions
230//
231
240UINTN
241EFIAPI
243 VOID
244 )
245{
247 {
248 MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
249
250 //
251 // Check to see if the CPU supports the APIC Base Address MSR
252 //
254 ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
255 //
256 // Local APIC should have been enabled
257 //
258 ASSERT (ApicBaseMsr.Bits.EN != 0);
259 ASSERT (ApicBaseMsr.Bits.EXTD == 0);
260 }
261 }
264}
265
277VOID
278EFIAPI
280 IN UINTN ApicMode
281 )
282{
283 ASSERT (ApicMode == LOCAL_APIC_MODE_XAPIC);
284 ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC);
285}
286
296UINT32
297EFIAPI
299 VOID
300 )
301{
302 UINT32 ApicId;
303 UINT32 MaxCpuIdIndex;
304 UINT32 RegEbx;
305
306 ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC);
307
308 //
309 // Get the max index of basic CPUID
310 //
311 AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL);
312
313 //
314 // If CPUID Leaf B is supported,
315 // And CPUID.0BH:EBX[15:0] reports a non-zero value,
316 // Then the initial 32-bit APIC ID = CPUID.0BH:EDX
317 // Else the initial 8-bit APIC ID = CPUID.1:EBX[31:24]
318 //
319 if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) {
320 AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 0, NULL, &RegEbx, NULL, &ApicId);
321 if ((RegEbx & (BIT16 - 1)) != 0) {
322 return ApicId;
323 }
324 }
325
327 return RegEbx >> 24;
328}
329
335UINT32
336EFIAPI
338 VOID
339 )
340{
341 UINT32 ApicId;
342
343 ASSERT (GetApicMode () == LOCAL_APIC_MODE_XAPIC);
344
345 if ((ApicId = GetInitialApicId ()) < 0x100) {
346 //
347 // If the initial local APIC ID is less 0x100, read APIC ID from
348 // XAPIC_ID_OFFSET, otherwise return the initial local APIC ID.
349 //
350 ApicId = ReadLocalApicReg (XAPIC_ID_OFFSET);
351 ApicId >>= 24;
352 }
353
354 return ApicId;
355}
356
362UINT32
363EFIAPI
365 VOID
366 )
367{
368 return ReadLocalApicReg (XAPIC_VERSION_OFFSET);
369}
370
379VOID
380EFIAPI
382 IN UINT32 ApicId,
383 IN UINT8 Vector
384 )
385{
386 LOCAL_APIC_ICR_LOW IcrLow;
387
388 IcrLow.Uint32 = 0;
389 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_FIXED;
390 IcrLow.Bits.Level = 1;
391 IcrLow.Bits.Vector = Vector;
392 SendIpi (IcrLow.Uint32, ApicId);
393}
394
402VOID
403EFIAPI
405 IN UINT8 Vector
406 )
407{
408 LOCAL_APIC_ICR_LOW IcrLow;
409
410 IcrLow.Uint32 = 0;
411 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_FIXED;
412 IcrLow.Bits.Level = 1;
413 IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF;
414 IcrLow.Bits.Vector = Vector;
415 SendIpi (IcrLow.Uint32, 0);
416}
417
425VOID
426EFIAPI
428 IN UINT32 ApicId
429 )
430{
431 LOCAL_APIC_ICR_LOW IcrLow;
432
433 IcrLow.Uint32 = 0;
434 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_SMI;
435 IcrLow.Bits.Level = 1;
436 SendIpi (IcrLow.Uint32, ApicId);
437}
438
444VOID
445EFIAPI
447 VOID
448 )
449{
450 LOCAL_APIC_ICR_LOW IcrLow;
451
452 IcrLow.Uint32 = 0;
453 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_SMI;
454 IcrLow.Bits.Level = 1;
455 IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF;
456 SendIpi (IcrLow.Uint32, 0);
457}
458
466VOID
467EFIAPI
469 IN UINT32 ApicId
470 )
471{
472 LOCAL_APIC_ICR_LOW IcrLow;
473
474 IcrLow.Uint32 = 0;
475 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_INIT;
476 IcrLow.Bits.Level = 1;
477 SendIpi (IcrLow.Uint32, ApicId);
478}
479
485VOID
486EFIAPI
488 VOID
489 )
490{
491 LOCAL_APIC_ICR_LOW IcrLow;
492
493 IcrLow.Uint32 = 0;
494 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_INIT;
495 IcrLow.Bits.Level = 1;
496 IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF;
497 SendIpi (IcrLow.Uint32, 0);
498}
499
508VOID
509EFIAPI
511 IN UINT32 StartupRoutine
512 )
513{
514 LOCAL_APIC_ICR_LOW IcrLow;
515
516 ASSERT (StartupRoutine < 0x100000);
517 ASSERT ((StartupRoutine & 0xfff) == 0);
518
519 IcrLow.Uint32 = 0;
520 IcrLow.Bits.Vector = (StartupRoutine >> 12);
521 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP;
522 IcrLow.Bits.Level = 1;
523 IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF;
524 SendIpi (IcrLow.Uint32, 0);
525}
526
539VOID
540EFIAPI
542 IN UINT32 ApicId,
543 IN UINT32 StartupRoutine
544 )
545{
546 LOCAL_APIC_ICR_LOW IcrLow;
547
548 ASSERT (StartupRoutine < 0x100000);
549 ASSERT ((StartupRoutine & 0xfff) == 0);
550
551 SendInitIpi (ApicId);
552 MicroSecondDelay (PcdGet32 (PcdCpuInitIpiDelayInMicroSeconds));
553 IcrLow.Uint32 = 0;
554 IcrLow.Bits.Vector = (StartupRoutine >> 12);
555 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP;
556 IcrLow.Bits.Level = 1;
557 SendIpi (IcrLow.Uint32, ApicId);
559 MicroSecondDelay (200);
560 SendIpi (IcrLow.Uint32, ApicId);
561 }
562}
563
575VOID
576EFIAPI
578 IN UINT32 StartupRoutine
579 )
580{
582 MicroSecondDelay (PcdGet32 (PcdCpuInitIpiDelayInMicroSeconds));
583 SendStartupIpiAllExcludingSelf (StartupRoutine);
585 MicroSecondDelay (200);
586 SendStartupIpiAllExcludingSelf (StartupRoutine);
587 }
588}
589
598VOID
599EFIAPI
601 IN BOOLEAN Enable
602 )
603{
604 LOCAL_APIC_SVR Svr;
605
606 //
607 // Set local APIC software-enabled bit.
608 //
609 Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET);
610 if (Enable) {
611 if (Svr.Bits.SoftwareEnable == 0) {
612 Svr.Bits.SoftwareEnable = 1;
613 WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);
614 }
615 } else {
616 if (Svr.Bits.SoftwareEnable == 1) {
617 Svr.Bits.SoftwareEnable = 0;
618 WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);
619 }
620 }
621}
622
631VOID
632EFIAPI
634 VOID
635 )
636{
637 LOCAL_APIC_SVR Svr;
639
640 //
641 // Enable the APIC via SVR and set the spurious interrupt to use Int 00F.
642 //
643 Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET);
644 Svr.Bits.SpuriousVector = 0xf;
645 Svr.Bits.SoftwareEnable = 1;
646 WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);
647
648 //
649 // Program the LINT0 vector entry as ExtInt. Not masked, edge, active high.
650 //
651 Lint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT0_OFFSET);
652 Lint.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_EXTINT;
653 Lint.Bits.InputPinPolarity = 0;
654 Lint.Bits.TriggerMode = 0;
655 Lint.Bits.Mask = 0;
656 WriteLocalApicReg (XAPIC_LVT_LINT0_OFFSET, Lint.Uint32);
657
658 //
659 // Program the LINT0 vector entry as NMI. Not masked, edge, active high.
660 //
661 Lint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT1_OFFSET);
662 Lint.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_NMI;
663 Lint.Bits.InputPinPolarity = 0;
664 Lint.Bits.TriggerMode = 0;
665 Lint.Bits.Mask = 0;
666 WriteLocalApicReg (XAPIC_LVT_LINT1_OFFSET, Lint.Uint32);
667}
668
674VOID
675EFIAPI
677 VOID
678 )
679{
680 LOCAL_APIC_LVT_LINT LvtLint;
681
682 LvtLint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT0_OFFSET);
683 LvtLint.Bits.Mask = 1;
684 WriteLocalApicReg (XAPIC_LVT_LINT0_OFFSET, LvtLint.Uint32);
685
686 LvtLint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT1_OFFSET);
687 LvtLint.Bits.Mask = 1;
688 WriteLocalApicReg (XAPIC_LVT_LINT1_OFFSET, LvtLint.Uint32);
689}
690
696UINT32
697EFIAPI
699 VOID
700 )
701{
702 return ReadLocalApicReg (XAPIC_TIMER_INIT_COUNT_OFFSET);
703}
704
710UINT32
711EFIAPI
713 VOID
714 )
715{
716 return ReadLocalApicReg (XAPIC_TIMER_CURRENT_COUNT_OFFSET);
717}
718
730VOID
731EFIAPI
733 IN UINTN DivideValue,
734 IN UINT32 InitCount,
735 IN BOOLEAN PeriodicMode,
736 IN UINT8 Vector
737 )
738{
739 LOCAL_APIC_DCR Dcr;
740 LOCAL_APIC_LVT_TIMER LvtTimer;
741 UINT32 Divisor;
742
743 //
744 // Ensure local APIC is in software-enabled state.
745 //
747
748 //
749 // Program init-count register.
750 //
751 WriteLocalApicReg (XAPIC_TIMER_INIT_COUNT_OFFSET, InitCount);
752
753 if (DivideValue != 0) {
754 ASSERT (DivideValue <= 128);
755 ASSERT (DivideValue == GetPowerOfTwo32 ((UINT32)DivideValue));
756 Divisor = (UINT32)((HighBitSet32 ((UINT32)DivideValue) - 1) & 0x7);
757
758 Dcr.Uint32 = ReadLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET);
759 Dcr.Bits.DivideValue1 = (Divisor & 0x3);
760 Dcr.Bits.DivideValue2 = (Divisor >> 2);
761 WriteLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET, Dcr.Uint32);
762 }
763
764 //
765 // Enable APIC timer interrupt with specified timer mode.
766 //
767 LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET);
768 if (PeriodicMode) {
769 LvtTimer.Bits.TimerMode = 1;
770 } else {
771 LvtTimer.Bits.TimerMode = 0;
772 }
773
774 LvtTimer.Bits.Mask = 0;
775 LvtTimer.Bits.Vector = Vector;
776 WriteLocalApicReg (XAPIC_LVT_TIMER_OFFSET, LvtTimer.Uint32);
777}
778
788VOID
789EFIAPI
791 OUT UINTN *DivideValue OPTIONAL,
792 OUT BOOLEAN *PeriodicMode OPTIONAL,
793 OUT UINT8 *Vector OPTIONAL
794 )
795{
796 UINT32 Divisor;
797 LOCAL_APIC_DCR Dcr;
798 LOCAL_APIC_LVT_TIMER LvtTimer;
799
800 //
801 // Check the APIC Software Enable/Disable bit (bit 8) in Spurious-Interrupt
802 // Vector Register.
803 // This bit will be 1, if local APIC is software enabled.
804 //
805 ASSERT ((ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET) & BIT8) != 0);
806
807 if (DivideValue != NULL) {
808 Dcr.Uint32 = ReadLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET);
809 Divisor = Dcr.Bits.DivideValue1 | (Dcr.Bits.DivideValue2 << 2);
810 Divisor = (Divisor + 1) & 0x7;
811 *DivideValue = ((UINTN)1) << Divisor;
812 }
813
814 if ((PeriodicMode != NULL) || (Vector != NULL)) {
815 LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET);
816 if (PeriodicMode != NULL) {
817 if (LvtTimer.Bits.TimerMode == 1) {
818 *PeriodicMode = TRUE;
819 } else {
820 *PeriodicMode = FALSE;
821 }
822 }
823
824 if (Vector != NULL) {
825 *Vector = (UINT8)LvtTimer.Bits.Vector;
826 }
827 }
828}
829
833VOID
834EFIAPI
836 VOID
837 )
838{
839 LOCAL_APIC_LVT_TIMER LvtTimer;
840
841 LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET);
842 LvtTimer.Bits.Mask = 0;
843 WriteLocalApicReg (XAPIC_LVT_TIMER_OFFSET, LvtTimer.Uint32);
844}
845
849VOID
850EFIAPI
852 VOID
853 )
854{
855 LOCAL_APIC_LVT_TIMER LvtTimer;
856
857 LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET);
858 LvtTimer.Bits.Mask = 1;
859 WriteLocalApicReg (XAPIC_LVT_TIMER_OFFSET, LvtTimer.Uint32);
860}
861
868BOOLEAN
869EFIAPI
871 VOID
872 )
873{
874 LOCAL_APIC_LVT_TIMER LvtTimer;
875
876 LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET);
877 return (BOOLEAN)(LvtTimer.Bits.Mask == 0);
878}
879
883VOID
884EFIAPI
886 VOID
887 )
888{
889 WriteLocalApicReg (XAPIC_EOI_OFFSET, 0);
890}
891
898UINT32
899EFIAPI
901 VOID
902 )
903{
904 LOCAL_APIC_MSI_ADDRESS MsiAddress;
905
906 //
907 // Return address for an MSI interrupt to be delivered only to the APIC ID
908 // of the currently executing processor.
909 //
910 MsiAddress.Uint32 = 0;
911 MsiAddress.Bits.BaseAddress = 0xFEE;
912 MsiAddress.Bits.DestinationId = GetApicId ();
913 return MsiAddress.Uint32;
914}
915
944UINT64
945EFIAPI
947 IN UINT8 Vector,
948 IN UINTN DeliveryMode,
949 IN BOOLEAN LevelTriggered,
950 IN BOOLEAN AssertionLevel
951 )
952{
953 LOCAL_APIC_MSI_DATA MsiData;
954
955 ASSERT (Vector >= 0x10 && Vector <= 0xFE);
956 ASSERT (DeliveryMode < 8 && DeliveryMode != 6 && DeliveryMode != 3);
957
958 MsiData.Uint64 = 0;
959 MsiData.Bits.Vector = Vector;
960 MsiData.Bits.DeliveryMode = (UINT32)DeliveryMode;
961 if (LevelTriggered) {
962 MsiData.Bits.TriggerMode = 1;
963 if (AssertionLevel) {
964 MsiData.Bits.Level = 1;
965 }
966 }
967
968 return MsiData.Uint64;
969}
970
983VOID
984EFIAPI
986 IN UINT32 InitialApicId,
987 OUT UINT32 *Package OPTIONAL,
988 OUT UINT32 *Core OPTIONAL,
989 OUT UINT32 *Thread OPTIONAL
990 )
991{
992 BOOLEAN TopologyLeafSupported;
993 CPUID_VERSION_INFO_EBX VersionInfoEbx;
994 CPUID_VERSION_INFO_EDX VersionInfoEdx;
995 CPUID_CACHE_PARAMS_EAX CacheParamsEax;
996 CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax;
997 CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx;
998 CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx;
999 CPUID_AMD_EXTENDED_CPU_SIG_ECX AmdExtendedCpuSigEcx;
1000 CPUID_AMD_PROCESSOR_TOPOLOGY_EBX AmdProcessorTopologyEbx;
1001 CPUID_AMD_VIR_PHY_ADDRESS_SIZE_ECX AmdVirPhyAddressSizeEcx;
1002 UINT32 MaxStandardCpuIdIndex;
1003 UINT32 MaxExtendedCpuIdIndex;
1004 UINT32 SubIndex;
1005 UINTN LevelType;
1006 UINT32 MaxLogicProcessorsPerPackage;
1007 UINT32 MaxCoresPerPackage;
1008 UINTN ThreadBits;
1009 UINTN CoreBits;
1010
1011 //
1012 // Check if the processor is capable of supporting more than one logical processor.
1013 //
1014 AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);
1015 if (VersionInfoEdx.Bits.HTT == 0) {
1016 if (Thread != NULL) {
1017 *Thread = 0;
1018 }
1019
1020 if (Core != NULL) {
1021 *Core = 0;
1022 }
1023
1024 if (Package != NULL) {
1025 *Package = 0;
1026 }
1027
1028 return;
1029 }
1030
1031 //
1032 // Assume three-level mapping of APIC ID: Package|Core|Thread.
1033 //
1034 ThreadBits = 0;
1035 CoreBits = 0;
1036
1037 //
1038 // Get max index of CPUID
1039 //
1040 AsmCpuid (CPUID_SIGNATURE, &MaxStandardCpuIdIndex, NULL, NULL, NULL);
1041 AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedCpuIdIndex, NULL, NULL, NULL);
1042
1043 //
1044 // If the extended topology enumeration leaf is available, it
1045 // is the preferred mechanism for enumerating topology.
1046 //
1047 TopologyLeafSupported = FALSE;
1048 if (MaxStandardCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) {
1049 AsmCpuidEx (
1051 0,
1052 &ExtendedTopologyEax.Uint32,
1053 &ExtendedTopologyEbx.Uint32,
1054 &ExtendedTopologyEcx.Uint32,
1055 NULL
1056 );
1057 //
1058 // Quoting Intel SDM:
1059 // Software must detect the presence of CPUID leaf 0BH by
1060 // verifying (a) the highest leaf index supported by CPUID is >=
1061 // 0BH, and (b) CPUID.0BH:EBX[15:0] reports a non-zero value.
1062 //
1063 if (ExtendedTopologyEbx.Bits.LogicalProcessors != 0) {
1064 TopologyLeafSupported = TRUE;
1065
1066 //
1067 // Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract
1068 // the SMT sub-field of x2APIC ID.
1069 //
1070 LevelType = ExtendedTopologyEcx.Bits.LevelType;
1071 ASSERT (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT);
1072 ThreadBits = ExtendedTopologyEax.Bits.ApicIdShift;
1073
1074 //
1075 // Software must not assume any "level type" encoding
1076 // value to be related to any sub-leaf index, except sub-leaf 0.
1077 //
1078 SubIndex = 1;
1079 do {
1080 AsmCpuidEx (
1082 SubIndex,
1083 &ExtendedTopologyEax.Uint32,
1084 NULL,
1085 &ExtendedTopologyEcx.Uint32,
1086 NULL
1087 );
1088 LevelType = ExtendedTopologyEcx.Bits.LevelType;
1089 if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) {
1090 CoreBits = ExtendedTopologyEax.Bits.ApicIdShift - ThreadBits;
1091 break;
1092 }
1093
1094 SubIndex++;
1095 } while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID);
1096 }
1097 }
1098
1099 if (!TopologyLeafSupported) {
1100 //
1101 // Get logical processor count
1102 //
1103 AsmCpuid (CPUID_VERSION_INFO, NULL, &VersionInfoEbx.Uint32, NULL, NULL);
1104 MaxLogicProcessorsPerPackage = VersionInfoEbx.Bits.MaximumAddressableIdsForLogicalProcessors;
1105
1106 //
1107 // Assume single-core processor
1108 //
1109 MaxCoresPerPackage = 1;
1110
1111 //
1112 // Check for topology extensions on AMD processor
1113 //
1115 if (MaxExtendedCpuIdIndex >= CPUID_AMD_PROCESSOR_TOPOLOGY) {
1116 AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, &AmdExtendedCpuSigEcx.Uint32, NULL);
1117 if (AmdExtendedCpuSigEcx.Bits.TopologyExtensions != 0) {
1118 //
1119 // Account for max possible thread count to decode ApicId
1120 //
1121 AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, NULL, NULL, &AmdVirPhyAddressSizeEcx.Uint32, NULL);
1122 MaxLogicProcessorsPerPackage = 1 << AmdVirPhyAddressSizeEcx.Bits.ApicIdCoreIdSize;
1123
1124 //
1125 // Get cores per processor package
1126 //
1127 AsmCpuid (CPUID_AMD_PROCESSOR_TOPOLOGY, NULL, &AmdProcessorTopologyEbx.Uint32, NULL, NULL);
1128 MaxCoresPerPackage = MaxLogicProcessorsPerPackage / (AmdProcessorTopologyEbx.Bits.ThreadsPerCore + 1);
1129 }
1130 }
1131 } else {
1132 //
1133 // Extract core count based on CACHE information
1134 //
1135 if (MaxStandardCpuIdIndex >= CPUID_CACHE_PARAMS) {
1136 AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NULL, NULL);
1137 if (CacheParamsEax.Uint32 != 0) {
1138 MaxCoresPerPackage = CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 1;
1139 }
1140 }
1141 }
1142
1143 ThreadBits = (UINTN)(HighBitSet32 (MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1);
1144 CoreBits = (UINTN)(HighBitSet32 (MaxCoresPerPackage - 1) + 1);
1145 }
1146
1147 if (Thread != NULL) {
1148 *Thread = InitialApicId & ((1 << ThreadBits) - 1);
1149 }
1150
1151 if (Core != NULL) {
1152 *Core = (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1);
1153 }
1154
1155 if (Package != NULL) {
1156 *Package = (InitialApicId >> (ThreadBits + CoreBits));
1157 }
1158}
1159
1176VOID
1178 IN UINT32 InitialApicId,
1179 OUT UINT32 *Package OPTIONAL,
1180 OUT UINT32 *Die OPTIONAL,
1181 OUT UINT32 *Tile OPTIONAL,
1182 OUT UINT32 *Module OPTIONAL,
1183 OUT UINT32 *Core OPTIONAL,
1184 OUT UINT32 *Thread OPTIONAL
1185 )
1186{
1187 CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax;
1188 CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx;
1189 CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx;
1190 UINT32 MaxExtendedCpuIdIndex;
1191 UINT32 TopologyLevel;
1192 UINT32 PreviousLevel;
1193 UINT32 Data;
1194
1195 if (Die != NULL) {
1196 *Die = 0;
1197 }
1198
1199 if (Tile != NULL) {
1200 *Tile = 0;
1201 }
1202
1203 if (Module != NULL) {
1204 *Module = 0;
1205 }
1206
1207 PreviousLevel = 0;
1208 TopologyLevel = 0;
1209
1211 AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedCpuIdIndex, NULL, NULL, NULL);
1212 if (MaxExtendedCpuIdIndex >= AMD_CPUID_EXTENDED_TOPOLOGY) {
1213 do {
1214 AsmCpuidEx (
1216 TopologyLevel,
1217 &ExtendedTopologyEax.Uint32,
1218 &ExtendedTopologyEbx.Uint32,
1219 &ExtendedTopologyEcx.Uint32,
1220 NULL
1221 );
1222
1226 break;
1227 }
1228
1229 Data = InitialApicId >> PreviousLevel;
1230 Data &= (1 << (ExtendedTopologyEax.Bits.ApicIdShift - PreviousLevel)) - 1;
1231
1232 switch (ExtendedTopologyEcx.Bits.LevelType) {
1233 case CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT:
1234 if (Thread != NULL) {
1235 *Thread = Data;
1236 }
1237
1238 break;
1239 case CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE:
1240 if (Core != NULL) {
1241 *Core = Data;
1242 }
1243
1244 break;
1246 if (Module != NULL) {
1247 *Module = Data;
1248 }
1249
1250 break;
1251 case CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_TILE:
1252 if (Die != NULL) {
1253 *Die = Data;
1254 }
1255
1256 break;
1257 default:
1258 break;
1259 }
1260
1261 TopologyLevel++;
1262 PreviousLevel = ExtendedTopologyEax.Bits.ApicIdShift;
1263 } while (ExtendedTopologyEbx.Bits.LogicalProcessors != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID);
1264
1265 if (Package != NULL) {
1266 *Package = InitialApicId >> PreviousLevel;
1267 }
1268 }
1269
1272 if (TopologyLevel == 0) {
1273 GetProcessorLocationByApicId (InitialApicId, Package, Core, Thread);
1274 }
1275
1276 return;
1277}
1278
1295VOID
1296EFIAPI
1298 IN UINT32 InitialApicId,
1299 OUT UINT32 *Package OPTIONAL,
1300 OUT UINT32 *Die OPTIONAL,
1301 OUT UINT32 *Tile OPTIONAL,
1302 OUT UINT32 *Module OPTIONAL,
1303 OUT UINT32 *Core OPTIONAL,
1304 OUT UINT32 *Thread OPTIONAL
1305 )
1306{
1307 CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax;
1308 CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx;
1309 CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx;
1310 UINT32 MaxStandardCpuIdIndex;
1311 UINT32 Index;
1312 UINTN LevelType;
1313 UINT32 Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2];
1314 UINT32 *Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2];
1315
1317 AmdGetProcessorLocation2ByApicId (InitialApicId, Package, Die, Tile, Module, Core, Thread);
1318 return;
1319 }
1320
1321 for (LevelType = 0; LevelType < ARRAY_SIZE (Bits); LevelType++) {
1322 Bits[LevelType] = 0;
1323 }
1324
1325 //
1326 // Quoting Intel SDM:
1327 // Software must detect the presence of CPUID leaf 1FH by verifying
1328 // (a) the highest leaf index supported by CPUID is >= 1FH, and (b)
1329 // CPUID.1FH:EBX[15:0] reports a non-zero value.
1330 //
1331 AsmCpuid (CPUID_SIGNATURE, &MaxStandardCpuIdIndex, NULL, NULL, NULL);
1332 if (MaxStandardCpuIdIndex < CPUID_V2_EXTENDED_TOPOLOGY) {
1333 ExtendedTopologyEbx.Bits.LogicalProcessors = 0;
1334 } else {
1335 AsmCpuidEx (CPUID_V2_EXTENDED_TOPOLOGY, 0, NULL, &ExtendedTopologyEbx.Uint32, NULL, NULL);
1336 }
1337
1338 if (ExtendedTopologyEbx.Bits.LogicalProcessors == 0) {
1339 if (Die != NULL) {
1340 *Die = 0;
1341 }
1342
1343 if (Tile != NULL) {
1344 *Tile = 0;
1345 }
1346
1347 if (Module != NULL) {
1348 *Module = 0;
1349 }
1350
1351 GetProcessorLocationByApicId (InitialApicId, Package, Core, Thread);
1352 return;
1353 }
1354
1355 //
1356 // If the V2 extended topology enumeration leaf is available, it
1357 // is the preferred mechanism for enumerating topology.
1358 //
1359 for (Index = 0; ; Index++) {
1360 AsmCpuidEx (
1362 Index,
1363 &ExtendedTopologyEax.Uint32,
1364 NULL,
1365 &ExtendedTopologyEcx.Uint32,
1366 NULL
1367 );
1368
1369 LevelType = ExtendedTopologyEcx.Bits.LevelType;
1370
1371 //
1372 // first level reported should be SMT.
1373 //
1374 ASSERT ((Index != 0) || (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT));
1376 break;
1377 }
1378
1379 ASSERT (LevelType < ARRAY_SIZE (Bits));
1380 Bits[LevelType] = ExtendedTopologyEax.Bits.ApicIdShift;
1381 }
1382
1383 for (LevelType = CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE; LevelType < ARRAY_SIZE (Bits); LevelType++) {
1384 //
1385 // If there are more levels between level-1 (low-level) and level-2 (high-level), the unknown levels will be ignored
1386 // and treated as an extension of the last known level (i.e., level-1 in this case).
1387 //
1388 if (Bits[LevelType] == 0) {
1389 Bits[LevelType] = Bits[LevelType - 1];
1390 }
1391 }
1392
1393 Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] = Package;
1394 Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE] = Die;
1395 Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_TILE] = Tile;
1397 Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE] = Core;
1398 Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT] = Thread;
1399
1400 Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] = 32;
1401
1402 for ( LevelType = CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT
1403 ; LevelType <= CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1
1404 ; LevelType++
1405 )
1406 {
1407 if (Location[LevelType] != NULL) {
1408 //
1409 // Bits[i] holds the number of bits to shift right on x2APIC ID to get a unique
1410 // topology ID of the next level type.
1411 //
1412 *Location[LevelType] = InitialApicId >> Bits[LevelType - 1];
1413
1414 //
1415 // Bits[i] - Bits[i-1] holds the number of bits for the next ONE level type.
1416 //
1417 *Location[LevelType] &= (1 << (Bits[LevelType] - Bits[LevelType - 1])) - 1;
1418 }
1419 }
1420}
UINT64 UINTN
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
BOOLEAN EFIAPI SetInterruptState(IN BOOLEAN InterruptState)
Definition: Cpu.c:48
BOOLEAN EFIAPI SaveAndDisableInterrupts(VOID)
Definition: Cpu.c:21
UINT32 EFIAPI GetPowerOfTwo32(IN UINT32 Operand)
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
INTN EFIAPI HighBitSet32(IN UINT32 Operand)
Definition: HighBitSet32.c:27
UINT32 EFIAPI BitFieldRead32(IN UINT32 Operand, IN UINTN StartBit, IN UINTN EndBit)
Definition: BitField.c:527
VOID EFIAPI SendInitSipiSipiAllExcludingSelf(IN UINT32 StartupRoutine)
Definition: BaseXApicLib.c:577
VOID EFIAPI SendFixedIpiAllExcludingSelf(IN UINT8 Vector)
Definition: BaseXApicLib.c:404
VOID EFIAPI InitializeLocalApicSoftwareEnable(IN BOOLEAN Enable)
Definition: BaseXApicLib.c:600
UINT32 EFIAPI ReadLocalApicReg(IN UINTN MmioOffset)
Definition: BaseXApicLib.c:134
VOID EFIAPI SendSmiIpi(IN UINT32 ApicId)
Definition: BaseXApicLib.c:427
UINT32 EFIAPI GetApicVersion(VOID)
Definition: BaseXApicLib.c:364
BOOLEAN EFIAPI GetApicTimerInterruptState(VOID)
Definition: BaseXApicLib.c:870
VOID EFIAPI SetLocalApicBaseAddress(IN UINTN BaseAddress)
Definition: BaseXApicLib.c:96
UINT32 EFIAPI GetApicId(VOID)
Definition: BaseXApicLib.c:337
VOID EFIAPI DisableLvtInterrupts(VOID)
Definition: BaseXApicLib.c:676
VOID EFIAPI GetApicTimerState(OUT UINTN *DivideValue OPTIONAL, OUT BOOLEAN *PeriodicMode OPTIONAL, OUT UINT8 *Vector OPTIONAL)
Definition: BaseXApicLib.c:790
VOID EFIAPI SendInitIpi(IN UINT32 ApicId)
Definition: BaseXApicLib.c:468
UINT32 EFIAPI GetInitialApicId(VOID)
Definition: BaseXApicLib.c:298
VOID EFIAPI SendInitIpiAllExcludingSelf(VOID)
Definition: BaseXApicLib.c:487
BOOLEAN LocalApicBaseAddressMsrSupported(VOID)
Definition: BaseXApicLib.c:38
VOID EFIAPI SendSmiIpiAllExcludingSelf(VOID)
Definition: BaseXApicLib.c:446
UINTN EFIAPI GetApicMode(VOID)
Definition: BaseXApicLib.c:242
VOID EFIAPI ProgramVirtualWireMode(VOID)
Definition: BaseXApicLib.c:633
VOID EFIAPI EnableApicTimerInterrupt(VOID)
Definition: BaseXApicLib.c:835
UINT32 EFIAPI GetApicMsiAddress(VOID)
Definition: BaseXApicLib.c:900
VOID AmdGetProcessorLocation2ByApicId(IN UINT32 InitialApicId, OUT UINT32 *Package OPTIONAL, OUT UINT32 *Die OPTIONAL, OUT UINT32 *Tile OPTIONAL, OUT UINT32 *Module OPTIONAL, OUT UINT32 *Core OPTIONAL, OUT UINT32 *Thread OPTIONAL)
VOID SendIpi(IN UINT32 IcrLow, IN UINT32 ApicId)
Definition: BaseXApicLib.c:180
VOID EFIAPI SendStartupIpiAllExcludingSelf(IN UINT32 StartupRoutine)
Definition: BaseXApicLib.c:510
VOID EFIAPI SendFixedIpi(IN UINT32 ApicId, IN UINT8 Vector)
Definition: BaseXApicLib.c:381
VOID EFIAPI WriteLocalApicReg(IN UINTN MmioOffset, IN UINT32 Value)
Definition: BaseXApicLib.c:160
VOID EFIAPI SetApicMode(IN UINTN ApicMode)
Definition: BaseXApicLib.c:279
UINT32 EFIAPI GetApicTimerInitCount(VOID)
Definition: BaseXApicLib.c:698
UINTN EFIAPI GetLocalApicBaseAddress(VOID)
Definition: BaseXApicLib.c:66
UINT64 EFIAPI GetApicMsiValue(IN UINT8 Vector, IN UINTN DeliveryMode, IN BOOLEAN LevelTriggered, IN BOOLEAN AssertionLevel)
Definition: BaseXApicLib.c:946
VOID EFIAPI GetProcessorLocation2ByApicId(IN UINT32 InitialApicId, OUT UINT32 *Package OPTIONAL, OUT UINT32 *Die OPTIONAL, OUT UINT32 *Tile OPTIONAL, OUT UINT32 *Module OPTIONAL, OUT UINT32 *Core OPTIONAL, OUT UINT32 *Thread OPTIONAL)
VOID EFIAPI GetProcessorLocationByApicId(IN UINT32 InitialApicId, OUT UINT32 *Package OPTIONAL, OUT UINT32 *Core OPTIONAL, OUT UINT32 *Thread OPTIONAL)
Definition: BaseXApicLib.c:985
VOID EFIAPI InitializeApicTimer(IN UINTN DivideValue, IN UINT32 InitCount, IN BOOLEAN PeriodicMode, IN UINT8 Vector)
Definition: BaseXApicLib.c:732
VOID EFIAPI SendApicEoi(VOID)
Definition: BaseXApicLib.c:885
UINT32 EFIAPI GetApicTimerCurrentCount(VOID)
Definition: BaseXApicLib.c:712
VOID EFIAPI SendInitSipiSipi(IN UINT32 ApicId, IN UINT32 StartupRoutine)
Definition: BaseXApicLib.c:541
VOID EFIAPI DisableApicTimerInterrupt(VOID)
Definition: BaseXApicLib.c:851
UINT32 EFIAPI AsmCpuidEx(IN UINT32 Index, IN UINT32 SubIndex, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
Definition: CpuIdEx.c:43
UINT64 EFIAPI AsmReadMsr64(IN UINT32 Index)
Definition: GccInlinePriv.c:60
UINT64 EFIAPI AsmWriteMsr64(IN UINT32 Index, IN UINT64 Value)
UINT32 EFIAPI MmioRead32(IN UINTN Address)
Definition: IoLib.c:262
UINT32 EFIAPI MmioWrite32(IN UINTN Address, IN UINT32 Value)
Definition: IoLib.c:309
#define LOCAL_APIC_MODE_XAPIC
xAPIC mode.
Definition: LocalApicLib.h:15
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
#define AMD_CPUID_EXTENDED_TOPOLOGY
Definition: Cpuid.h:64
#define CPUID_AMD_PROCESSOR_TOPOLOGY
Definition: Cpuid.h:540
#define MSR_IA32_APIC_BASE
#define CPUID_SIGNATURE
Definition: Cpuid.h:45
#define CPUID_CACHE_PARAMS
Definition: Cpuid.h:802
#define CPUID_VERSION_INFO
Definition: Cpuid.h:81
#define CPUID_EXTENDED_TOPOLOGY
Definition: Cpuid.h:1815
#define CPUID_V2_EXTENDED_TOPOLOGY
Definition: Cpuid.h:3685
#define CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_MODULE
Definition: Cpuid.h:3692
#define CPUID_EXTENDED_CPU_SIG
Definition: Cpuid.h:3768
#define CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID
Definition: Cpuid.h:1902
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
Definition: CpuId.c:36
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
BOOLEAN EFIAPI StandardSignatureIsAuthenticAMD(VOID)
Definition: X86BaseCpuLib.c:27
struct CPUID_AMD_EXTENDED_CPU_SIG_ECX::@592 Bits
struct CPUID_AMD_PROCESSOR_TOPOLOGY_EBX::@598 Bits
struct CPUID_AMD_VIR_PHY_ADDRESS_SIZE_ECX::@596 Bits
struct CPUID_CACHE_PARAMS_EAX::@698 Bits
UINT32 MaximumAddressableIdsForLogicalProcessors
Definition: Cpuid.h:843
struct CPUID_EXTENDED_TOPOLOGY_EAX::@714 Bits
struct CPUID_EXTENDED_TOPOLOGY_EBX::@715 Bits
struct CPUID_EXTENDED_TOPOLOGY_ECX::@716 Bits
struct CPUID_VERSION_INFO_EBX::@694 Bits
UINT32 MaximumAddressableIdsForLogicalProcessors
Definition: Cpuid.h:147
struct CPUID_VERSION_INFO_EDX::@696 Bits
UINT32 DivideValue1
Low 2 bits of the divide value.
Definition: LocalApic.h:109
UINT32 DivideValue2
Highest 1 bit of the divide value.
Definition: LocalApic.h:111
UINT32 Vector
The vector number of the interrupt being sent.
Definition: LocalApic.h:64
UINT32 DeliveryMode
Specifies the type of IPI to be sent.
Definition: LocalApic.h:65
UINT32 Level
0 for the INIT level de-assert delivery mode. Otherwise 1.
Definition: LocalApic.h:69
UINT32 DestinationShorthand
A shorthand notation to specify the destination of the interrupt.
Definition: LocalApic.h:72
UINT32 DeliveryStatus
Indicates the IPI delivery status. This field is reserved in x2APIC mode.
Definition: LocalApic.h:67
UINT32 TriggerMode
0:edge, 1:level.
Definition: LocalApic.h:144
UINT32 InputPinPolarity
Interrupt Input Pin Polarity.
Definition: LocalApic.h:142
UINT32 DeliveryMode
Specifies the type of interrupt to be sent.
Definition: LocalApic.h:139
UINT32 Mask
0: Not masked, 1: Masked.
Definition: LocalApic.h:145
UINT32 Vector
The vector number of the interrupt being sent.
Definition: LocalApic.h:122
UINT32 TimerMode
0: One-shot, 1: Periodic.
Definition: LocalApic.h:127
UINT32 Mask
0: Not masked, 1: Masked.
Definition: LocalApic.h:126
UINT32 BaseAddress
Must be 0FEEH.
Definition: LocalApic.h:161
UINT32 DestinationId
Specifies the Destination ID.
Definition: LocalApic.h:160
UINT32 DeliveryMode
Specifies the type of interrupt to be sent.
Definition: LocalApic.h:172
UINT32 Level
0:Deassert, 1:Assert. Ignored for Edge triggered interrupts.
Definition: LocalApic.h:174
UINT32 TriggerMode
0:Edge, 1:Level.
Definition: LocalApic.h:175
UINT32 Vector
Interrupt vector in range 010h..0FEH.
Definition: LocalApic.h:171
UINT32 SpuriousVector
Spurious Vector.
Definition: LocalApic.h:94
UINT32 SoftwareEnable
APIC Software Enable/Disable.
Definition: LocalApic.h:95
struct MSR_IA32_APIC_BASE_REGISTER::@627 Bits