-/** @file
- CPU Register Table Library functions.
-
- Copyright (c) 2017, 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 <PiDxe.h>
-
-#include <Library/UefiBootServicesTableLib.h>
-
-#include "RegisterCpuFeatures.h"
-
-CPU_FEATURES_DATA mCpuFeaturesData = {0};
-static EFI_MP_SERVICES_PROTOCOL *mMpServices = NULL;
-
-/**
- Worker function to get CPU_FEATURES_DATA pointer.
-
- @return Pointer to CPU_FEATURES_DATA.
-**/
-CPU_FEATURES_DATA *
-GetCpuFeaturesData (
- VOID
- )
-{
- return &mCpuFeaturesData;
-}
-
-/**
- Worker function to get EFI_MP_SERVICES_PROTOCOL pointer.
-
- @return Pointer to EFI_MP_SERVICES_PROTOCOL.
-**/
-EFI_MP_SERVICES_PROTOCOL *
-GetMpProtocol (
- VOID
- )
-{
- EFI_STATUS Status;
-
- if (mMpServices == NULL) {
- //
- // Get MP Services Protocol
- //
- Status = gBS->LocateProtocol (
- &gEfiMpServiceProtocolGuid,
- NULL,
- (VOID **)&mMpServices
- );
- ASSERT_EFI_ERROR (Status);
- }
-
- ASSERT (mMpServices != NULL);
- return mMpServices;
-}
-
-/**
- Worker function to return processor index.
-
- @return The processor index.
-**/
-UINTN
-GetProcessorIndex (
- VOID
- )
-{
- EFI_STATUS Status;
- UINTN ProcessorIndex;
- EFI_MP_SERVICES_PROTOCOL *MpServices;
-
- MpServices = GetMpProtocol ();
- Status = MpServices->WhoAmI(MpServices, &ProcessorIndex);
- ASSERT_EFI_ERROR (Status);
- return ProcessorIndex;
-}
-
-/**
- Gets detailed 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_STATUS Status;
- EFI_MP_SERVICES_PROTOCOL *MpServices;
-
- MpServices = GetMpProtocol ();
- Status = MpServices->GetProcessorInfo (
- MpServices,
- 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_MP_SERVICES_PROTOCOL *MpServices;
-
- MpServices = GetMpProtocol ();
- //
- // Wakeup all APs
- //
- Status = MpServices->StartupAllAPs (
- MpServices,
- Procedure,
- FALSE,
- NULL,
- 0,
- NULL,
- 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_MP_SERVICES_PROTOCOL *MpServices;
-
- MpServices = GetMpProtocol ();
- //
- // Wakeup all APs
- //
- Status = MpServices->SwitchBSP (
- MpServices,
- 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_MP_SERVICES_PROTOCOL *MpServices;
-
- MpServices = GetMpProtocol ();
-
- //
- // Get the number of CPUs
- //
- Status = MpServices->GetNumberOfProcessors (
- MpServices,
- 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
- )
-{
- //
- // CpuS3DataDxe will do it.
- //
- ASSERT (FALSE);
- return NULL;
-}
-
-/**
- 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;
-
- Address = BASE_4GB - 1;
- AllocatePages = RegisterTable->AllocatedSize / EFI_PAGE_SIZE;
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- 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
- );
- //
- // RegisterTableEntry is allocated by gBS->AllocatePages() service.
- // So, gBS->FreePages() service is used to free it.
- //
- gBS->FreePages (
- RegisterTable->RegisterTableEntry,
- AllocatePages
- );
- }
-
- //
- // 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) 2017, 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 <PiDxe.h>\r
+\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#include "RegisterCpuFeatures.h"\r
+\r
+CPU_FEATURES_DATA mCpuFeaturesData = {0};\r
+EFI_MP_SERVICES_PROTOCOL *mCpuFeaturesMpServices = NULL;\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
+ return &mCpuFeaturesData;\r
+}\r
+\r
+/**\r
+ Worker function to get EFI_MP_SERVICES_PROTOCOL pointer.\r
+\r
+ @return Pointer to EFI_MP_SERVICES_PROTOCOL.\r
+**/\r
+EFI_MP_SERVICES_PROTOCOL *\r
+GetMpProtocol (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ if (mCpuFeaturesMpServices == NULL) {\r
+ //\r
+ // Get MP Services Protocol\r
+ //\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiMpServiceProtocolGuid,\r
+ NULL,\r
+ (VOID **)&mCpuFeaturesMpServices\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+ ASSERT (mCpuFeaturesMpServices != NULL);\r
+ return mCpuFeaturesMpServices;\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
+ UINTN ProcessorIndex;\r
+ EFI_MP_SERVICES_PROTOCOL *MpServices;\r
+\r
+ MpServices = GetMpProtocol ();\r
+ Status = MpServices->WhoAmI(MpServices, &ProcessorIndex);\r
+ ASSERT_EFI_ERROR (Status);\r
+ return ProcessorIndex;\r
+}\r
+\r
+/**\r
+ Gets detailed 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_STATUS Status;\r
+ EFI_MP_SERVICES_PROTOCOL *MpServices;\r
+\r
+ MpServices = GetMpProtocol ();\r
+ Status = MpServices->GetProcessorInfo (\r
+ MpServices,\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_MP_SERVICES_PROTOCOL *MpServices;\r
+\r
+ MpServices = GetMpProtocol ();\r
+ //\r
+ // Wakeup all APs\r
+ //\r
+ Status = MpServices->StartupAllAPs (\r
+ MpServices,\r
+ Procedure,\r
+ FALSE,\r
+ NULL,\r
+ 0,\r
+ NULL,\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_MP_SERVICES_PROTOCOL *MpServices;\r
+\r
+ MpServices = GetMpProtocol ();\r
+ //\r
+ // Wakeup all APs\r
+ //\r
+ Status = MpServices->SwitchBSP (\r
+ MpServices,\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_MP_SERVICES_PROTOCOL *MpServices;\r
+\r
+ MpServices = GetMpProtocol ();\r
+\r
+ //\r
+ // Get the number of CPUs\r
+ //\r
+ Status = MpServices->GetNumberOfProcessors (\r
+ MpServices,\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
+ //\r
+ // CpuS3DataDxe will do it.\r
+ //\r
+ ASSERT (FALSE);\r
+ return NULL;\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
+ Address = BASE_4GB - 1;\r
+ AllocatePages = RegisterTable->AllocatedSize / EFI_PAGE_SIZE;\r
+ Status = gBS->AllocatePages (\r
+ AllocateMaxAddress,\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
+ // RegisterTableEntry is allocated by gBS->AllocatePages() service.\r
+ // So, gBS->FreePages() service is used to free it.\r
+ //\r
+ gBS->FreePages (\r
+ RegisterTable->RegisterTableEntry,\r
+ AllocatePages\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