-/** @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] NumberOfProcessors 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, 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
+\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/MpServices.h>\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 PEI PPI service pointer.\r
+**/\r
+EFI_PEI_MP_SERVICES_PPI *\r
+GetMpPpi (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PEI_MP_SERVICES_PPI *CpuMpPpi;\r
+\r
+ //\r
+ // Get MP Services Protocol\r
+ //\r
+ Status = PeiServicesLocatePpi (\r
+ &gEfiPeiMpServicesPpiGuid,\r
+ 0,\r
+ NULL,\r
+ (VOID **)&CpuMpPpi\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ return CpuMpPpi;\r
+}\r
+\r
+/**\r
+ Worker function to return processor index.\r
+\r
+ @return The processor index.\r
+**/\r
+UINTN\r
+GetProcessorIndex (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PEI_MP_SERVICES_PPI *CpuMpPpi;\r
+ UINTN ProcessorIndex;\r
+\r
+ CpuMpPpi = GetMpPpi ();\r
+\r
+ Status = CpuMpPpi->WhoAmI(GetPeiServicesTablePointer (), CpuMpPpi, &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
+ EFI_PEI_MP_SERVICES_PPI *CpuMpPpi;\r
+ EFI_STATUS Status;\r
+\r
+ CpuMpPpi = GetMpPpi ();\r
+ Status = CpuMpPpi->GetProcessorInfo (\r
+ GetPeiServicesTablePointer(),\r
+ CpuMpPpi,\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
+**/\r
+VOID\r
+StartupAPsWorker (\r
+ IN EFI_AP_PROCEDURE Procedure\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PEI_MP_SERVICES_PPI *CpuMpPpi;\r
+\r
+ //\r
+ // Get MP Services Protocol\r
+ //\r
+ Status = PeiServicesLocatePpi (\r
+ &gEfiPeiMpServicesPpiGuid,\r
+ 0,\r
+ NULL,\r
+ (VOID **)&CpuMpPpi\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Wakeup all APs for data collection.\r
+ //\r
+ Status = CpuMpPpi->StartupAllAPs (\r
+ GetPeiServicesTablePointer (),\r
+ CpuMpPpi,\r
+ Procedure,\r
+ FALSE,\r
+ 0,\r
+ NULL\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
+ EFI_PEI_MP_SERVICES_PPI *CpuMpPpi;\r
+\r
+ //\r
+ // Get MP Services Protocol\r
+ //\r
+ Status = PeiServicesLocatePpi (\r
+ &gEfiPeiMpServicesPpiGuid,\r
+ 0,\r
+ NULL,\r
+ (VOID **)&CpuMpPpi\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Wakeup all APs for data collection.\r
+ //\r
+ Status = CpuMpPpi->SwitchBSP (\r
+ GetPeiServicesTablePointer (),\r
+ CpuMpPpi,\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
+ EFI_PEI_MP_SERVICES_PPI *CpuMpPpi;\r
+\r
+ //\r
+ // Get MP Services Protocol\r
+ //\r
+ Status = PeiServicesLocatePpi (\r
+ &gEfiPeiMpServicesPpiGuid,\r
+ 0,\r
+ NULL,\r
+ (VOID **)&CpuMpPpi\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Get the number of CPUs\r
+ //\r
+ Status = CpuMpPpi->GetNumberOfProcessors (\r
+ GetPeiServicesTablePointer (),\r
+ CpuMpPpi,\r
+ NumberOfCpus,\r
+ NumberOfEnabledProcessors\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+/**\r
+ Allocates ACPI NVS memory to save ACPI_CPU_DATA.\r
+\r
+ @return Pointer to allocated ACPI_CPU_DATA.\r
+**/\r
+ACPI_CPU_DATA *\r
+AllocateAcpiCpuData (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PEI_MP_SERVICES_PPI *CpuMpPpi;\r
+ UINTN NumberOfCpus;\r
+ UINTN NumberOfEnabledProcessors;\r
+ ACPI_CPU_DATA *AcpiCpuData;\r
+ EFI_PHYSICAL_ADDRESS Address;\r
+ UINTN TableSize;\r
+ CPU_REGISTER_TABLE *RegisterTable;\r
+ UINTN Index;\r
+ EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer;\r
+\r
+ Status = PeiServicesAllocatePages (\r
+ EfiACPIMemoryNVS,\r
+ EFI_SIZE_TO_PAGES (sizeof (ACPI_CPU_DATA)),\r
+ &Address\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ AcpiCpuData = (ACPI_CPU_DATA *) (UINTN) Address;\r
+ ASSERT (AcpiCpuData != NULL);\r
+\r
+ //\r
+ // Get MP Services Protocol\r
+ //\r
+ Status = PeiServicesLocatePpi (\r
+ &gEfiPeiMpServicesPpiGuid,\r
+ 0,\r
+ NULL,\r
+ (VOID **)&CpuMpPpi\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Get the number of CPUs\r
+ //\r
+ Status = CpuMpPpi->GetNumberOfProcessors (\r
+ GetPeiServicesTablePointer (),\r
+ CpuMpPpi,\r
+ &NumberOfCpus,\r
+ &NumberOfEnabledProcessors\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ AcpiCpuData->NumberOfCpus = (UINT32)NumberOfCpus;\r
+\r
+ //\r
+ // Allocate buffer for empty RegisterTable and PreSmmInitRegisterTable for all CPUs\r
+ //\r
+ TableSize = 2 * NumberOfCpus * sizeof (CPU_REGISTER_TABLE);\r
+ Status = PeiServicesAllocatePages (\r
+ EfiACPIMemoryNVS,\r
+ EFI_SIZE_TO_PAGES (TableSize),\r
+ &Address\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ RegisterTable = (CPU_REGISTER_TABLE *) (UINTN) Address;\r
+\r
+ for (Index = 0; Index < NumberOfCpus; Index++) {\r
+ Status = CpuMpPpi->GetProcessorInfo (\r
+ GetPeiServicesTablePointer (),\r
+ CpuMpPpi,\r
+ Index,\r
+ &ProcessorInfoBuffer\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ RegisterTable[Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
+ RegisterTable[Index].TableLength = 0;\r
+ RegisterTable[Index].AllocatedSize = 0;\r
+ RegisterTable[Index].RegisterTableEntry = 0;\r
+\r
+ RegisterTable[NumberOfCpus + Index].InitialApicId = (UINT32)ProcessorInfoBuffer.ProcessorId;\r
+ RegisterTable[NumberOfCpus + Index].TableLength = 0;\r
+ RegisterTable[NumberOfCpus + Index].AllocatedSize = 0;\r
+ RegisterTable[NumberOfCpus + Index].RegisterTableEntry = 0;\r
+ }\r
+ AcpiCpuData->RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTable;\r
+ AcpiCpuData->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)(RegisterTable + NumberOfCpus);\r
+\r
+ return AcpiCpuData;\r
+}\r
+\r
+/**\r
+ Enlarges CPU register table for each processor.\r
+\r
+ @param[in, out] RegisterTable Pointer processor's CPU register table\r
+**/\r
+VOID\r
+EnlargeRegisterTable (\r
+ IN OUT CPU_REGISTER_TABLE *RegisterTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PHYSICAL_ADDRESS Address;\r
+ UINTN AllocatePages;\r
+\r
+ AllocatePages = RegisterTable->AllocatedSize / EFI_PAGE_SIZE;\r
+ Status = PeiServicesAllocatePages (\r
+ EfiACPIMemoryNVS,\r
+ AllocatePages + 1,\r
+ &Address\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // If there are records existing in the register table, then copy its contents\r
+ // to new region and free the old one.\r
+ //\r
+ if (RegisterTable->AllocatedSize > 0) {\r
+ CopyMem (\r
+ (VOID *) (UINTN) Address,\r
+ (VOID *) (UINTN) RegisterTable->RegisterTableEntry,\r
+ RegisterTable->AllocatedSize\r
+ );\r
+ }\r
+\r
+ //\r
+ // Adjust the allocated size and register table base address.\r
+ //\r
+ RegisterTable->AllocatedSize += EFI_PAGE_SIZE;\r
+ RegisterTable->RegisterTableEntry = Address;\r
+}\r