]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/CpuCommonFeaturesLib/Ppin.c
UefiCpuPkg/CpuCommonFeaturesLib: Correct the CPU location check
[mirror_edk2.git] / UefiCpuPkg / Library / CpuCommonFeaturesLib / Ppin.c
index 721470cdfe9c844e5f31b198ad8a3a33cfbb3879..3c4c1bc706ba5d5a4ab659ef19968b889bc7b79e 100644 (file)
@@ -2,18 +2,34 @@
   Protected Processor Inventory Number(PPIN) feature.\r
 \r
   Copyright (c) 2017 - 2018, 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
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include "CpuCommonFeatures.h"\r
 \r
+/**\r
+  Prepares for the data used by CPU feature detection and initialization.\r
+\r
+  @param[in]  NumberOfProcessors  The number of CPUs in the platform.\r
+\r
+  @return  Pointer to a buffer of CPU related configuration data.\r
+\r
+  @note This service could be called by BSP only.\r
+**/\r
+VOID *\r
+EFIAPI\r
+PpinGetConfigData (\r
+  IN UINTN               NumberOfProcessors\r
+  )\r
+{\r
+  VOID          *ConfigData;\r
+\r
+  ConfigData = AllocateZeroPool (sizeof (MSR_IVY_BRIDGE_PPIN_CTL_REGISTER) * NumberOfProcessors);\r
+  ASSERT (ConfigData != NULL);\r
+  return ConfigData;\r
+}\r
+\r
 /**\r
   Detects if Protected Processor Inventory Number feature supported on current\r
   processor.\r
@@ -40,6 +56,7 @@ PpinSupport (
   )\r
 {\r
   MSR_IVY_BRIDGE_PLATFORM_INFO_1_REGISTER    PlatformInfo;\r
+  MSR_IVY_BRIDGE_PPIN_CTL_REGISTER           *MsrPpinCtrl;\r
 \r
   if ((CpuInfo->DisplayFamily == 0x06) &&\r
       ((CpuInfo->DisplayModel == 0x3E) ||      // Xeon E5 V2\r
@@ -53,7 +70,12 @@ PpinSupport (
     // Check whether platform support this feature.\r
     //\r
     PlatformInfo.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_PLATFORM_INFO_1);\r
-    return (PlatformInfo.Bits.PPIN_CAP != 0);\r
+    if (PlatformInfo.Bits.PPIN_CAP != 0) {\r
+      MsrPpinCtrl = (MSR_IVY_BRIDGE_PPIN_CTL_REGISTER *) ConfigData;\r
+      ASSERT (MsrPpinCtrl != NULL);\r
+      MsrPpinCtrl[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_PPIN_CTL);\r
+      return TRUE;\r
+    }\r
   }\r
 \r
   return FALSE;\r
@@ -79,6 +101,7 @@ PpinSupport (
   @retval RETURN_DEVICE_ERROR  Device can't change state because it has been\r
                                locked.\r
 \r
+  @note This service could be called by BSP only.\r
 **/\r
 RETURN_STATUS\r
 EFIAPI\r
@@ -89,25 +112,52 @@ PpinInitialize (
   IN BOOLEAN                           State\r
   )\r
 {\r
-  MSR_IVY_BRIDGE_PPIN_CTL_REGISTER     MsrPpinCtrl;\r
+  MSR_IVY_BRIDGE_PPIN_CTL_REGISTER     *MsrPpinCtrl;\r
+\r
+  MsrPpinCtrl = (MSR_IVY_BRIDGE_PPIN_CTL_REGISTER *) ConfigData;\r
+  ASSERT (MsrPpinCtrl != NULL);\r
 \r
   //\r
-  // Check whether device already lock this register.\r
-  // If already locked, just base on the request state and\r
+  // Check whether processor already lock this register.\r
+  // If already locked, just based on the request state and\r
   // the current state to return the status.\r
   //\r
-  MsrPpinCtrl.Uint64 = AsmReadMsr64 (MSR_IVY_BRIDGE_PPIN_CTL);\r
-  if (MsrPpinCtrl.Bits.LockOut != 0) {\r
-    return MsrPpinCtrl.Bits.Enable_PPIN == State ? RETURN_SUCCESS : RETURN_DEVICE_ERROR;\r
+  if (MsrPpinCtrl[ProcessorNumber].Bits.LockOut != 0) {\r
+    return MsrPpinCtrl[ProcessorNumber].Bits.Enable_PPIN == State ? RETURN_SUCCESS : RETURN_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Support function already check the processor which support PPIN feature, so this function not need\r
+  // to check the processor again.\r
+  //\r
+  // The scope of the MSR_IVY_BRIDGE_PPIN_CTL is package level, only program MSR_IVY_BRIDGE_PPIN_CTL\r
+  // once for each package.\r
+  //\r
+  if ((CpuInfo->First.Thread == 0) || (CpuInfo->First.Core == 0)) {\r
+    return RETURN_SUCCESS;\r
+  }\r
+\r
+  if (State) {\r
+    //\r
+    // Enable and Unlock.\r
+    // According to SDM, once Enable_PPIN is set, attempt to write 1 to LockOut will cause #GP.\r
+    //\r
+    MsrPpinCtrl[ProcessorNumber].Bits.Enable_PPIN = 1;\r
+    MsrPpinCtrl[ProcessorNumber].Bits.LockOut = 0;\r
+  } else {\r
+    //\r
+    // Disable and Lock.\r
+    // According to SDM, writing 1 to LockOut is permitted only if Enable_PPIN is clear.\r
+    //\r
+    MsrPpinCtrl[ProcessorNumber].Bits.Enable_PPIN = 0;\r
+    MsrPpinCtrl[ProcessorNumber].Bits.LockOut = 1;\r
   }\r
 \r
-  CPU_REGISTER_TABLE_WRITE_FIELD (\r
+  CPU_REGISTER_TABLE_WRITE64 (\r
     ProcessorNumber,\r
     Msr,\r
     MSR_IVY_BRIDGE_PPIN_CTL,\r
-    MSR_IVY_BRIDGE_PPIN_CTL_REGISTER,\r
-    Bits.Enable_PPIN,\r
-    (State) ? 1 : 0\r
+    MsrPpinCtrl[ProcessorNumber].Uint64\r
     );\r
 \r
   return RETURN_SUCCESS;\r