TianoCore EDK2 master
Loading...
Searching...
No Matches
BaseXApicX2ApicLib.c
Go to the documentation of this file.
1
15#include <Register/Amd/Cpuid.h>
16#include <Register/Intel/Msr.h>
18
19#include <Library/BaseLib.h>
20#include <Library/DebugLib.h>
22#include <Library/IoLib.h>
23#include <Library/TimerLib.h>
24#include <Library/PcdLib.h>
25#include <Library/CpuLib.h>
27
28//
29// Library internal functions
30//
31
41BOOLEAN
43 IN UINT32 MsrIndex
44 )
45{
46 if (!TdIsEnabled ()) {
47 return FALSE;
48 }
49
50 switch (MsrIndex) {
55 case MSR_IA32_X2APIC_ISR1:
56 case MSR_IA32_X2APIC_ISR2:
57 case MSR_IA32_X2APIC_ISR3:
58 case MSR_IA32_X2APIC_ISR4:
59 case MSR_IA32_X2APIC_ISR5:
60 case MSR_IA32_X2APIC_ISR6:
61 case MSR_IA32_X2APIC_ISR7:
63 case MSR_IA32_X2APIC_TMR1:
64 case MSR_IA32_X2APIC_TMR2:
65 case MSR_IA32_X2APIC_TMR3:
66 case MSR_IA32_X2APIC_TMR4:
67 case MSR_IA32_X2APIC_TMR5:
68 case MSR_IA32_X2APIC_TMR6:
69 case MSR_IA32_X2APIC_TMR7:
71 case MSR_IA32_X2APIC_IRR1:
72 case MSR_IA32_X2APIC_IRR2:
73 case MSR_IA32_X2APIC_IRR3:
74 case MSR_IA32_X2APIC_IRR4:
75 case MSR_IA32_X2APIC_IRR5:
76 case MSR_IA32_X2APIC_IRR6:
77 case MSR_IA32_X2APIC_IRR7:
78 return FALSE;
79 default:
80 break;
81 }
82
83 return TRUE;
84}
85
93UINT64
95 IN UINT32 MsrIndex
96 )
97{
98 UINT64 Val;
99 UINT64 Status;
100
101 if (AccessMsrTdxCall (MsrIndex)) {
102 Status = TdVmCall (TDVMCALL_RDMSR, (UINT64)MsrIndex, 0, 0, 0, &Val);
103 if (Status != 0) {
104 TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0);
105 }
106 } else {
107 Val = AsmReadMsr64 (MsrIndex);
108 }
109
110 return Val;
111}
112
122UINT64
124 IN UINT32 MsrIndex,
125 IN UINT64 Value
126 )
127{
128 UINT64 Status;
129
130 if (AccessMsrTdxCall (MsrIndex)) {
131 Status = TdVmCall (TDVMCALL_WRMSR, (UINT64)MsrIndex, Value, 0, 0, 0);
132 if (Status != 0) {
133 TdVmCall (TDVMCALL_HALT, 0, 0, 0, 0, 0);
134 }
135 } else {
136 AsmWriteMsr64 (MsrIndex, Value);
137 }
138
139 return Value;
140}
141
149UINT32
151 IN UINT32 MsrIndex
152 )
153{
154 return (UINT32)LocalApicReadMsrReg64 (MsrIndex);
155}
156
166UINT32
168 IN UINT32 MsrIndex,
169 IN UINT32 Value
170 )
171{
172 return (UINT32)LocalApicWriteMsrReg64 (MsrIndex, Value);
173}
174
182BOOLEAN
184 VOID
185 )
186{
187 UINT32 RegEax;
188 UINTN FamilyId;
189
190 AsmCpuid (1, &RegEax, NULL, NULL, NULL);
191 FamilyId = BitFieldRead32 (RegEax, 8, 11);
192 if ((FamilyId == 0x04) || (FamilyId == 0x05)) {
193 //
194 // CPUs with a FamilyId of 0x04 or 0x05 do not support the
195 // Local APIC Base Address MSR
196 //
197 return FALSE;
198 }
199
200 return TRUE;
201}
202
209UINTN
210EFIAPI
212 VOID
213 )
214{
215 MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
216
218 //
219 // If CPU does not support Local APIC Base Address MSR, then retrieve
220 // Local APIC Base Address from PCD
221 //
222 return PcdGet32 (PcdCpuLocalApicBaseAddress);
223 }
224
226
227 return (UINTN)(LShiftU64 ((UINT64)ApicBaseMsr.Bits.ApicBaseHi, 32)) +
228 (((UINTN)ApicBaseMsr.Bits.ApicBase) << 12);
229}
230
239VOID
240EFIAPI
242 IN UINTN BaseAddress
243 )
244{
245 MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
246
247 ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0);
248
250 //
251 // Ignore set request of the CPU does not support APIC Base Address MSR
252 //
253 return;
254 }
255
257
258 ApicBaseMsr.Bits.ApicBase = (UINT32)(BaseAddress >> 12);
259 ApicBaseMsr.Bits.ApicBaseHi = (UINT32)(RShiftU64 ((UINT64)BaseAddress, 32));
260
262}
263
277UINT32
278EFIAPI
280 IN UINTN MmioOffset
281 )
282{
283 UINT32 MsrIndex;
284
285 ASSERT ((MmioOffset & 0xf) == 0);
286
288 return MmioRead32 (GetLocalApicBaseAddress () + MmioOffset);
289 } else {
290 //
291 // DFR is not supported in x2APIC mode.
292 //
293 ASSERT (MmioOffset != XAPIC_ICR_DFR_OFFSET);
294 //
295 // Note that in x2APIC mode, ICR is a 64-bit MSR that needs special treatment. It
296 // is not supported in this function for simplicity.
297 //
298 ASSERT (MmioOffset != XAPIC_ICR_HIGH_OFFSET);
299
300 MsrIndex = (UINT32)(MmioOffset >> 4) + X2APIC_MSR_BASE_ADDRESS;
301 return LocalApicReadMsrReg32 (MsrIndex);
302 }
303}
304
319VOID
320EFIAPI
322 IN UINTN MmioOffset,
323 IN UINT32 Value
324 )
325{
326 UINT32 MsrIndex;
327
328 ASSERT ((MmioOffset & 0xf) == 0);
329
331 MmioWrite32 (GetLocalApicBaseAddress () + MmioOffset, Value);
332 } else {
333 //
334 // DFR is not supported in x2APIC mode.
335 //
336 ASSERT (MmioOffset != XAPIC_ICR_DFR_OFFSET);
337 //
338 // Note that in x2APIC mode, ICR is a 64-bit MSR that needs special treatment. It
339 // is not supported in this function for simplicity.
340 //
341 ASSERT (MmioOffset != XAPIC_ICR_HIGH_OFFSET);
342 ASSERT (MmioOffset != XAPIC_ICR_LOW_OFFSET);
343
344 MsrIndex = (UINT32)(MmioOffset >> 4) + X2APIC_MSR_BASE_ADDRESS;
345 //
346 // The serializing semantics of WRMSR are relaxed when writing to the APIC registers.
347 // Use memory fence here to force the serializing semantics to be consisent with xAPIC mode.
348 //
349 MemoryFence ();
350 LocalApicWriteMsrReg32 (MsrIndex, Value);
351 }
352}
353
362VOID
364 IN UINT32 IcrLow,
365 IN UINT32 ApicId
366 )
367{
368 UINT64 MsrValue;
369 LOCAL_APIC_ICR_LOW IcrLowReg;
370 UINTN LocalApciBaseAddress;
371 UINT32 IcrHigh;
372 BOOLEAN InterruptState;
373
374 //
375 // Legacy APIC or X2APIC?
376 //
378 ASSERT (ApicId <= 0xff);
379
380 InterruptState = SaveAndDisableInterrupts ();
381
382 //
383 // Get base address of this LAPIC
384 //
385 LocalApciBaseAddress = GetLocalApicBaseAddress ();
386
387 //
388 // Save existing contents of ICR high 32 bits
389 //
390 IcrHigh = MmioRead32 (LocalApciBaseAddress + XAPIC_ICR_HIGH_OFFSET);
391
392 //
393 // Wait for DeliveryStatus clear in case a previous IPI
394 // is still being sent
395 //
396 do {
397 IcrLowReg.Uint32 = MmioRead32 (LocalApciBaseAddress + XAPIC_ICR_LOW_OFFSET);
398 } while (IcrLowReg.Bits.DeliveryStatus != 0);
399
400 //
401 // For xAPIC, the act of writing to the low doubleword of the ICR causes the IPI to be sent.
402 //
403 MmioWrite32 (LocalApciBaseAddress + XAPIC_ICR_HIGH_OFFSET, ApicId << 24);
404 MmioWrite32 (LocalApciBaseAddress + XAPIC_ICR_LOW_OFFSET, IcrLow);
405
406 //
407 // Wait for DeliveryStatus clear again
408 //
409 do {
410 IcrLowReg.Uint32 = MmioRead32 (LocalApciBaseAddress + XAPIC_ICR_LOW_OFFSET);
411 } while (IcrLowReg.Bits.DeliveryStatus != 0);
412
413 //
414 // And restore old contents of ICR high
415 //
416 MmioWrite32 (LocalApciBaseAddress + XAPIC_ICR_HIGH_OFFSET, IcrHigh);
417
418 SetInterruptState (InterruptState);
419 } else {
420 //
421 // For x2APIC, A single MSR write to the Interrupt Command Register is required for dispatching an
422 // interrupt in x2APIC mode.
423 //
424 MsrValue = LShiftU64 ((UINT64)ApicId, 32) | IcrLow;
425 AsmWriteMsr64 (X2APIC_MSR_ICR_ADDRESS, MsrValue);
426 }
427}
428
429//
430// Library API implementation functions
431//
432
441UINTN
442EFIAPI
444 VOID
445 )
446{
447 MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
448
450 //
451 // If CPU does not support APIC Base Address MSR, then return XAPIC mode
452 //
454 }
455
457 //
458 // Local APIC should have been enabled
459 //
460 ASSERT (ApicBaseMsr.Bits.EN != 0);
461 if (ApicBaseMsr.Bits.EXTD != 0) {
463 } else {
465 }
466}
467
479VOID
480EFIAPI
482 IN UINTN ApicMode
483 )
484{
485 UINTN CurrentMode;
486 MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;
487
489 //
490 // Ignore set request if the CPU does not support APIC Base Address MSR
491 //
492 return;
493 }
494
495 CurrentMode = GetApicMode ();
496 if (CurrentMode == LOCAL_APIC_MODE_XAPIC) {
497 switch (ApicMode) {
499 break;
502 ApicBaseMsr.Bits.EXTD = 1;
504 break;
505 default:
506 ASSERT (FALSE);
507 }
508 } else {
509 switch (ApicMode) {
511 //
512 // Transition from x2APIC mode to xAPIC mode is a two-step process:
513 // x2APIC -> Local APIC disabled -> xAPIC
514 //
515 ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);
516 ApicBaseMsr.Bits.EXTD = 0;
517 ApicBaseMsr.Bits.EN = 0;
519 ApicBaseMsr.Bits.EN = 1;
521 break;
523 break;
524 default:
525 ASSERT (FALSE);
526 }
527 }
528}
529
539UINT32
540EFIAPI
542 VOID
543 )
544{
545 UINT32 ApicId;
546 UINT32 MaxCpuIdIndex;
547 UINT32 RegEbx;
548
550 //
551 // Get the max index of basic CPUID
552 //
553 AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL);
554 //
555 // If CPUID Leaf B is supported,
556 // And CPUID.0BH:EBX[15:0] reports a non-zero value,
557 // Then the initial 32-bit APIC ID = CPUID.0BH:EDX
558 // Else the initial 8-bit APIC ID = CPUID.1:EBX[31:24]
559 //
560 if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) {
561 AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 0, NULL, &RegEbx, NULL, &ApicId);
562 if ((RegEbx & (BIT16 - 1)) != 0) {
563 return ApicId;
564 }
565 }
566
568 return RegEbx >> 24;
569 } else {
570 return GetApicId ();
571 }
572}
573
579UINT32
580EFIAPI
582 VOID
583 )
584{
585 UINT32 ApicId;
586 UINT32 InitApicId;
587
588 ApicId = ReadLocalApicReg (XAPIC_ID_OFFSET);
590 ApicId = ((InitApicId = GetInitialApicId ()) < 0x100) ? (ApicId >> 24) : InitApicId;
591 }
592
593 return ApicId;
594}
595
601UINT32
602EFIAPI
604 VOID
605 )
606{
607 return ReadLocalApicReg (XAPIC_VERSION_OFFSET);
608}
609
618VOID
619EFIAPI
621 IN UINT32 ApicId,
622 IN UINT8 Vector
623 )
624{
625 LOCAL_APIC_ICR_LOW IcrLow;
626
627 IcrLow.Uint32 = 0;
628 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_FIXED;
629 IcrLow.Bits.Level = 1;
630 IcrLow.Bits.Vector = Vector;
631 SendIpi (IcrLow.Uint32, ApicId);
632}
633
641VOID
642EFIAPI
644 IN UINT8 Vector
645 )
646{
647 LOCAL_APIC_ICR_LOW IcrLow;
648
649 IcrLow.Uint32 = 0;
650 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_FIXED;
651 IcrLow.Bits.Level = 1;
652 IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF;
653 IcrLow.Bits.Vector = Vector;
654 SendIpi (IcrLow.Uint32, 0);
655}
656
664VOID
665EFIAPI
667 IN UINT32 ApicId
668 )
669{
670 LOCAL_APIC_ICR_LOW IcrLow;
671
672 IcrLow.Uint32 = 0;
673 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_SMI;
674 IcrLow.Bits.Level = 1;
675 SendIpi (IcrLow.Uint32, ApicId);
676}
677
683VOID
684EFIAPI
686 VOID
687 )
688{
689 LOCAL_APIC_ICR_LOW IcrLow;
690
691 IcrLow.Uint32 = 0;
692 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_SMI;
693 IcrLow.Bits.Level = 1;
694 IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF;
695 SendIpi (IcrLow.Uint32, 0);
696}
697
705VOID
706EFIAPI
708 IN UINT32 ApicId
709 )
710{
711 LOCAL_APIC_ICR_LOW IcrLow;
712
713 IcrLow.Uint32 = 0;
714 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_INIT;
715 IcrLow.Bits.Level = 1;
716 SendIpi (IcrLow.Uint32, ApicId);
717}
718
724VOID
725EFIAPI
727 VOID
728 )
729{
730 LOCAL_APIC_ICR_LOW IcrLow;
731
732 IcrLow.Uint32 = 0;
733 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_INIT;
734 IcrLow.Bits.Level = 1;
735 IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF;
736 SendIpi (IcrLow.Uint32, 0);
737}
738
747VOID
748EFIAPI
750 IN UINT32 StartupRoutine
751 )
752{
753 LOCAL_APIC_ICR_LOW IcrLow;
754
755 ASSERT (StartupRoutine < 0x100000);
756 ASSERT ((StartupRoutine & 0xfff) == 0);
757
758 IcrLow.Uint32 = 0;
759 IcrLow.Bits.Vector = (StartupRoutine >> 12);
760 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP;
761 IcrLow.Bits.Level = 1;
762 IcrLow.Bits.DestinationShorthand = LOCAL_APIC_DESTINATION_SHORTHAND_ALL_EXCLUDING_SELF;
763 SendIpi (IcrLow.Uint32, 0);
764}
765
778VOID
779EFIAPI
781 IN UINT32 ApicId,
782 IN UINT32 StartupRoutine
783 )
784{
785 LOCAL_APIC_ICR_LOW IcrLow;
786
787 ASSERT (StartupRoutine < 0x100000);
788 ASSERT ((StartupRoutine & 0xfff) == 0);
789
790 SendInitIpi (ApicId);
791 MicroSecondDelay (PcdGet32 (PcdCpuInitIpiDelayInMicroSeconds));
792 IcrLow.Uint32 = 0;
793 IcrLow.Bits.Vector = (StartupRoutine >> 12);
794 IcrLow.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_STARTUP;
795 IcrLow.Bits.Level = 1;
796 SendIpi (IcrLow.Uint32, ApicId);
798 MicroSecondDelay (200);
799 SendIpi (IcrLow.Uint32, ApicId);
800 }
801}
802
814VOID
815EFIAPI
817 IN UINT32 StartupRoutine
818 )
819{
821 MicroSecondDelay (PcdGet32 (PcdCpuInitIpiDelayInMicroSeconds));
822 SendStartupIpiAllExcludingSelf (StartupRoutine);
824 MicroSecondDelay (200);
825 SendStartupIpiAllExcludingSelf (StartupRoutine);
826 }
827}
828
837VOID
838EFIAPI
840 IN BOOLEAN Enable
841 )
842{
843 LOCAL_APIC_SVR Svr;
844
845 //
846 // Set local APIC software-enabled bit.
847 //
848 Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET);
849 if (Enable) {
850 if (Svr.Bits.SoftwareEnable == 0) {
851 Svr.Bits.SoftwareEnable = 1;
852 WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);
853 }
854 } else {
855 if (Svr.Bits.SoftwareEnable == 1) {
856 Svr.Bits.SoftwareEnable = 0;
857 WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);
858 }
859 }
860}
861
870VOID
871EFIAPI
873 VOID
874 )
875{
876 LOCAL_APIC_SVR Svr;
878
879 //
880 // Enable the APIC via SVR and set the spurious interrupt to use Int 00F.
881 //
882 Svr.Uint32 = ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET);
883 Svr.Bits.SpuriousVector = 0xf;
884 Svr.Bits.SoftwareEnable = 1;
885 WriteLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET, Svr.Uint32);
886
887 //
888 // Program the LINT0 vector entry as ExtInt. Not masked, edge, active high.
889 //
890 Lint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT0_OFFSET);
891 Lint.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_EXTINT;
892 Lint.Bits.InputPinPolarity = 0;
893 Lint.Bits.TriggerMode = 0;
894 Lint.Bits.Mask = 0;
895 WriteLocalApicReg (XAPIC_LVT_LINT0_OFFSET, Lint.Uint32);
896
897 //
898 // Program the LINT0 vector entry as NMI. Not masked, edge, active high.
899 //
900 Lint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT1_OFFSET);
901 Lint.Bits.DeliveryMode = LOCAL_APIC_DELIVERY_MODE_NMI;
902 Lint.Bits.InputPinPolarity = 0;
903 Lint.Bits.TriggerMode = 0;
904 Lint.Bits.Mask = 0;
905 WriteLocalApicReg (XAPIC_LVT_LINT1_OFFSET, Lint.Uint32);
906}
907
913VOID
914EFIAPI
916 VOID
917 )
918{
919 LOCAL_APIC_LVT_LINT LvtLint;
920
921 LvtLint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT0_OFFSET);
922 LvtLint.Bits.Mask = 1;
923 WriteLocalApicReg (XAPIC_LVT_LINT0_OFFSET, LvtLint.Uint32);
924
925 LvtLint.Uint32 = ReadLocalApicReg (XAPIC_LVT_LINT1_OFFSET);
926 LvtLint.Bits.Mask = 1;
927 WriteLocalApicReg (XAPIC_LVT_LINT1_OFFSET, LvtLint.Uint32);
928}
929
935UINT32
936EFIAPI
938 VOID
939 )
940{
941 return ReadLocalApicReg (XAPIC_TIMER_INIT_COUNT_OFFSET);
942}
943
949UINT32
950EFIAPI
952 VOID
953 )
954{
955 return ReadLocalApicReg (XAPIC_TIMER_CURRENT_COUNT_OFFSET);
956}
957
969VOID
970EFIAPI
972 IN UINTN DivideValue,
973 IN UINT32 InitCount,
974 IN BOOLEAN PeriodicMode,
975 IN UINT8 Vector
976 )
977{
978 LOCAL_APIC_DCR Dcr;
979 LOCAL_APIC_LVT_TIMER LvtTimer;
980 UINT32 Divisor;
981
982 //
983 // Ensure local APIC is in software-enabled state.
984 //
986
987 if (DivideValue != 0) {
988 ASSERT (DivideValue <= 128);
989 ASSERT (DivideValue == GetPowerOfTwo32 ((UINT32)DivideValue));
990 Divisor = (UINT32)((HighBitSet32 ((UINT32)DivideValue) - 1) & 0x7);
991
992 Dcr.Uint32 = ReadLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET);
993 Dcr.Bits.DivideValue1 = (Divisor & 0x3);
994 Dcr.Bits.DivideValue2 = (Divisor >> 2);
995 WriteLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET, Dcr.Uint32);
996 }
997
998 //
999 // Enable APIC timer interrupt with specified timer mode.
1000 //
1001 LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET);
1002 if (PeriodicMode) {
1003 LvtTimer.Bits.TimerMode = 1;
1004 } else {
1005 LvtTimer.Bits.TimerMode = 0;
1006 }
1007
1008 LvtTimer.Bits.Mask = 0;
1009 LvtTimer.Bits.Vector = Vector;
1010 WriteLocalApicReg (XAPIC_LVT_TIMER_OFFSET, LvtTimer.Uint32);
1011
1012 //
1013 // Program init-count register.
1014 //
1015 WriteLocalApicReg (XAPIC_TIMER_INIT_COUNT_OFFSET, InitCount);
1016}
1017
1027VOID
1028EFIAPI
1030 OUT UINTN *DivideValue OPTIONAL,
1031 OUT BOOLEAN *PeriodicMode OPTIONAL,
1032 OUT UINT8 *Vector OPTIONAL
1033 )
1034{
1035 UINT32 Divisor;
1036 LOCAL_APIC_DCR Dcr;
1037 LOCAL_APIC_LVT_TIMER LvtTimer;
1038
1039 //
1040 // Check the APIC Software Enable/Disable bit (bit 8) in Spurious-Interrupt
1041 // Vector Register.
1042 // This bit will be 1, if local APIC is software enabled.
1043 //
1044 ASSERT ((ReadLocalApicReg (XAPIC_SPURIOUS_VECTOR_OFFSET) & BIT8) != 0);
1045
1046 if (DivideValue != NULL) {
1047 Dcr.Uint32 = ReadLocalApicReg (XAPIC_TIMER_DIVIDE_CONFIGURATION_OFFSET);
1048 Divisor = Dcr.Bits.DivideValue1 | (Dcr.Bits.DivideValue2 << 2);
1049 Divisor = (Divisor + 1) & 0x7;
1050 *DivideValue = ((UINTN)1) << Divisor;
1051 }
1052
1053 if ((PeriodicMode != NULL) || (Vector != NULL)) {
1054 LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET);
1055 if (PeriodicMode != NULL) {
1056 if (LvtTimer.Bits.TimerMode == 1) {
1057 *PeriodicMode = TRUE;
1058 } else {
1059 *PeriodicMode = FALSE;
1060 }
1061 }
1062
1063 if (Vector != NULL) {
1064 *Vector = (UINT8)LvtTimer.Bits.Vector;
1065 }
1066 }
1067}
1068
1072VOID
1073EFIAPI
1075 VOID
1076 )
1077{
1078 LOCAL_APIC_LVT_TIMER LvtTimer;
1079
1080 LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET);
1081 LvtTimer.Bits.Mask = 0;
1082 WriteLocalApicReg (XAPIC_LVT_TIMER_OFFSET, LvtTimer.Uint32);
1083}
1084
1088VOID
1089EFIAPI
1091 VOID
1092 )
1093{
1094 LOCAL_APIC_LVT_TIMER LvtTimer;
1095
1096 LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET);
1097 LvtTimer.Bits.Mask = 1;
1098 WriteLocalApicReg (XAPIC_LVT_TIMER_OFFSET, LvtTimer.Uint32);
1099}
1100
1107BOOLEAN
1108EFIAPI
1110 VOID
1111 )
1112{
1113 LOCAL_APIC_LVT_TIMER LvtTimer;
1114
1115 LvtTimer.Uint32 = ReadLocalApicReg (XAPIC_LVT_TIMER_OFFSET);
1116 return (BOOLEAN)(LvtTimer.Bits.Mask == 0);
1117}
1118
1122VOID
1123EFIAPI
1125 VOID
1126 )
1127{
1128 WriteLocalApicReg (XAPIC_EOI_OFFSET, 0);
1129}
1130
1137UINT32
1138EFIAPI
1140 VOID
1141 )
1142{
1143 LOCAL_APIC_MSI_ADDRESS MsiAddress;
1144
1145 //
1146 // Return address for an MSI interrupt to be delivered only to the APIC ID
1147 // of the currently executing processor.
1148 //
1149 MsiAddress.Uint32 = 0;
1150 MsiAddress.Bits.BaseAddress = 0xFEE;
1151 MsiAddress.Bits.DestinationId = GetApicId ();
1152 return MsiAddress.Uint32;
1153}
1154
1183UINT64
1184EFIAPI
1186 IN UINT8 Vector,
1187 IN UINTN DeliveryMode,
1188 IN BOOLEAN LevelTriggered,
1189 IN BOOLEAN AssertionLevel
1190 )
1191{
1192 LOCAL_APIC_MSI_DATA MsiData;
1193
1194 ASSERT (Vector >= 0x10 && Vector <= 0xFE);
1195 ASSERT (DeliveryMode < 8 && DeliveryMode != 6 && DeliveryMode != 3);
1196
1197 MsiData.Uint64 = 0;
1198 MsiData.Bits.Vector = Vector;
1199 MsiData.Bits.DeliveryMode = (UINT32)DeliveryMode;
1200 if (LevelTriggered) {
1201 MsiData.Bits.TriggerMode = 1;
1202 if (AssertionLevel) {
1203 MsiData.Bits.Level = 1;
1204 }
1205 }
1206
1207 return MsiData.Uint64;
1208}
1209
1222VOID
1223EFIAPI
1225 IN UINT32 InitialApicId,
1226 OUT UINT32 *Package OPTIONAL,
1227 OUT UINT32 *Core OPTIONAL,
1228 OUT UINT32 *Thread OPTIONAL
1229 )
1230{
1231 BOOLEAN TopologyLeafSupported;
1232 CPUID_VERSION_INFO_EBX VersionInfoEbx;
1233 CPUID_VERSION_INFO_EDX VersionInfoEdx;
1234 CPUID_CACHE_PARAMS_EAX CacheParamsEax;
1235 CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax;
1236 CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx;
1237 CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx;
1238 CPUID_AMD_EXTENDED_CPU_SIG_ECX AmdExtendedCpuSigEcx;
1239 CPUID_AMD_PROCESSOR_TOPOLOGY_EBX AmdProcessorTopologyEbx;
1240 CPUID_AMD_VIR_PHY_ADDRESS_SIZE_ECX AmdVirPhyAddressSizeEcx;
1241 UINT32 MaxStandardCpuIdIndex;
1242 UINT32 MaxExtendedCpuIdIndex;
1243 UINT32 SubIndex;
1244 UINTN LevelType;
1245 UINT32 MaxLogicProcessorsPerPackage;
1246 UINT32 MaxCoresPerPackage;
1247 UINTN ThreadBits;
1248 UINTN CoreBits;
1249
1250 //
1251 // Check if the processor is capable of supporting more than one logical processor.
1252 //
1253 AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32);
1254 if (VersionInfoEdx.Bits.HTT == 0) {
1255 if (Thread != NULL) {
1256 *Thread = 0;
1257 }
1258
1259 if (Core != NULL) {
1260 *Core = 0;
1261 }
1262
1263 if (Package != NULL) {
1264 *Package = 0;
1265 }
1266
1267 return;
1268 }
1269
1270 //
1271 // Assume three-level mapping of APIC ID: Package|Core|Thread.
1272 //
1273 ThreadBits = 0;
1274 CoreBits = 0;
1275
1276 //
1277 // Get max index of CPUID
1278 //
1279 AsmCpuid (CPUID_SIGNATURE, &MaxStandardCpuIdIndex, NULL, NULL, NULL);
1280 AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedCpuIdIndex, NULL, NULL, NULL);
1281
1282 //
1283 // If the extended topology enumeration leaf is available, it
1284 // is the preferred mechanism for enumerating topology.
1285 //
1286 TopologyLeafSupported = FALSE;
1287 if (MaxStandardCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) {
1288 AsmCpuidEx (
1290 0,
1291 &ExtendedTopologyEax.Uint32,
1292 &ExtendedTopologyEbx.Uint32,
1293 &ExtendedTopologyEcx.Uint32,
1294 NULL
1295 );
1296 //
1297 // Quoting Intel SDM:
1298 // Software must detect the presence of CPUID leaf 0BH by
1299 // verifying (a) the highest leaf index supported by CPUID is >=
1300 // 0BH, and (b) CPUID.0BH:EBX[15:0] reports a non-zero value.
1301 //
1302 if (ExtendedTopologyEbx.Bits.LogicalProcessors != 0) {
1303 TopologyLeafSupported = TRUE;
1304
1305 //
1306 // Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract
1307 // the SMT sub-field of x2APIC ID.
1308 //
1309 LevelType = ExtendedTopologyEcx.Bits.LevelType;
1310 ASSERT (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT);
1311 ThreadBits = ExtendedTopologyEax.Bits.ApicIdShift;
1312
1313 //
1314 // Software must not assume any "level type" encoding
1315 // value to be related to any sub-leaf index, except sub-leaf 0.
1316 //
1317 SubIndex = 1;
1318 do {
1319 AsmCpuidEx (
1321 SubIndex,
1322 &ExtendedTopologyEax.Uint32,
1323 NULL,
1324 &ExtendedTopologyEcx.Uint32,
1325 NULL
1326 );
1327 LevelType = ExtendedTopologyEcx.Bits.LevelType;
1328 if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) {
1329 CoreBits = ExtendedTopologyEax.Bits.ApicIdShift - ThreadBits;
1330 break;
1331 }
1332
1333 SubIndex++;
1334 } while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID);
1335 }
1336 }
1337
1338 if (!TopologyLeafSupported) {
1339 //
1340 // Get logical processor count
1341 //
1342 AsmCpuid (CPUID_VERSION_INFO, NULL, &VersionInfoEbx.Uint32, NULL, NULL);
1343 MaxLogicProcessorsPerPackage = VersionInfoEbx.Bits.MaximumAddressableIdsForLogicalProcessors;
1344
1345 //
1346 // Assume single-core processor
1347 //
1348 MaxCoresPerPackage = 1;
1349
1350 //
1351 // Check for topology extensions on AMD processor
1352 //
1354 if (MaxExtendedCpuIdIndex >= CPUID_AMD_PROCESSOR_TOPOLOGY) {
1355 AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, &AmdExtendedCpuSigEcx.Uint32, NULL);
1356 if (AmdExtendedCpuSigEcx.Bits.TopologyExtensions != 0) {
1357 //
1358 // Account for max possible thread count to decode ApicId
1359 //
1360 AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, NULL, NULL, &AmdVirPhyAddressSizeEcx.Uint32, NULL);
1361 MaxLogicProcessorsPerPackage = 1 << AmdVirPhyAddressSizeEcx.Bits.ApicIdCoreIdSize;
1362
1363 //
1364 // Get cores per processor package
1365 //
1366 AsmCpuid (CPUID_AMD_PROCESSOR_TOPOLOGY, NULL, &AmdProcessorTopologyEbx.Uint32, NULL, NULL);
1367 MaxCoresPerPackage = MaxLogicProcessorsPerPackage / (AmdProcessorTopologyEbx.Bits.ThreadsPerCore + 1);
1368 }
1369 }
1370 } else {
1371 //
1372 // Extract core count based on CACHE information
1373 //
1374 if (MaxStandardCpuIdIndex >= CPUID_CACHE_PARAMS) {
1375 AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NULL, NULL);
1376 if (CacheParamsEax.Uint32 != 0) {
1377 MaxCoresPerPackage = CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 1;
1378 }
1379 }
1380 }
1381
1382 ThreadBits = (UINTN)(HighBitSet32 (MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1);
1383 CoreBits = (UINTN)(HighBitSet32 (MaxCoresPerPackage - 1) + 1);
1384 }
1385
1386 if (Thread != NULL) {
1387 *Thread = InitialApicId & ((1 << ThreadBits) - 1);
1388 }
1389
1390 if (Core != NULL) {
1391 *Core = (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1);
1392 }
1393
1394 if (Package != NULL) {
1395 *Package = (InitialApicId >> (ThreadBits + CoreBits));
1396 }
1397}
1398
1415VOID
1417 IN UINT32 InitialApicId,
1418 OUT UINT32 *Package OPTIONAL,
1419 OUT UINT32 *Die OPTIONAL,
1420 OUT UINT32 *Tile OPTIONAL,
1421 OUT UINT32 *Module OPTIONAL,
1422 OUT UINT32 *Core OPTIONAL,
1423 OUT UINT32 *Thread OPTIONAL
1424 )
1425{
1426 CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax;
1427 CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx;
1428 CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx;
1429 UINT32 MaxExtendedCpuIdIndex;
1430 UINT32 TopologyLevel;
1431 UINT32 PreviousLevel;
1432 UINT32 Data;
1433
1434 if (Die != NULL) {
1435 *Die = 0;
1436 }
1437
1438 if (Tile != NULL) {
1439 *Tile = 0;
1440 }
1441
1442 if (Module != NULL) {
1443 *Module = 0;
1444 }
1445
1446 PreviousLevel = 0;
1447 TopologyLevel = 0;
1448
1450 AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedCpuIdIndex, NULL, NULL, NULL);
1451 if (MaxExtendedCpuIdIndex >= AMD_CPUID_EXTENDED_TOPOLOGY) {
1452 do {
1453 AsmCpuidEx (
1455 TopologyLevel,
1456 &ExtendedTopologyEax.Uint32,
1457 &ExtendedTopologyEbx.Uint32,
1458 &ExtendedTopologyEcx.Uint32,
1459 NULL
1460 );
1461
1465 break;
1466 }
1467
1468 Data = InitialApicId >> PreviousLevel;
1469 Data &= (1 << (ExtendedTopologyEax.Bits.ApicIdShift - PreviousLevel)) - 1;
1470
1471 switch (ExtendedTopologyEcx.Bits.LevelType) {
1472 case CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT:
1473 if (Thread != NULL) {
1474 *Thread = Data;
1475 }
1476
1477 break;
1478 case CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE:
1479 if (Core != NULL) {
1480 *Core = Data;
1481 }
1482
1483 break;
1485 if (Module != NULL) {
1486 *Module = Data;
1487 }
1488
1489 break;
1490 case CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_TILE:
1491 if (Die != NULL) {
1492 *Die = Data;
1493 }
1494
1495 break;
1496 default:
1497 break;
1498 }
1499
1500 TopologyLevel++;
1501 PreviousLevel = ExtendedTopologyEax.Bits.ApicIdShift;
1502 } while (ExtendedTopologyEbx.Bits.LogicalProcessors != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID);
1503
1504 if (Package != NULL) {
1505 *Package = InitialApicId >> PreviousLevel;
1506 }
1507 }
1508
1511 if (TopologyLevel == 0) {
1512 GetProcessorLocationByApicId (InitialApicId, Package, Core, Thread);
1513 }
1514
1515 return;
1516}
1517
1534VOID
1535EFIAPI
1537 IN UINT32 InitialApicId,
1538 OUT UINT32 *Package OPTIONAL,
1539 OUT UINT32 *Die OPTIONAL,
1540 OUT UINT32 *Tile OPTIONAL,
1541 OUT UINT32 *Module OPTIONAL,
1542 OUT UINT32 *Core OPTIONAL,
1543 OUT UINT32 *Thread OPTIONAL
1544 )
1545{
1546 CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax;
1547 CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx;
1548 CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx;
1549 UINT32 MaxStandardCpuIdIndex;
1550 UINT32 Index;
1551 UINTN LevelType;
1552 UINT32 Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2];
1553 UINT32 *Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2];
1554
1556 AmdGetProcessorLocation2ByApicId (InitialApicId, Package, Die, Tile, Module, Core, Thread);
1557 return;
1558 }
1559
1560 for (LevelType = 0; LevelType < ARRAY_SIZE (Bits); LevelType++) {
1561 Bits[LevelType] = 0;
1562 }
1563
1564 //
1565 // Quoting Intel SDM:
1566 // Software must detect the presence of CPUID leaf 1FH by verifying
1567 // (a) the highest leaf index supported by CPUID is >= 1FH, and (b)
1568 // CPUID.1FH:EBX[15:0] reports a non-zero value.
1569 //
1570 AsmCpuid (CPUID_SIGNATURE, &MaxStandardCpuIdIndex, NULL, NULL, NULL);
1571 if (MaxStandardCpuIdIndex < CPUID_V2_EXTENDED_TOPOLOGY) {
1572 ExtendedTopologyEbx.Bits.LogicalProcessors = 0;
1573 } else {
1574 AsmCpuidEx (CPUID_V2_EXTENDED_TOPOLOGY, 0, NULL, &ExtendedTopologyEbx.Uint32, NULL, NULL);
1575 }
1576
1577 if (ExtendedTopologyEbx.Bits.LogicalProcessors == 0) {
1578 if (Die != NULL) {
1579 *Die = 0;
1580 }
1581
1582 if (Tile != NULL) {
1583 *Tile = 0;
1584 }
1585
1586 if (Module != NULL) {
1587 *Module = 0;
1588 }
1589
1590 GetProcessorLocationByApicId (InitialApicId, Package, Core, Thread);
1591 return;
1592 }
1593
1594 //
1595 // If the V2 extended topology enumeration leaf is available, it
1596 // is the preferred mechanism for enumerating topology.
1597 //
1598 for (Index = 0; ; Index++) {
1599 AsmCpuidEx (
1601 Index,
1602 &ExtendedTopologyEax.Uint32,
1603 NULL,
1604 &ExtendedTopologyEcx.Uint32,
1605 NULL
1606 );
1607
1608 LevelType = ExtendedTopologyEcx.Bits.LevelType;
1609
1610 //
1611 // first level reported should be SMT.
1612 //
1613 ASSERT ((Index != 0) || (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT));
1615 break;
1616 }
1617
1618 ASSERT (LevelType < ARRAY_SIZE (Bits));
1619 Bits[LevelType] = ExtendedTopologyEax.Bits.ApicIdShift;
1620 }
1621
1622 for (LevelType = CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE; LevelType < ARRAY_SIZE (Bits); LevelType++) {
1623 //
1624 // If there are more levels between level-1 (low-level) and level-2 (high-level), the unknown levels will be ignored
1625 // and treated as an extension of the last known level (i.e., level-1 in this case).
1626 //
1627 if (Bits[LevelType] == 0) {
1628 Bits[LevelType] = Bits[LevelType - 1];
1629 }
1630 }
1631
1632 Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] = Package;
1633 Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE] = Die;
1634 Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_TILE] = Tile;
1636 Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE] = Core;
1637 Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT] = Thread;
1638
1639 Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] = 32;
1640
1641 for ( LevelType = CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT
1642 ; LevelType <= CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1
1643 ; LevelType++
1644 )
1645 {
1646 if (Location[LevelType] != NULL) {
1647 //
1648 // Bits[i] holds the number of bits to shift right on x2APIC ID to get a unique
1649 // topology ID of the next level type.
1650 //
1651 *Location[LevelType] = InitialApicId >> Bits[LevelType - 1];
1652
1653 //
1654 // Bits[i] - Bits[i-1] holds the number of bits for the next ONE level type.
1655 //
1656 *Location[LevelType] &= (1 << (Bits[LevelType] - Bits[LevelType - 1])) - 1;
1657 }
1658 }
1659}
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)
VOID EFIAPI MemoryFence(VOID)
Definition: CpuBreakpoint.c:42
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
UINTN EFIAPI TdVmCall(IN UINT64 Leaf, IN UINT64 Arg1, IN UINT64 Arg2, IN UINT64 Arg3, IN UINT64 Arg4, IN OUT VOID *Results)
Definition: IntelTdxNull.c:59
UINT32 EFIAPI BitFieldRead32(IN UINT32 Operand, IN UINTN StartBit, IN UINTN EndBit)
Definition: BitField.c:527
VOID EFIAPI SendInitSipiSipiAllExcludingSelf(IN UINT32 StartupRoutine)
VOID EFIAPI SendFixedIpiAllExcludingSelf(IN UINT8 Vector)
VOID EFIAPI InitializeLocalApicSoftwareEnable(IN BOOLEAN Enable)
UINT32 EFIAPI ReadLocalApicReg(IN UINTN MmioOffset)
VOID EFIAPI SendSmiIpi(IN UINT32 ApicId)
UINT32 EFIAPI GetApicVersion(VOID)
BOOLEAN EFIAPI GetApicTimerInterruptState(VOID)
VOID EFIAPI SetLocalApicBaseAddress(IN UINTN BaseAddress)
UINT32 EFIAPI GetApicId(VOID)
VOID EFIAPI DisableLvtInterrupts(VOID)
VOID EFIAPI GetApicTimerState(OUT UINTN *DivideValue OPTIONAL, OUT BOOLEAN *PeriodicMode OPTIONAL, OUT UINT8 *Vector OPTIONAL)
VOID EFIAPI SendInitIpi(IN UINT32 ApicId)
UINT32 EFIAPI GetInitialApicId(VOID)
VOID EFIAPI SendInitIpiAllExcludingSelf(VOID)
UINT64 LocalApicReadMsrReg64(IN UINT32 MsrIndex)
BOOLEAN LocalApicBaseAddressMsrSupported(VOID)
VOID EFIAPI SendSmiIpiAllExcludingSelf(VOID)
UINTN EFIAPI GetApicMode(VOID)
VOID EFIAPI ProgramVirtualWireMode(VOID)
BOOLEAN AccessMsrTdxCall(IN UINT32 MsrIndex)
VOID EFIAPI EnableApicTimerInterrupt(VOID)
UINT32 EFIAPI GetApicMsiAddress(VOID)
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)
VOID EFIAPI SendStartupIpiAllExcludingSelf(IN UINT32 StartupRoutine)
VOID EFIAPI SendFixedIpi(IN UINT32 ApicId, IN UINT8 Vector)
VOID EFIAPI WriteLocalApicReg(IN UINTN MmioOffset, IN UINT32 Value)
VOID EFIAPI SetApicMode(IN UINTN ApicMode)
UINT32 EFIAPI GetApicTimerInitCount(VOID)
UINTN EFIAPI GetLocalApicBaseAddress(VOID)
UINT64 EFIAPI GetApicMsiValue(IN UINT8 Vector, IN UINTN DeliveryMode, IN BOOLEAN LevelTriggered, IN BOOLEAN AssertionLevel)
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)
VOID EFIAPI InitializeApicTimer(IN UINTN DivideValue, IN UINT32 InitCount, IN BOOLEAN PeriodicMode, IN UINT8 Vector)
VOID EFIAPI SendApicEoi(VOID)
UINT32 LocalApicReadMsrReg32(IN UINT32 MsrIndex)
UINT32 EFIAPI GetApicTimerCurrentCount(VOID)
VOID EFIAPI SendInitSipiSipi(IN UINT32 ApicId, IN UINT32 StartupRoutine)
VOID EFIAPI DisableApicTimerInterrupt(VOID)
UINT32 LocalApicWriteMsrReg32(IN UINT32 MsrIndex, IN UINT32 Value)
UINT64 LocalApicWriteMsrReg64(IN UINT32 MsrIndex, IN UINT64 Value)
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_X2APIC
x2APIC mode.
Definition: LocalApicLib.h:16
#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 AMD_CPUID_EXTENDED_TOPOLOGY
Definition: Cpuid.h:64
#define CPUID_AMD_PROCESSOR_TOPOLOGY
Definition: Cpuid.h:540
#define MSR_IA32_X2APIC_ISR0
#define MSR_IA32_APIC_BASE
#define MSR_IA32_X2APIC_EOI
#define MSR_IA32_X2APIC_IRR0
#define MSR_IA32_X2APIC_TPR
#define MSR_IA32_X2APIC_TMR0
#define MSR_IA32_X2APIC_PPR
#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
BOOLEAN EFIAPI TdIsEnabled()
Definition: IntelTdxNull.c:79
#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