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
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include <PiDxe.h>\r
\r
#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.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
Worker function to get EFI_MP_SERVICES_PROTOCOL pointer.\r
\r
- @return Pointer to EFI_MP_SERVICES_PROTOCOL.\r
+ @return MP_SERVICES variable.\r
**/\r
-EFI_MP_SERVICES_PROTOCOL *\r
-GetMpProtocol (\r
+MP_SERVICES\r
+GetMpService (\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
+ EFI_STATUS Status;\r
+ MP_SERVICES MpService;\r
\r
- ASSERT (mCpuFeaturesMpServices != NULL);\r
- return mCpuFeaturesMpServices;\r
+ //\r
+ // Get MP Services Protocol\r
+ //\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiMpServiceProtocolGuid,\r
+ NULL,\r
+ (VOID **)&MpService.Protocol\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\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
- VOID\r
+ IN CPU_FEATURES_DATA *CpuFeaturesData\r
)\r
{\r
EFI_STATUS Status;\r
UINTN ProcessorIndex;\r
EFI_MP_SERVICES_PROTOCOL *MpServices;\r
\r
- MpServices = GetMpProtocol ();\r
+ MpServices = CpuFeaturesData->MpService.Protocol;\r
Status = MpServices->WhoAmI(MpServices, &ProcessorIndex);\r
ASSERT_EFI_ERROR (Status);\r
return ProcessorIndex;\r
{\r
EFI_STATUS Status;\r
EFI_MP_SERVICES_PROTOCOL *MpServices;\r
+ CPU_FEATURES_DATA *CpuFeaturesData;\r
+\r
+ CpuFeaturesData = GetCpuFeaturesData ();\r
+ MpServices = CpuFeaturesData->MpService.Protocol;\r
\r
- MpServices = GetMpProtocol ();\r
Status = MpServices->GetProcessorInfo (\r
MpServices,\r
ProcessorNumber,\r
\r
@param[in] Procedure A pointer to the function to be run on\r
enabled APs of the system.\r
+ @param[in] MpEvent A pointer to the event to be used later\r
+ to check whether procedure has done.\r
**/\r
VOID\r
StartupAPsWorker (\r
- IN EFI_AP_PROCEDURE Procedure\r
+ IN EFI_AP_PROCEDURE Procedure,\r
+ IN EFI_EVENT MpEvent\r
)\r
{\r
EFI_STATUS Status;\r
EFI_MP_SERVICES_PROTOCOL *MpServices;\r
+ CPU_FEATURES_DATA *CpuFeaturesData;\r
+\r
+ CpuFeaturesData = GetCpuFeaturesData ();\r
+ MpServices = CpuFeaturesData->MpService.Protocol;\r
\r
- MpServices = GetMpProtocol ();\r
//\r
// Wakeup all APs\r
//\r
MpServices,\r
Procedure,\r
FALSE,\r
- NULL,\r
+ MpEvent,\r
0,\r
- NULL,\r
+ CpuFeaturesData,\r
NULL\r
);\r
ASSERT_EFI_ERROR (Status);\r
{\r
EFI_STATUS Status;\r
EFI_MP_SERVICES_PROTOCOL *MpServices;\r
+ CPU_FEATURES_DATA *CpuFeaturesData;\r
+\r
+ CpuFeaturesData = GetCpuFeaturesData ();\r
+ MpServices = CpuFeaturesData->MpService.Protocol;\r
\r
- MpServices = GetMpProtocol ();\r
//\r
// Wakeup all APs\r
//\r
{\r
EFI_STATUS Status;\r
EFI_MP_SERVICES_PROTOCOL *MpServices;\r
+ CPU_FEATURES_DATA *CpuFeaturesData;\r
\r
- MpServices = GetMpProtocol ();\r
+ CpuFeaturesData = GetCpuFeaturesData ();\r
+ MpServices = CpuFeaturesData->MpService.Protocol;\r
\r
//\r
// Get the number of CPUs\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
+ EFI_EVENT MpEvent;\r
+ EFI_STATUS Status;\r
+\r
+ CpuFeaturesData = GetCpuFeaturesData ();\r
+\r
+ OldBspNumber = GetProcessorIndex (CpuFeaturesData);\r
+ CpuFeaturesData->BspNumber = OldBspNumber;\r
+\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_WAIT,\r
+ TPL_CALLBACK,\r
+ EfiEventEmptyFunction,\r
+ NULL,\r
+ &MpEvent\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Wakeup all APs for programming.\r
+ //\r
+ StartupAPsWorker (SetProcessorRegister, MpEvent);\r
+ //\r
+ // Programming BSP\r
+ //\r
+ SetProcessorRegister (CpuFeaturesData);\r
+\r
+ //\r
+ // Wait all processors to finish the task.\r
+ //\r
+ do {\r
+ Status = gBS->CheckEvent (MpEvent);\r
+ } while (Status == EFI_NOT_READY);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Switch to new BSP if required\r
+ //\r
+ if (CpuFeaturesData->BspNumber != OldBspNumber) {\r
+ SwitchNewBsp (CpuFeaturesData->BspNumber);\r
+ }\r
+}\r
+\r