]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/PlatformPei/FeatureControl.c
BaseTools: Library hashing fix and optimization for --hash feature
[mirror_edk2.git] / OvmfPkg / PlatformPei / FeatureControl.c
CommitLineData
dbab9949
LE
1/**@file\r
2 Install a callback when necessary for setting the Feature Control MSR on all\r
3 processors.\r
4\r
5 Copyright (C) 2016, Red Hat, Inc.\r
6\r
b26f0cf9 7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
dbab9949
LE
8**/\r
9\r
10#include <Library/DebugLib.h>\r
11#include <Library/PeiServicesLib.h>\r
12#include <Library/QemuFwCfgLib.h>\r
13#include <Ppi/MpServices.h>\r
14#include <Register/Msr/Core2Msr.h>\r
15\r
16#include "Platform.h"\r
17\r
18//\r
19// The value to be written to the Feature Control MSR, retrieved from fw_cfg.\r
20//\r
21STATIC UINT64 mFeatureControlValue;\r
22\r
23/**\r
24 Write the Feature Control MSR on an Application Processor or the Boot\r
25 Processor.\r
26\r
27 All APs execute this function in parallel. The BSP executes the function\r
28 separately.\r
29\r
30 @param[in,out] WorkSpace Pointer to the input/output argument workspace\r
31 shared by all processors.\r
32**/\r
33STATIC\r
34VOID\r
35EFIAPI\r
36WriteFeatureControl (\r
37 IN OUT VOID *WorkSpace\r
38 )\r
39{\r
40 AsmWriteMsr64 (MSR_CORE2_FEATURE_CONTROL, mFeatureControlValue);\r
41}\r
42\r
43/**\r
44 Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available.\r
45\r
46 @param[in] PeiServices Indirect reference to the PEI Services Table.\r
47 @param[in] NotifyDescriptor Address of the notification descriptor data\r
48 structure.\r
49 @param[in] Ppi Address of the PPI that was installed.\r
50\r
51 @return Status of the notification. The status code returned from this\r
52 function is ignored.\r
53**/\r
54STATIC\r
55EFI_STATUS\r
56EFIAPI\r
57OnMpServicesAvailable (\r
58 IN EFI_PEI_SERVICES **PeiServices,\r
59 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
60 IN VOID *Ppi\r
61 )\r
62{\r
63 EFI_PEI_MP_SERVICES_PPI *MpServices;\r
64 EFI_STATUS Status;\r
65\r
66 DEBUG ((EFI_D_VERBOSE, "%a: %a\n", gEfiCallerBaseName, __FUNCTION__));\r
67\r
68 //\r
69 // Write the MSR on all the APs in parallel.\r
70 //\r
71 MpServices = Ppi;\r
72 Status = MpServices->StartupAllAPs (\r
73 (CONST EFI_PEI_SERVICES **)PeiServices,\r
74 MpServices,\r
75 WriteFeatureControl, // Procedure\r
76 FALSE, // SingleThread\r
77 0, // TimeoutInMicroSeconds: inf.\r
78 NULL // ProcedureArgument\r
79 );\r
80 if (EFI_ERROR (Status) && Status != EFI_NOT_STARTED) {\r
81 DEBUG ((EFI_D_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__, Status));\r
82 return Status;\r
83 }\r
84\r
85 //\r
86 // Now write the MSR on the BSP too.\r
87 //\r
88 WriteFeatureControl (NULL);\r
89 return EFI_SUCCESS;\r
90}\r
91\r
92//\r
93// Notification object for registering the callback, for when\r
94// EFI_PEI_MP_SERVICES_PPI becomes available.\r
95//\r
96STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify = {\r
97 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags\r
98 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
99 &gEfiPeiMpServicesPpiGuid, // Guid\r
100 OnMpServicesAvailable // Notify\r
101};\r
102\r
103VOID\r
104InstallFeatureControlCallback (\r
105 VOID\r
106 )\r
107{\r
108 EFI_STATUS Status;\r
109 FIRMWARE_CONFIG_ITEM FwCfgItem;\r
110 UINTN FwCfgSize;\r
111\r
112 Status = QemuFwCfgFindFile ("etc/msr_feature_control", &FwCfgItem,\r
113 &FwCfgSize);\r
114 if (EFI_ERROR (Status) || FwCfgSize != sizeof mFeatureControlValue) {\r
115 //\r
116 // Nothing to do.\r
117 //\r
118 return;\r
119 }\r
120 QemuFwCfgSelectItem (FwCfgItem);\r
121 QemuFwCfgReadBytes (sizeof mFeatureControlValue, &mFeatureControlValue);\r
122\r
123 Status = PeiServicesNotifyPpi (&mMpServicesNotify);\r
124 if (EFI_ERROR (Status)) {\r
125 DEBUG ((EFI_D_ERROR, "%a: failed to set up MP Services callback: %r\n",\r
126 __FUNCTION__, Status));\r
127 }\r
128}\r