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