2 Install a callback when necessary for setting the Feature Control MSR on all
5 Copyright (C) 2016, Red Hat, Inc.
7 This program and the accompanying materials are licensed and made available
8 under the terms and conditions of the BSD License which accompanies this
9 distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
13 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Library/DebugLib.h>
17 #include <Library/PeiServicesLib.h>
18 #include <Library/QemuFwCfgLib.h>
19 #include <Ppi/MpServices.h>
20 #include <Register/Msr/Core2Msr.h>
25 // The value to be written to the Feature Control MSR, retrieved from fw_cfg.
27 STATIC UINT64 mFeatureControlValue
;
30 Write the Feature Control MSR on an Application Processor or the Boot
33 All APs execute this function in parallel. The BSP executes the function
36 @param[in,out] WorkSpace Pointer to the input/output argument workspace
37 shared by all processors.
43 IN OUT VOID
*WorkSpace
46 AsmWriteMsr64 (MSR_CORE2_FEATURE_CONTROL
, mFeatureControlValue
);
50 Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available.
52 @param[in] PeiServices Indirect reference to the PEI Services Table.
53 @param[in] NotifyDescriptor Address of the notification descriptor data
55 @param[in] Ppi Address of the PPI that was installed.
57 @return Status of the notification. The status code returned from this
63 OnMpServicesAvailable (
64 IN EFI_PEI_SERVICES
**PeiServices
,
65 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
69 EFI_PEI_MP_SERVICES_PPI
*MpServices
;
72 DEBUG ((EFI_D_VERBOSE
, "%a: %a\n", gEfiCallerBaseName
, __FUNCTION__
));
75 // Write the MSR on all the APs in parallel.
78 Status
= MpServices
->StartupAllAPs (
79 (CONST EFI_PEI_SERVICES
**)PeiServices
,
81 WriteFeatureControl
, // Procedure
82 FALSE
, // SingleThread
83 0, // TimeoutInMicroSeconds: inf.
84 NULL
// ProcedureArgument
86 if (EFI_ERROR (Status
) && Status
!= EFI_NOT_STARTED
) {
87 DEBUG ((EFI_D_ERROR
, "%a: StartupAllAps(): %r\n", __FUNCTION__
, Status
));
92 // Now write the MSR on the BSP too.
94 WriteFeatureControl (NULL
);
99 // Notification object for registering the callback, for when
100 // EFI_PEI_MP_SERVICES_PPI becomes available.
102 STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify
= {
103 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| // Flags
104 EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
105 &gEfiPeiMpServicesPpiGuid
, // Guid
106 OnMpServicesAvailable
// Notify
110 InstallFeatureControlCallback (
115 FIRMWARE_CONFIG_ITEM FwCfgItem
;
118 Status
= QemuFwCfgFindFile ("etc/msr_feature_control", &FwCfgItem
,
120 if (EFI_ERROR (Status
) || FwCfgSize
!= sizeof mFeatureControlValue
) {
126 QemuFwCfgSelectItem (FwCfgItem
);
127 QemuFwCfgReadBytes (sizeof mFeatureControlValue
, &mFeatureControlValue
);
129 Status
= PeiServicesNotifyPpi (&mMpServicesNotify
);
130 if (EFI_ERROR (Status
)) {
131 DEBUG ((EFI_D_ERROR
, "%a: failed to set up MP Services callback: %r\n",
132 __FUNCTION__
, Status
));