2 Install a callback when necessary for setting the Feature Control MSR on all
5 Copyright (C) 2016, Red Hat, Inc.
7 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/DebugLib.h>
11 #include <Library/PeiServicesLib.h>
12 #include <Library/QemuFwCfgLib.h>
13 #include <Ppi/MpServices.h>
14 #include <Register/ArchitecturalMsr.h>
15 #include <IndustryStandard/Tdx.h>
20 // The value to be written to the Feature Control MSR, retrieved from fw_cfg.
22 STATIC UINT64 mFeatureControlValue
;
25 Write the Feature Control MSR on an Application Processor or the Boot
28 All APs execute this function in parallel. The BSP executes the function
31 @param[in,out] WorkSpace Pointer to the input/output argument workspace
32 shared by all processors.
38 IN OUT VOID
*WorkSpace
42 TdVmCall (TDVMCALL_WRMSR
, (UINT64
)MSR_IA32_FEATURE_CONTROL
, mFeatureControlValue
, 0, 0, 0);
44 AsmWriteMsr64 (MSR_IA32_FEATURE_CONTROL
, mFeatureControlValue
);
49 Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available.
51 @param[in] PeiServices Indirect reference to the PEI Services Table.
52 @param[in] NotifyDescriptor Address of the notification descriptor data
54 @param[in] Ppi Address of the PPI that was installed.
56 @return Status of the notification. The status code returned from this
62 OnMpServicesAvailable (
63 IN EFI_PEI_SERVICES
**PeiServices
,
64 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
68 EFI_PEI_MP_SERVICES_PPI
*MpServices
;
71 DEBUG ((DEBUG_VERBOSE
, "%a: %a\n", gEfiCallerBaseName
, __FUNCTION__
));
74 // Write the MSR on all the APs in parallel.
77 Status
= MpServices
->StartupAllAPs (
78 (CONST EFI_PEI_SERVICES
**)PeiServices
,
80 WriteFeatureControl
, // Procedure
81 FALSE
, // SingleThread
82 0, // TimeoutInMicroSeconds: inf.
83 NULL
// ProcedureArgument
85 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_STARTED
)) {
86 DEBUG ((DEBUG_ERROR
, "%a: StartupAllAps(): %r\n", __FUNCTION__
, Status
));
91 // Now write the MSR on the BSP too.
93 WriteFeatureControl (NULL
);
98 // Notification object for registering the callback, for when
99 // EFI_PEI_MP_SERVICES_PPI becomes available.
101 STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify
= {
102 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| // Flags
103 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
104 &gEfiPeiMpServicesPpiGuid
, // Guid
105 OnMpServicesAvailable
// Notify
109 InstallFeatureControlCallback (
114 FIRMWARE_CONFIG_ITEM FwCfgItem
;
117 Status
= QemuFwCfgFindFile (
118 "etc/msr_feature_control",
122 if (EFI_ERROR (Status
) || (FwCfgSize
!= sizeof mFeatureControlValue
)) {
129 QemuFwCfgSelectItem (FwCfgItem
);
130 QemuFwCfgReadBytes (sizeof mFeatureControlValue
, &mFeatureControlValue
);
132 Status
= PeiServicesNotifyPpi (&mMpServicesNotify
);
133 if (EFI_ERROR (Status
)) {
136 "%a: failed to set up MP Services callback: %r\n",