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.kin...@intel.com<mailto:michael.d.kin...@intel.com>>

Index: Library/BaseXApicLib/BaseXApicLib.c
===================================================================
--- Library/BaseXApicLib/BaseXApicLib.c  (revision 17201)
+++ Library/BaseXApicLib/BaseXApicLib.c               (working copy)
@@ -3,7 +3,7 @@
   This local APIC library instance supports xAPIC mode only.
-  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD 
License
   which accompanies this distribution.  The full text of the license may be 
found at
@@ -21,6 +21,7 @@
#include <Library/LocalApicLib.h>
#include <Library/IoLib.h>
#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
 //
// Library internal functions
@@ -27,6 +28,33 @@
//
 /**
+  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.
@@ -38,8 +66,16 @@
   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)) +
@@ -60,10 +96,17 @@
   IN UINTN                BaseAddress
   )
{
-  MSR_IA32_APIC_BASE ApicBaseMsr;
+  MSR_IA32_APIC_BASE  ApicBaseMsr;
   ASSERT ((BaseAddress & (SIZE_4KB - 1)) == 0);
+  if (!LocalApicBaseAddressMsrSupported ()) {
+    //
+    // Ignore set request if the CPU does not support APIC Base Address MSR
+    //
+    return;
+  }
+
   ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
   ApicBaseMsr.Bits.ApicBaseLow  = (UINT32) (BaseAddress >> 12);
@@ -202,14 +245,19 @@
{
   DEBUG_CODE (
     {
-      MSR_IA32_APIC_BASE ApicBaseMsr;
+      MSR_IA32_APIC_BASE  ApicBaseMsr;
-      ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
       //
-      // Local APIC should have been enabled
+      // Check to see if the CPU supports the APIC Base Address MSR
       //
-      ASSERT (ApicBaseMsr.Bits.En != 0);
-      ASSERT (ApicBaseMsr.Bits.Extd == 0);
+      if (LocalApicBaseAddressMsrSupported ()) {
+        ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE_ADDRESS);
+        //
+        // Local APIC should have been enabled
+        //
+        ASSERT (ApicBaseMsr.Bits.En != 0);
+        ASSERT (ApicBaseMsr.Bits.Extd == 0);
+      }
     }
   );
   return LOCAL_APIC_MODE_XAPIC;
Index: Library/BaseXApicLib/BaseXApicLib.inf
===================================================================
--- Library/BaseXApicLib/BaseXApicLib.inf               (revision 17201)
+++ Library/BaseXApicLib/BaseXApicLib.inf            (working copy)
@@ -21,7 +21,7 @@
   MODULE_UNI_FILE                = BaseXApicLib.uni
   FILE_GUID                      = D87CA0A8-1AC2-439b-90F8-EF4A2AC88DAF
   MODULE_TYPE                    = BASE
-  VERSION_STRING                 = 1.0
+  VERSION_STRING                 = 1.1
   LIBRARY_CLASS                  = LocalApicLib

 #
@@ -42,6 +42,8 @@
   DebugLib
   TimerLib
   IoLib
+  PcdLib
 [Pcd]
-  gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds   ## 
SOMETIMES_CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuInitIpiDelayInMicroSeconds  ## 
SOMETIMES_CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress        ## 
SOMETIMES_CONSUMES
Index: Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
===================================================================
--- Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c        (revision 17201)
+++ Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c      (working copy)
@@ -22,6 +22,7 @@
#include <Library/LocalApicLib.h>
#include <Library/IoLib.h>
#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
 //
// Library internal functions
@@ -28,6 +29,33 @@
//
 /**
+  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 @@
   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 @@
   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,8 +300,15 @@
   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);
   //
   // Local APIC should have been enabled
@@ -288,9 +338,16 @@
   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) {
     switch (ApicMode) {
Index: Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
===================================================================
--- Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf     (revision 17201)
+++ Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf   (working copy)
@@ -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
------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud 
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to