]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRegisterCpuFeaturesLib.c
UefiCpuPkg: Apply uncrustify changes
[mirror_edk2.git] / UefiCpuPkg / Library / RegisterCpuFeaturesLib / PeiRegisterCpuFeaturesLib.c
index 8fde742dce3719e0e4531a28785dfa800db5fca0..d4c528b3e9c26d4985c0fa6a1c6d024fee1fe7ce 100644 (file)
-/** @file
-  CPU Register Table Library functions.
-
-  Copyright (c) 2016, 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
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include <PiPei.h>
-
-#include <Library/HobLib.h>
-#include <Library/PeiServicesLib.h>
-#include <Library/PeiServicesTablePointerLib.h>
-#include <Ppi/MpServices.h>
-#include "RegisterCpuFeatures.h"
-
-#define REGISTER_CPU_FEATURES_GUID \
-  { \
-    0xa694c467, 0x697a, 0x446b, { 0xb9, 0x29, 0x5b, 0x14, 0xa0, 0xcf, 0x39, 0xf } \
-  }
-
-EFI_GUID mRegisterCpuFeaturesHobGuid = REGISTER_CPU_FEATURES_GUID;
-
-/**
-  Worker function to get CPU_FEATURES_DATA pointer.
-
-  @return Pointer to CPU_FEATURES_DATA.
-**/
-CPU_FEATURES_DATA *
-GetCpuFeaturesData (
-  VOID
-  )
-{
-  CPU_FEATURES_DATA       *CpuInitData;
-  EFI_HOB_GUID_TYPE       *GuidHob;
-  VOID                    *DataInHob;
-  UINT64                  Data64;
-
-  CpuInitData = NULL;
-  GuidHob = GetFirstGuidHob (&mRegisterCpuFeaturesHobGuid);
-  if (GuidHob != NULL) {
-    DataInHob = GET_GUID_HOB_DATA (GuidHob);
-    CpuInitData = (CPU_FEATURES_DATA *) (*(UINTN *) DataInHob);
-    ASSERT (CpuInitData != NULL);
-  } else {
-    CpuInitData = AllocateZeroPool (sizeof (CPU_FEATURES_DATA));
-    ASSERT (CpuInitData != NULL);
-    //
-    // Build location of CPU MP DATA buffer in HOB
-    //
-    Data64 = (UINT64) (UINTN) CpuInitData;
-    BuildGuidDataHob (
-      &mRegisterCpuFeaturesHobGuid,
-      (VOID *) &Data64,
-      sizeof (UINT64)
-      );
-  }
-
-  return CpuInitData;
-}
-
-/**
-  Worker function to get MP PPI service pointer.
-
-  @return PEI PPI service pointer.
-**/
-EFI_PEI_MP_SERVICES_PPI *
-GetMpPpi (
-  VOID
-  )
-{
-  EFI_STATUS                 Status;
-  EFI_PEI_MP_SERVICES_PPI    *CpuMpPpi;
-
-  //
-  // Get MP Services Protocol
-  //
-  Status = PeiServicesLocatePpi (
-             &gEfiPeiMpServicesPpiGuid,
-             0,
-             NULL,
-             (VOID **)&CpuMpPpi
-             );
-  ASSERT_EFI_ERROR (Status);
-  return CpuMpPpi;
-}
-
-/**
-  Worker function to return processor index.
-
-  @return  The processor index.
-**/
-UINTN
-GetProcessorIndex (
-  VOID
-  )
-{
-  EFI_STATUS                 Status;
-  EFI_PEI_MP_SERVICES_PPI    *CpuMpPpi;
-  UINTN                      ProcessorIndex;
-
-  CpuMpPpi = GetMpPpi ();
-
-  Status = CpuMpPpi->WhoAmI(GetPeiServicesTablePointer (), CpuMpPpi, &ProcessorIndex);
-  ASSERT_EFI_ERROR (Status);
-  return ProcessorIndex;
-}
-
-/**
-  Worker function to MP-related information on the requested processor at the
-  instant this call is made.
-
-  @param[in]  ProcessorNumber       The handle number of processor.
-  @param[out] ProcessorInfoBuffer   A pointer to the buffer where information for
-                                    the requested processor is deposited.
-
-  @return Status of MpServices->GetProcessorInfo().
-**/
-EFI_STATUS
-GetProcessorInformation (
-  IN  UINTN                            ProcessorNumber,
-  OUT EFI_PROCESSOR_INFORMATION        *ProcessorInfoBuffer
-  )
-{
-  EFI_PEI_MP_SERVICES_PPI    *CpuMpPpi;
-  EFI_STATUS                 Status;
-
-  CpuMpPpi = GetMpPpi ();
-  Status = CpuMpPpi->GetProcessorInfo (
-               GetPeiServicesTablePointer(),
-               CpuMpPpi,
-               ProcessorNumber,
-               ProcessorInfoBuffer
-               );
-  return Status;
-}
-
-/**
-  Worker function to execute a caller provided function on all enabled APs.
-
-  @param[in]  Procedure               A pointer to the function to be run on
-                                      enabled APs of the system.
-**/
-VOID
-StartupAPsWorker (
-  IN  EFI_AP_PROCEDURE                 Procedure
-  )
-{
-  EFI_STATUS                           Status;
-  EFI_PEI_MP_SERVICES_PPI              *CpuMpPpi;
-
-  //
-  // Get MP Services Protocol
-  //
-  Status = PeiServicesLocatePpi (
-             &gEfiPeiMpServicesPpiGuid,
-             0,
-             NULL,
-             (VOID **)&CpuMpPpi
-             );
-  ASSERT_EFI_ERROR (Status);
-
-  //
-  // Wakeup all APs for data collection.
-  //
-  Status = CpuMpPpi->StartupAllAPs (
-                 GetPeiServicesTablePointer (),
-                 CpuMpPpi,
-                 Procedure,
-                 FALSE,
-                 0,
-                 NULL
-                 );
-  ASSERT_EFI_ERROR (Status);
-}
-
-/**
-  Worker function to switch the requested AP to be the BSP from that point onward.
-
-  @param[in] ProcessorNumber   The handle number of AP that is to become the new BSP.
-**/
-VOID
-SwitchNewBsp (
-  IN  UINTN                            ProcessorNumber
-  )
-{
-  EFI_STATUS                           Status;
-  EFI_PEI_MP_SERVICES_PPI              *CpuMpPpi;
-
-  //
-  // Get MP Services Protocol
-  //
-  Status = PeiServicesLocatePpi (
-             &gEfiPeiMpServicesPpiGuid,
-             0,
-             NULL,
-             (VOID **)&CpuMpPpi
-             );
-  ASSERT_EFI_ERROR (Status);
-
-  //
-  // Wakeup all APs for data collection.
-  //
-  Status = CpuMpPpi->SwitchBSP (
-                 GetPeiServicesTablePointer (),
-                 CpuMpPpi,
-                 ProcessorNumber,
-                 TRUE
-                 );
-  ASSERT_EFI_ERROR (Status);
-}
-
-/**
-  Worker function to retrieve the number of logical processor in the platform.
-
-  @param[out] NumberOfCpus                Pointer to the total number of logical
-                                          processors in the system, including the BSP
-                                          and disabled APs.
-  @param[out] NumberOfEnabledProcessors   Pointer to the number of enabled logical
-                                          processors that exist in system, including
-                                          the BSP.
-**/
-VOID
-GetNumberOfProcessor (
-  OUT UINTN                            *NumberOfCpus,
-  OUT UINTN                            *NumberOfEnabledProcessors
-  )
-{
-  EFI_STATUS                 Status;
-  EFI_PEI_MP_SERVICES_PPI    *CpuMpPpi;
-
-  //
-  // Get MP Services Protocol
-  //
-  Status = PeiServicesLocatePpi (
-             &gEfiPeiMpServicesPpiGuid,
-             0,
-             NULL,
-             (VOID **)&CpuMpPpi
-             );
-  ASSERT_EFI_ERROR (Status);
-
-  //
-  // Get the number of CPUs
-  //
-  Status = CpuMpPpi->GetNumberOfProcessors (
-                         GetPeiServicesTablePointer (),
-                         CpuMpPpi,
-                         NumberOfCpus,
-                         NumberOfEnabledProcessors
-                         );
-  ASSERT_EFI_ERROR (Status);
-}
-
-/**
-  Allocates ACPI NVS memory to save ACPI_CPU_DATA.
-
-  @return  Pointer to allocated ACPI_CPU_DATA.
-**/
-ACPI_CPU_DATA *
-AllocateAcpiCpuData (
-  VOID
-  )
-{
-  EFI_STATUS                           Status;
-  EFI_PEI_MP_SERVICES_PPI              *CpuMpPpi;
-  UINTN                                NumberOfCpus;
-  UINTN                                NumberOfEnabledProcessors;
-  ACPI_CPU_DATA                        *AcpiCpuData;
-  EFI_PHYSICAL_ADDRESS                 Address;
-  UINTN                                TableSize;
-  CPU_REGISTER_TABLE                   *RegisterTable;
-  UINTN                                Index;
-  EFI_PROCESSOR_INFORMATION            ProcessorInfoBuffer;
-
-  Status = PeiServicesAllocatePages (
-             EfiACPIMemoryNVS,
-             EFI_SIZE_TO_PAGES (sizeof (ACPI_CPU_DATA)),
-             &Address
-             );
-  ASSERT_EFI_ERROR (Status);
-  AcpiCpuData = (ACPI_CPU_DATA *) (UINTN) Address;
-  ASSERT (AcpiCpuData != NULL);
-
-  //
-  // Get MP Services Protocol
-  //
-  Status = PeiServicesLocatePpi (
-             &gEfiPeiMpServicesPpiGuid,
-             0,
-             NULL,
-             (VOID **)&CpuMpPpi
-             );
-  ASSERT_EFI_ERROR (Status);
-
-  //
-  // Get the number of CPUs
-  //
-  Status = CpuMpPpi->GetNumberOfProcessors (
-                         GetPeiServicesTablePointer (),
-                         CpuMpPpi,
-                         &NumberOfCpus,
-                         &NumberOfEnabledProcessors
-                         );
-  ASSERT_EFI_ERROR (Status);
-  AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus;
-
-  //
-  // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs
-  //
-  TableSize = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE);
-  Status = PeiServicesAllocatePages (
-             EfiACPIMemoryNVS,
-             EFI_SIZE_TO_PAGES (TableSize),
-             &Address
-             );
-  ASSERT_EFI_ERROR (Status);
-  RegisterTable = (CPU_REGISTER_TABLE *) (UINTN) Address;
-
-  for (Index = 0; Index < NumberOfCpus; Index++) {
-    Status = CpuMpPpi->GetProcessorInfo (
-                         GetPeiServicesTablePointer (),
-                         CpuMpPpi,
-                         Index,
-                         &ProcessorInfoBuffer
-                         );
-    ASSERT_EFI_ERROR (Status);
-
-    RegisterTable[Index].InitialApicId      = (UINT32)ProcessorInfoBuffer.ProcessorId;
-    RegisterTable[Index].TableLength        = 0;
-    RegisterTable[Index].AllocatedSize      = 0;
-    RegisterTable[Index].RegisterTableEntry = 0;
-
-    RegisterTable[NumberOfCpus + Index].InitialApicId      = (UINT32)ProcessorInfoBuffer.ProcessorId;
-    RegisterTable[NumberOfCpus + Index].TableLength        = 0;
-    RegisterTable[NumberOfCpus + Index].AllocatedSize      = 0;
-    RegisterTable[NumberOfCpus + Index].RegisterTableEntry = 0;
-  }
-  AcpiCpuData->RegisterTable           = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable;
-  AcpiCpuData->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus);
-
-  return AcpiCpuData;
-}
-
-/**
-  Enlarges CPU register table for each processor.
-
-  @param[in, out]  RegisterTable   Pointer processor's CPU register table
-**/
-VOID
-EnlargeRegisterTable (
-  IN OUT CPU_REGISTER_TABLE            *RegisterTable
-  )
-{
-  EFI_STATUS                           Status;
-  EFI_PHYSICAL_ADDRESS                 Address;
-  UINTN                                AllocatePages;
-
-  AllocatePages = RegisterTable->AllocatedSize / EFI_PAGE_SIZE;
-  Status = PeiServicesAllocatePages (
-             EfiACPIMemoryNVS,
-             AllocatePages + 1,
-             &Address
-             );
-  ASSERT_EFI_ERROR (Status);
-
-  //
-  // If there are records existing in the register table, then copy its contents
-  // to new region and free the old one.
-  //
-  if (RegisterTable->AllocatedSize > 0) {
-    CopyMem (
-      (VOID *) (UINTN) Address,
-      (VOID *) (UINTN) RegisterTable->RegisterTableEntry,
-      RegisterTable->AllocatedSize
-      );
-  }
-
-  //
-  // Adjust the allocated size and register table base address.
-  //
-  RegisterTable->AllocatedSize += EFI_PAGE_SIZE;
-  RegisterTable->RegisterTableEntry = Address;
-}
+/** @file\r
+  CPU Register Table Library functions.\r
+\r
+  Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+\r
+#include <Library/HobLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/PeiServicesTablePointerLib.h>\r
+#include <Ppi/MpServices2.h>\r
+\r
+#include "RegisterCpuFeatures.h"\r
+\r
+#define REGISTER_CPU_FEATURES_GUID \\r
+  { \\r
+    0xa694c467, 0x697a, 0x446b, { 0xb9, 0x29, 0x5b, 0x14, 0xa0, 0xcf, 0x39, 0xf } \\r
+  }\r
+\r
+EFI_GUID  mRegisterCpuFeaturesHobGuid = REGISTER_CPU_FEATURES_GUID;\r
+\r
+/**\r
+  Worker function to get CPU_FEATURES_DATA pointer.\r
+\r
+  @return Pointer to CPU_FEATURES_DATA.\r
+**/\r
+CPU_FEATURES_DATA *\r
+GetCpuFeaturesData (\r
+  VOID\r
+  )\r
+{\r
+  CPU_FEATURES_DATA  *CpuInitData;\r
+  EFI_HOB_GUID_TYPE  *GuidHob;\r
+  VOID               *DataInHob;\r
+  UINT64             Data64;\r
+\r
+  CpuInitData = NULL;\r
+  GuidHob     = GetFirstGuidHob (&mRegisterCpuFeaturesHobGuid);\r
+  if (GuidHob != NULL) {\r
+    DataInHob   = GET_GUID_HOB_DATA (GuidHob);\r
+    CpuInitData = (CPU_FEATURES_DATA *)(*(UINTN *)DataInHob);\r
+    ASSERT (CpuInitData != NULL);\r
+  } else {\r
+    CpuInitData = AllocateZeroPool (sizeof (CPU_FEATURES_DATA));\r
+    ASSERT (CpuInitData != NULL);\r
+    //\r
+    // Build location of CPU MP DATA buffer in HOB\r
+    //\r
+    Data64 = (UINT64)(UINTN)CpuInitData;\r
+    BuildGuidDataHob (\r
+      &mRegisterCpuFeaturesHobGuid,\r
+      (VOID *)&Data64,\r
+      sizeof (UINT64)\r
+      );\r
+  }\r
+\r
+  return CpuInitData;\r
+}\r
+\r
+/**\r
+  Worker function to get MP PPI service pointer.\r
+\r
+  @return MP_SERVICES variable.\r
+**/\r
+MP_SERVICES\r
+GetMpService (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS   Status;\r
+  MP_SERVICES  MpService;\r
+\r
+  //\r
+  // Get MP Services2 Ppi\r
+  //\r
+  Status = PeiServicesLocatePpi (\r
+             &gEdkiiPeiMpServices2PpiGuid,\r
+             0,\r
+             NULL,\r
+             (VOID **)&MpService.Ppi\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+  return MpService;\r
+}\r
+\r
+/**\r
+  Worker function to return processor index.\r
+\r
+  @param  CpuFeaturesData    Cpu Feature Data structure.\r
+\r
+  @return  The processor index.\r
+**/\r
+UINTN\r
+GetProcessorIndex (\r
+  IN CPU_FEATURES_DATA  *CpuFeaturesData\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EDKII_PEI_MP_SERVICES2_PPI  *CpuMp2Ppi;\r
+  UINTN                       ProcessorIndex;\r
+\r
+  CpuMp2Ppi = CpuFeaturesData->MpService.Ppi;\r
+\r
+  //\r
+  // For two reasons which use NULL for WhoAmI:\r
+  // 1. This function will be called by APs and AP should not use PeiServices Table\r
+  // 2. Check WhoAmI implementation, this parameter will not be used.\r
+  //\r
+  Status = CpuMp2Ppi->WhoAmI (CpuMp2Ppi, &ProcessorIndex);\r
+  ASSERT_EFI_ERROR (Status);\r
+  return ProcessorIndex;\r
+}\r
+\r
+/**\r
+  Worker function to MP-related information on the requested processor at the\r
+  instant this call is made.\r
+\r
+  @param[in]  ProcessorNumber       The handle number of processor.\r
+  @param[out] ProcessorInfoBuffer   A pointer to the buffer where information for\r
+                                    the requested processor is deposited.\r
+\r
+  @return Status of MpServices->GetProcessorInfo().\r
+**/\r
+EFI_STATUS\r
+GetProcessorInformation (\r
+  IN  UINTN                      ProcessorNumber,\r
+  OUT EFI_PROCESSOR_INFORMATION  *ProcessorInfoBuffer\r
+  )\r
+{\r
+  EDKII_PEI_MP_SERVICES2_PPI  *CpuMp2Ppi;\r
+  EFI_STATUS                  Status;\r
+  CPU_FEATURES_DATA           *CpuFeaturesData;\r
+\r
+  CpuFeaturesData = GetCpuFeaturesData ();\r
+  CpuMp2Ppi       = CpuFeaturesData->MpService.Ppi;\r
+\r
+  Status = CpuMp2Ppi->GetProcessorInfo (\r
+                        CpuMp2Ppi,\r
+                        ProcessorNumber,\r
+                        ProcessorInfoBuffer\r
+                        );\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Worker function to execute a caller provided function on all enabled APs.\r
+\r
+  @param[in]  Procedure               A pointer to the function to be run on\r
+                                      enabled APs of the system.\r
+  @param[in]  MpEvent                 The Event used to sync the result.\r
+\r
+**/\r
+VOID\r
+StartupAllAPsWorker (\r
+  IN  EFI_AP_PROCEDURE  Procedure,\r
+  IN  EFI_EVENT         MpEvent\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EDKII_PEI_MP_SERVICES2_PPI  *CpuMp2Ppi;\r
+  CPU_FEATURES_DATA           *CpuFeaturesData;\r
+\r
+  CpuFeaturesData = GetCpuFeaturesData ();\r
+  CpuMp2Ppi       = CpuFeaturesData->MpService.Ppi;\r
+\r
+  //\r
+  // Wakeup all APs for data collection.\r
+  //\r
+  Status = CpuMp2Ppi->StartupAllAPs (\r
+                        CpuMp2Ppi,\r
+                        Procedure,\r
+                        FALSE,\r
+                        0,\r
+                        CpuFeaturesData\r
+                        );\r
+  ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+/**\r
+  Worker function to execute a caller provided function on all enabled CPUs.\r
+\r
+  @param[in]  Procedure               A pointer to the function to be run on\r
+                                      enabled CPUs of the system.\r
+\r
+**/\r
+VOID\r
+StartupAllCPUsWorker (\r
+  IN  EFI_AP_PROCEDURE  Procedure\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EDKII_PEI_MP_SERVICES2_PPI  *CpuMp2Ppi;\r
+  CPU_FEATURES_DATA           *CpuFeaturesData;\r
+\r
+  CpuFeaturesData = GetCpuFeaturesData ();\r
+\r
+  //\r
+  // Get MP Services2 Ppi\r
+  //\r
+  CpuMp2Ppi = CpuFeaturesData->MpService.Ppi;\r
+  Status    = CpuMp2Ppi->StartupAllCPUs (\r
+                           CpuMp2Ppi,\r
+                           Procedure,\r
+                           0,\r
+                           CpuFeaturesData\r
+                           );\r
+  ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+/**\r
+  Worker function to switch the requested AP to be the BSP from that point onward.\r
+\r
+  @param[in] ProcessorNumber   The handle number of AP that is to become the new BSP.\r
+**/\r
+VOID\r
+SwitchNewBsp (\r
+  IN  UINTN  ProcessorNumber\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EDKII_PEI_MP_SERVICES2_PPI  *CpuMp2Ppi;\r
+  CPU_FEATURES_DATA           *CpuFeaturesData;\r
+\r
+  CpuFeaturesData = GetCpuFeaturesData ();\r
+  CpuMp2Ppi       = CpuFeaturesData->MpService.Ppi;\r
+\r
+  //\r
+  // Wakeup all APs for data collection.\r
+  //\r
+  Status = CpuMp2Ppi->SwitchBSP (\r
+                        CpuMp2Ppi,\r
+                        ProcessorNumber,\r
+                        TRUE\r
+                        );\r
+  ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+/**\r
+  Worker function to retrieve the number of logical processor in the platform.\r
+\r
+  @param[out] NumberOfCpus                Pointer to the total number of logical\r
+                                          processors in the system, including the BSP\r
+                                          and disabled APs.\r
+  @param[out] NumberOfEnabledProcessors   Pointer to the number of enabled logical\r
+                                          processors that exist in system, including\r
+                                          the BSP.\r
+**/\r
+VOID\r
+GetNumberOfProcessor (\r
+  OUT UINTN  *NumberOfCpus,\r
+  OUT UINTN  *NumberOfEnabledProcessors\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EDKII_PEI_MP_SERVICES2_PPI  *CpuMp2Ppi;\r
+  CPU_FEATURES_DATA           *CpuFeaturesData;\r
+\r
+  CpuFeaturesData = GetCpuFeaturesData ();\r
+  CpuMp2Ppi       = CpuFeaturesData->MpService.Ppi;\r
+\r
+  //\r
+  // Get the number of CPUs\r
+  //\r
+  Status = CpuMp2Ppi->GetNumberOfProcessors (\r
+                        CpuMp2Ppi,\r
+                        NumberOfCpus,\r
+                        NumberOfEnabledProcessors\r
+                        );\r
+  ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+/**\r
+  Performs CPU features Initialization.\r
+\r
+  This service will invoke MP service to perform CPU features\r
+  initialization on BSP/APs per user configuration.\r
+\r
+  @note This service could be called by BSP only.\r
+**/\r
+VOID\r
+EFIAPI\r
+CpuFeaturesInitialize (\r
+  VOID\r
+  )\r
+{\r
+  CPU_FEATURES_DATA  *CpuFeaturesData;\r
+  UINTN              OldBspNumber;\r
+\r
+  CpuFeaturesData = GetCpuFeaturesData ();\r
+\r
+  OldBspNumber               = GetProcessorIndex (CpuFeaturesData);\r
+  CpuFeaturesData->BspNumber = OldBspNumber;\r
+\r
+  //\r
+  // Start to program register for all CPUs.\r
+  //\r
+  StartupAllCPUsWorker (SetProcessorRegister);\r
+\r
+  //\r
+  // Switch to new BSP if required\r
+  //\r
+  if (CpuFeaturesData->BspNumber != OldBspNumber) {\r
+    SwitchNewBsp (CpuFeaturesData->BspNumber);\r
+  }\r
+}\r