]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/PlatformPei/FeatureControl.c
BaseTools: Library hashing fix and optimization for --hash feature
[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/PeiServicesLib.h>
12 #include <Library/QemuFwCfgLib.h>
13 #include <Ppi/MpServices.h>
14 #include <Register/Msr/Core2Msr.h>
15
16 #include "Platform.h"
17
18 //
19 // The value to be written to the Feature Control MSR, retrieved from fw_cfg.
20 //
21 STATIC UINT64 mFeatureControlValue;
22
23 /**
24 Write the Feature Control MSR on an Application Processor or the Boot
25 Processor.
26
27 All APs execute this function in parallel. The BSP executes the function
28 separately.
29
30 @param[in,out] WorkSpace Pointer to the input/output argument workspace
31 shared by all processors.
32 **/
33 STATIC
34 VOID
35 EFIAPI
36 WriteFeatureControl (
37 IN OUT VOID *WorkSpace
38 )
39 {
40 AsmWriteMsr64 (MSR_CORE2_FEATURE_CONTROL, mFeatureControlValue);
41 }
42
43 /**
44 Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available.
45
46 @param[in] PeiServices Indirect reference to the PEI Services Table.
47 @param[in] NotifyDescriptor Address of the notification descriptor data
48 structure.
49 @param[in] Ppi Address of the PPI that was installed.
50
51 @return Status of the notification. The status code returned from this
52 function is ignored.
53 **/
54 STATIC
55 EFI_STATUS
56 EFIAPI
57 OnMpServicesAvailable (
58 IN EFI_PEI_SERVICES **PeiServices,
59 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
60 IN VOID *Ppi
61 )
62 {
63 EFI_PEI_MP_SERVICES_PPI *MpServices;
64 EFI_STATUS Status;
65
66 DEBUG ((EFI_D_VERBOSE, "%a: %a\n", gEfiCallerBaseName, __FUNCTION__));
67
68 //
69 // Write the MSR on all the APs in parallel.
70 //
71 MpServices = Ppi;
72 Status = MpServices->StartupAllAPs (
73 (CONST EFI_PEI_SERVICES **)PeiServices,
74 MpServices,
75 WriteFeatureControl, // Procedure
76 FALSE, // SingleThread
77 0, // TimeoutInMicroSeconds: inf.
78 NULL // ProcedureArgument
79 );
80 if (EFI_ERROR (Status) && Status != EFI_NOT_STARTED) {
81 DEBUG ((EFI_D_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__, Status));
82 return Status;
83 }
84
85 //
86 // Now write the MSR on the BSP too.
87 //
88 WriteFeatureControl (NULL);
89 return EFI_SUCCESS;
90 }
91
92 //
93 // Notification object for registering the callback, for when
94 // EFI_PEI_MP_SERVICES_PPI becomes available.
95 //
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
101 };
102
103 VOID
104 InstallFeatureControlCallback (
105 VOID
106 )
107 {
108 EFI_STATUS Status;
109 FIRMWARE_CONFIG_ITEM FwCfgItem;
110 UINTN FwCfgSize;
111
112 Status = QemuFwCfgFindFile ("etc/msr_feature_control", &FwCfgItem,
113 &FwCfgSize);
114 if (EFI_ERROR (Status) || FwCfgSize != sizeof mFeatureControlValue) {
115 //
116 // Nothing to do.
117 //
118 return;
119 }
120 QemuFwCfgSelectItem (FwCfgItem);
121 QemuFwCfgReadBytes (sizeof mFeatureControlValue, &mFeatureControlValue);
122
123 Status = PeiServicesNotifyPpi (&mMpServicesNotify);
124 if (EFI_ERROR (Status)) {
125 DEBUG ((EFI_D_ERROR, "%a: failed to set up MP Services callback: %r\n",
126 __FUNCTION__, Status));
127 }
128 }