]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdePkg/BaseXApicLib: Support IA32 processors without MSR_IA32_APIC_BASE_ADDRESS
authorMichael Kinney <michael.d.kinney@intel.com>
Mon, 27 Apr 2015 19:47:26 +0000 (19:47 +0000)
committermdkinney <mdkinney@Edk2>
Mon, 27 Apr 2015 19:47:26 +0000 (19:47 +0000)
Use Family from CPUID 01 to detect support for the Local APIC Base Address MSR (MSR_IA32_APIC_BASE_ADDRESS).
If this MSR is not supported, then use Local APIC Base Address from the PCD PcdCpuLocalApicBaseAddress.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <michael.d.kinney@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17216 6f19259b-4bc3-4df7-8a09-765794883524

UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c
UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf

index 6f8cd2eb9b48c444cac6a2b21134da611f86dd89..f219b07888c0873a5279e8c3c83349de17aecbb8 100644 (file)
@@ -3,7 +3,7 @@
 \r
   This local APIC library instance supports xAPIC mode only.\r
 \r
-  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
 #include <Library/LocalApicLib.h>\r
 #include <Library/IoLib.h>\r
 #include <Library/TimerLib.h>\r
+#include <Library/PcdLib.h>\r
 \r
 //\r
 // Library internal functions\r
 //\r
 \r
+/**\r
+  Determine if the CPU supports the Local APIC Base Address MSR.\r
+\r
+  @retval TRUE  The CPU supports the Local APIC Base Address MSR.\r
+  @retval FALSE The CPU does not support the Local APIC Base Address MSR.\r
+\r
+**/\r
+BOOLEAN\r
+LocalApicBaseAddressMsrSupported (\r
+  VOID\r
+  )\r
+{\r
+  UINT32  RegEax;\r
+  UINTN   FamilyId;\r
+  \r
+  AsmCpuid (1, &RegEax, NULL, NULL, NULL);\r
+  FamilyId = BitFieldRead32 (RegEax, 8, 11);\r
+  if (FamilyId == 0x04 || FamilyId == 0x05) {\r
+    //\r
+    // CPUs with a FamilyId of 0x04 or 0x05 do not support the \r
+    // Local APIC Base Address MSR\r
+    //\r
+    return FALSE;\r
+  }\r
+  return TRUE;\r
+}\r
+\r
 /**\r
   Retrieve the base address of local APIC.\r
 \r
@@ -38,8 +66,16 @@ GetLocalApicBaseAddress (
   VOID\r
   )\r
 {\r
-  MSR_IA32_APIC_BASE ApicBaseMsr;\r
-  \r
+  MSR_IA32_APIC_BASE  ApicBaseMsr;\r
+\r
+  if (!LocalApicBaseAddressMsrSupported ()) {\r
+    //\r
+    // If CPU does not support Local APIC Base Address MSR, then retrieve\r
+    // Local APIC Base Address from PCD\r
+    //\r
+    return PcdGet32 (PcdCpuLocalApicBaseAddress);\r
+  }\r
+\r
   ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);\r
   \r
   return (UINTN)(LShiftU64 ((UINT64) ApicBaseMsr.Bits.ApicBaseHigh, 32)) +\r
@@ -60,10 +96,17 @@ SetLocalApicBaseAddress (
   IN UINTN                BaseAddress\r
   )\r
 {\r
-  MSR_IA32_APIC_BASE ApicBaseMsr;\r
+  MSR_IA32_APIC_BASE  ApicBaseMsr;\r
 \r
   ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0);\r
 \r
+  if (!LocalApicBaseAddressMsrSupported ()) {\r
+    //\r
+    // Ignore set request if the CPU does not support APIC Base Address MSR\r
+    //\r
+    return;\r
+  }\r
+\r
   ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);\r
 \r
   ApicBaseMsr.Bits.ApicBaseLow  = (UINT32) (BaseAddress >> 12);\r
@@ -202,14 +245,19 @@ GetApicMode (
 {\r
   DEBUG_CODE (\r
     {\r
-      MSR_IA32_APIC_BASE ApicBaseMsr;\r
+      MSR_IA32_APIC_BASE  ApicBaseMsr;\r
 \r
-      ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);\r
       //\r
-      // Local APIC should have been enabled\r
+      // Check to see if the CPU supports the APIC Base Address MSR \r
       //\r
-      ASSERT (ApicBaseMsr.Bits.En != 0);\r
-      ASSERT (ApicBaseMsr.Bits.Extd == 0);\r
+      if (LocalApicBaseAddressMsrSupported ()) {\r
+        ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);\r
+        //\r
+        // Local APIC should have been enabled\r
+        //\r
+        ASSERT (ApicBaseMsr.Bits.En != 0);\r
+        ASSERT (ApicBaseMsr.Bits.Extd == 0);\r
+      }\r
     }\r
   );\r
   return LOCAL_APIC_MODE_XAPIC;\r
index 120e6e50e9fbb36cf175318ea7a07e8e33261e33..7dd2714af3fcbe13783421db8ebbd13c11539693 100644 (file)
@@ -21,7 +21,7 @@
   MODULE_UNI_FILE                = BaseXApicLib.uni\r
   FILE_GUID                      = D87CA0A8-1AC2-439b-90F8-EF4A2AC88DAF\r
   MODULE_TYPE                    = BASE\r
-  VERSION_STRING                 = 1.0\r
+  VERSION_STRING                 = 1.1\r
   LIBRARY_CLASS                  = LocalApicLib \r
 \r
 #\r
@@ -42,6 +42,8 @@
   DebugLib\r
   TimerLib\r
   IoLib\r
+  PcdLib\r
 \r
 [Pcd]\r
-  gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds   ## SOMETIMES_CONSUMES\r
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds  ## SOMETIMES_CONSUMES\r
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress        ## SOMETIMES_CONSUMES\r