diff options
Diffstat (limited to 'UefiCpuPkg')
-rw-r--r-- | UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c | 69 | ||||
-rw-r--r-- | UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf | 7 |
2 files changed, 67 insertions, 9 deletions
diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c index bf318e06e4..8c6e8d7415 100644 --- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c +++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c @@ -22,12 +22,40 @@ #include <Library/LocalApicLib.h>
#include <Library/IoLib.h>
#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
//
// Library internal functions
//
/**
+ Determine if the CPU supports the Local APIC Base Address MSR.
+
+ @retval TRUE The CPU supports the Local APIC Base Address MSR.
+ @retval FALSE The CPU does not support the Local APIC Base Address MSR.
+
+**/
+BOOLEAN
+LocalApicBaseAddressMsrSupported (
+ VOID
+ )
+{
+ UINT32 RegEax;
+ UINTN FamilyId;
+
+ AsmCpuid (1, &RegEax, NULL, NULL, NULL);
+ FamilyId = BitFieldRead32 (RegEax, 8, 11);
+ if (FamilyId == 0x04 || FamilyId == 0x05) {
+ //
+ // CPUs with a FamilyId of 0x04 or 0x05 do not support the
+ // Local APIC Base Address MSR
+ //
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
Retrieve the base address of local APIC.
@return The base address of local APIC.
@@ -39,8 +67,16 @@ GetLocalApicBaseAddress ( VOID
)
{
- MSR_IA32_APIC_BASE ApicBaseMsr;
-
+ MSR_IA32_APIC_BASE ApicBaseMsr;
+
+ if (!LocalApicBaseAddressMsrSupported ()) {
+ //
+ // If CPU does not support Local APIC Base Address MSR, then retrieve
+ // Local APIC Base Address from PCD
+ //
+ return PcdGet32 (PcdCpuLocalApicBaseAddress);
+ }
+
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHigh, 32)) +
@@ -61,10 +97,17 @@ SetLocalApicBaseAddress ( IN UINTN BaseAddress
)
{
- MSR_IA32_APIC_BASE ApicBaseMsr;
+ MSR_IA32_APIC_BASE ApicBaseMsr;
ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0);
+ if (!LocalApicBaseAddressMsrSupported ()) {
+ //
+ // Ignore set request of the CPU does not support APIC Base Address MSR
+ //
+ return;
+ }
+
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
ApicBaseMsr.Bits.ApicBaseLow = (UINT32) (BaseAddress >> 12);
@@ -257,7 +300,14 @@ GetApicMode ( VOID
)
{
- MSR_IA32_APIC_BASE ApicBaseMsr;
+ MSR_IA32_APIC_BASE ApicBaseMsr;
+
+ if (!LocalApicBaseAddressMsrSupported ()) {
+ //
+ // If CPU does not support APIC Base Address MSR, then return XAPIC mode
+ //
+ return LOCAL_APIC_MODE_XAPIC;
+ }
ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
//
@@ -288,8 +338,15 @@ SetApicMode ( IN UINTN ApicMode
)
{
- UINTN CurrentMode;
- MSR_IA32_APIC_BASE ApicBaseMsr;
+ UINTN CurrentMode;
+ MSR_IA32_APIC_BASE ApicBaseMsr;
+
+ if (!LocalApicBaseAddressMsrSupported ()) {
+ //
+ // Ignore set request if the CPU does not support APIC Base Address MSR
+ //
+ return;
+ }
CurrentMode = GetApicMode ();
if (CurrentMode == LOCAL_APIC_MODE_XAPIC) {
diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf index 1e0e98433d..53e186858f 100644 --- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf +++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf @@ -21,7 +21,7 @@ MODULE_UNI_FILE = BaseXApicX2ApicLib.uni
FILE_GUID = 967B6E05-F10D-4c10-8BF7-365291CA143F
MODULE_TYPE = BASE
- VERSION_STRING = 1.0
+ VERSION_STRING = 1.1
LIBRARY_CLASS = LocalApicLib
#
@@ -42,7 +42,8 @@ DebugLib
TimerLib
IoLib
+ PcdLib
[Pcd]
- gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds ## SOMETIMES_CONSUMES
-
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds ## SOMETIMES_CONSUMES
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress ## SOMETIMES_CONSUMES
|