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>
19 // The value to be written to the Feature Control MSR, retrieved from fw_cfg.
21 STATIC UINT64 mFeatureControlValue
;
24 Write the Feature Control MSR on an Application Processor or the Boot
27 All APs execute this function in parallel. The BSP executes the function
30 @param[in,out] WorkSpace Pointer to the input/output argument workspace
31 shared by all processors.
37 IN OUT VOID
*WorkSpace
40 AsmWriteMsr64 (MSR_IA32_FEATURE_CONTROL
, mFeatureControlValue
);
44 Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available.
46 @param[in] PeiServices Indirect reference to the PEI Services Table.
47 @param[in] NotifyDescriptor Address of the notification descriptor data
49 @param[in] Ppi Address of the PPI that was installed.
51 @return Status of the notification. The status code returned from this
57 OnMpServicesAvailable (
58 IN EFI_PEI_SERVICES
**PeiServices
,
59 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
63 EFI_PEI_MP_SERVICES_PPI
*MpServices
;
66 DEBUG ((DEBUG_VERBOSE
, "%a: %a\n", gEfiCallerBaseName
, __FUNCTION__
));
69 // Write the MSR on all the APs in parallel.
72 Status
= MpServices
->StartupAllAPs (
73 (CONST EFI_PEI_SERVICES
**)PeiServices
,
75 WriteFeatureControl
, // Procedure
76 FALSE
, // SingleThread
77 0, // TimeoutInMicroSeconds: inf.
78 NULL
// ProcedureArgument
80 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_STARTED
)) {
81 DEBUG ((DEBUG_ERROR
, "%a: StartupAllAps(): %r\n", __FUNCTION__
, Status
));
86 // Now write the MSR on the BSP too.
88 WriteFeatureControl (NULL
);
93 // Notification object for registering the callback, for when
94 // EFI_PEI_MP_SERVICES_PPI becomes available.
96 STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify
= {
97 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| // Flags
98 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
99 &gEfiPeiMpServicesPpiGuid
, // Guid
100 OnMpServicesAvailable
// Notify
104 InstallFeatureControlCallback (
109 FIRMWARE_CONFIG_ITEM FwCfgItem
;
112 Status
= QemuFwCfgFindFile (
113 "etc/msr_feature_control",
117 if (EFI_ERROR (Status
) || (FwCfgSize
!= sizeof mFeatureControlValue
)) {
124 QemuFwCfgSelectItem (FwCfgItem
);
125 QemuFwCfgReadBytes (sizeof mFeatureControlValue
, &mFeatureControlValue
);
127 Status
= PeiServicesNotifyPpi (&mMpServicesNotify
);
128 if (EFI_ERROR (Status
)) {
131 "%a: failed to set up MP Services callback: %r\n",