]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/PlatformPei/FeatureControl.c
OvmfPkg/PlatformPei: remove mFeatureControlValue
[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
f6a196c7 11#include <Library/HobLib.h>\r
dbab9949
LE
12#include <Library/PeiServicesLib.h>\r
13#include <Library/QemuFwCfgLib.h>\r
14#include <Ppi/MpServices.h>\r
1ab7d726 15#include <Register/ArchitecturalMsr.h>\r
cf17156d 16#include <IndustryStandard/Tdx.h>\r
dbab9949
LE
17\r
18#include "Platform.h"\r
19\r
dbab9949
LE
20/**\r
21 Write the Feature Control MSR on an Application Processor or the Boot\r
22 Processor.\r
23\r
24 All APs execute this function in parallel. The BSP executes the function\r
25 separately.\r
26\r
27 @param[in,out] WorkSpace Pointer to the input/output argument workspace\r
28 shared by all processors.\r
29**/\r
30STATIC\r
31VOID\r
32EFIAPI\r
33WriteFeatureControl (\r
ac0a286f 34 IN OUT VOID *WorkSpace\r
dbab9949
LE
35 )\r
36{\r
f6a196c7
GH
37 EFI_HOB_PLATFORM_INFO *PlatformInfoHob = WorkSpace;\r
38\r
cf17156d 39 if (TdIsEnabled ()) {\r
f6a196c7
GH
40 TdVmCall (\r
41 TDVMCALL_WRMSR,\r
42 (UINT64)MSR_IA32_FEATURE_CONTROL,\r
43 PlatformInfoHob->FeatureControlValue,\r
44 0,\r
45 0,\r
46 0\r
47 );\r
cf17156d 48 } else {\r
f6a196c7
GH
49 AsmWriteMsr64 (\r
50 MSR_IA32_FEATURE_CONTROL,\r
51 PlatformInfoHob->FeatureControlValue\r
52 );\r
cf17156d 53 }\r
dbab9949
LE
54}\r
55\r
56/**\r
57 Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available.\r
58\r
59 @param[in] PeiServices Indirect reference to the PEI Services Table.\r
60 @param[in] NotifyDescriptor Address of the notification descriptor data\r
61 structure.\r
62 @param[in] Ppi Address of the PPI that was installed.\r
63\r
64 @return Status of the notification. The status code returned from this\r
65 function is ignored.\r
66**/\r
67STATIC\r
68EFI_STATUS\r
69EFIAPI\r
70OnMpServicesAvailable (\r
71 IN EFI_PEI_SERVICES **PeiServices,\r
72 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
73 IN VOID *Ppi\r
74 )\r
75{\r
ac0a286f
MK
76 EFI_PEI_MP_SERVICES_PPI *MpServices;\r
77 EFI_STATUS Status;\r
f6a196c7
GH
78 EFI_HOB_PLATFORM_INFO *PlatformInfoHob;\r
79 EFI_HOB_GUID_TYPE *GuidHob;\r
80\r
81 GuidHob = GetFirstGuidHob (&gUefiOvmfPkgPlatformInfoGuid);\r
82 if (GuidHob == NULL) {\r
83 return EFI_UNSUPPORTED;\r
84 }\r
85\r
86 PlatformInfoHob = (EFI_HOB_PLATFORM_INFO *)GET_GUID_HOB_DATA (GuidHob);\r
dbab9949 87\r
70d5086c 88 DEBUG ((DEBUG_VERBOSE, "%a: %a\n", gEfiCallerBaseName, __FUNCTION__));\r
dbab9949
LE
89\r
90 //\r
91 // Write the MSR on all the APs in parallel.\r
92 //\r
93 MpServices = Ppi;\r
ac0a286f
MK
94 Status = MpServices->StartupAllAPs (\r
95 (CONST EFI_PEI_SERVICES **)PeiServices,\r
96 MpServices,\r
97 WriteFeatureControl, // Procedure\r
98 FALSE, // SingleThread\r
99 0, // TimeoutInMicroSeconds: inf.\r
f6a196c7 100 PlatformInfoHob // ProcedureArgument\r
ac0a286f
MK
101 );\r
102 if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {\r
70d5086c 103 DEBUG ((DEBUG_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__, Status));\r
dbab9949
LE
104 return Status;\r
105 }\r
106\r
107 //\r
108 // Now write the MSR on the BSP too.\r
109 //\r
f6a196c7 110 WriteFeatureControl (PlatformInfoHob);\r
dbab9949
LE
111 return EFI_SUCCESS;\r
112}\r
113\r
114//\r
115// Notification object for registering the callback, for when\r
116// EFI_PEI_MP_SERVICES_PPI becomes available.\r
117//\r
ac0a286f 118STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify = {\r
dbab9949
LE
119 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags\r
120 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
121 &gEfiPeiMpServicesPpiGuid, // Guid\r
122 OnMpServicesAvailable // Notify\r
123};\r
124\r
125VOID\r
126InstallFeatureControlCallback (\r
f6a196c7 127 IN OUT EFI_HOB_PLATFORM_INFO *PlatformInfoHob\r
dbab9949
LE
128 )\r
129{\r
ac0a286f
MK
130 EFI_STATUS Status;\r
131 FIRMWARE_CONFIG_ITEM FwCfgItem;\r
132 UINTN FwCfgSize;\r
133\r
134 Status = QemuFwCfgFindFile (\r
135 "etc/msr_feature_control",\r
136 &FwCfgItem,\r
137 &FwCfgSize\r
138 );\r
f6a196c7 139 if (EFI_ERROR (Status) || (FwCfgSize != sizeof (PlatformInfoHob->FeatureControlValue))) {\r
dbab9949
LE
140 //\r
141 // Nothing to do.\r
142 //\r
143 return;\r
144 }\r
ac0a286f 145\r
dbab9949 146 QemuFwCfgSelectItem (FwCfgItem);\r
f6a196c7
GH
147 QemuFwCfgReadBytes (\r
148 sizeof (PlatformInfoHob->FeatureControlValue),\r
149 &(PlatformInfoHob->FeatureControlValue)\r
150 );\r
dbab9949
LE
151\r
152 Status = PeiServicesNotifyPpi (&mMpServicesNotify);\r
153 if (EFI_ERROR (Status)) {\r
ac0a286f
MK
154 DEBUG ((\r
155 DEBUG_ERROR,\r
156 "%a: failed to set up MP Services callback: %r\n",\r
157 __FUNCTION__,\r
158 Status\r
159 ));\r
dbab9949
LE
160 }\r
161}\r