]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.c
3654c105ef78312618cf42276f51985114b977ad
[mirror_edk2.git] / UefiCpuPkg / Library / RegisterCpuFeaturesLib / DxeRegisterCpuFeaturesLib.c
1 /** @file
2 CPU Register Table Library functions.
3
4 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <PiDxe.h>
16
17 #include <Library/UefiBootServicesTableLib.h>
18 #include <Library/UefiLib.h>
19
20 #include "RegisterCpuFeatures.h"
21
22 CPU_FEATURES_DATA mCpuFeaturesData = {0};
23
24 /**
25 Worker function to get CPU_FEATURES_DATA pointer.
26
27 @return Pointer to CPU_FEATURES_DATA.
28 **/
29 CPU_FEATURES_DATA *
30 GetCpuFeaturesData (
31 VOID
32 )
33 {
34 return &mCpuFeaturesData;
35 }
36
37 /**
38 Worker function to get EFI_MP_SERVICES_PROTOCOL pointer.
39
40 @return MP_SERVICES variable.
41 **/
42 MP_SERVICES
43 GetMpService (
44 VOID
45 )
46 {
47 EFI_STATUS Status;
48 MP_SERVICES MpService;
49
50 //
51 // Get MP Services Protocol
52 //
53 Status = gBS->LocateProtocol (
54 &gEfiMpServiceProtocolGuid,
55 NULL,
56 (VOID **)&MpService.Protocol
57 );
58 ASSERT_EFI_ERROR (Status);
59
60 return MpService;
61 }
62
63 /**
64 Worker function to return processor index.
65
66 @param CpuFeaturesData Cpu Feature Data structure.
67
68 @return The processor index.
69 **/
70 UINTN
71 GetProcessorIndex (
72 IN CPU_FEATURES_DATA *CpuFeaturesData
73 )
74 {
75 EFI_STATUS Status;
76 UINTN ProcessorIndex;
77 EFI_MP_SERVICES_PROTOCOL *MpServices;
78
79 MpServices = CpuFeaturesData->MpService.Protocol;
80 Status = MpServices->WhoAmI(MpServices, &ProcessorIndex);
81 ASSERT_EFI_ERROR (Status);
82 return ProcessorIndex;
83 }
84
85 /**
86 Gets detailed MP-related information on the requested processor at the
87 instant this call is made.
88
89 @param[in] ProcessorNumber The handle number of processor.
90 @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
91 the requested processor is deposited.
92
93 @return Status of MpServices->GetProcessorInfo().
94 **/
95 EFI_STATUS
96 GetProcessorInformation (
97 IN UINTN ProcessorNumber,
98 OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
99 )
100 {
101 EFI_STATUS Status;
102 EFI_MP_SERVICES_PROTOCOL *MpServices;
103 CPU_FEATURES_DATA *CpuFeaturesData;
104
105 CpuFeaturesData = GetCpuFeaturesData ();
106 MpServices = CpuFeaturesData->MpService.Protocol;
107
108 Status = MpServices->GetProcessorInfo (
109 MpServices,
110 ProcessorNumber,
111 ProcessorInfoBuffer
112 );
113 return Status;
114 }
115
116 /**
117 Worker function to execute a caller provided function on all enabled APs.
118
119 @param[in] Procedure A pointer to the function to be run on
120 enabled APs of the system.
121 @param[in] MpEvent A pointer to the event to be used later
122 to check whether procedure has done.
123 **/
124 VOID
125 StartupAPsWorker (
126 IN EFI_AP_PROCEDURE Procedure,
127 IN EFI_EVENT MpEvent
128 )
129 {
130 EFI_STATUS Status;
131 EFI_MP_SERVICES_PROTOCOL *MpServices;
132 CPU_FEATURES_DATA *CpuFeaturesData;
133
134 CpuFeaturesData = GetCpuFeaturesData ();
135 MpServices = CpuFeaturesData->MpService.Protocol;
136
137 //
138 // Wakeup all APs
139 //
140 Status = MpServices->StartupAllAPs (
141 MpServices,
142 Procedure,
143 FALSE,
144 MpEvent,
145 0,
146 CpuFeaturesData,
147 NULL
148 );
149 ASSERT_EFI_ERROR (Status);
150 }
151
152 /**
153 Worker function to switch the requested AP to be the BSP from that point onward.
154
155 @param[in] ProcessorNumber The handle number of AP that is to become the new BSP.
156 **/
157 VOID
158 SwitchNewBsp (
159 IN UINTN ProcessorNumber
160 )
161 {
162 EFI_STATUS Status;
163 EFI_MP_SERVICES_PROTOCOL *MpServices;
164 CPU_FEATURES_DATA *CpuFeaturesData;
165
166 CpuFeaturesData = GetCpuFeaturesData ();
167 MpServices = CpuFeaturesData->MpService.Protocol;
168
169 //
170 // Wakeup all APs
171 //
172 Status = MpServices->SwitchBSP (
173 MpServices,
174 ProcessorNumber,
175 TRUE
176 );
177 ASSERT_EFI_ERROR (Status);
178 }
179
180 /**
181 Worker function to retrieve the number of logical processor in the platform.
182
183 @param[out] NumberOfCpus Pointer to the total number of logical
184 processors in the system, including the BSP
185 and disabled APs.
186 @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
187 processors that exist in system, including
188 the BSP.
189 **/
190 VOID
191 GetNumberOfProcessor (
192 OUT UINTN *NumberOfCpus,
193 OUT UINTN *NumberOfEnabledProcessors
194 )
195 {
196 EFI_STATUS Status;
197 EFI_MP_SERVICES_PROTOCOL *MpServices;
198 CPU_FEATURES_DATA *CpuFeaturesData;
199
200 CpuFeaturesData = GetCpuFeaturesData ();
201 MpServices = CpuFeaturesData->MpService.Protocol;
202
203 //
204 // Get the number of CPUs
205 //
206 Status = MpServices->GetNumberOfProcessors (
207 MpServices,
208 NumberOfCpus,
209 NumberOfEnabledProcessors
210 );
211 ASSERT_EFI_ERROR (Status);
212 }
213
214 /**
215 Performs CPU features Initialization.
216
217 This service will invoke MP service to perform CPU features
218 initialization on BSP/APs per user configuration.
219
220 @note This service could be called by BSP only.
221 **/
222 VOID
223 EFIAPI
224 CpuFeaturesInitialize (
225 VOID
226 )
227 {
228 CPU_FEATURES_DATA *CpuFeaturesData;
229 UINTN OldBspNumber;
230 EFI_EVENT MpEvent;
231 EFI_STATUS Status;
232
233 CpuFeaturesData = GetCpuFeaturesData ();
234
235 OldBspNumber = GetProcessorIndex (CpuFeaturesData);
236 CpuFeaturesData->BspNumber = OldBspNumber;
237
238 Status = gBS->CreateEvent (
239 EVT_NOTIFY_WAIT,
240 TPL_CALLBACK,
241 EfiEventEmptyFunction,
242 NULL,
243 &MpEvent
244 );
245 ASSERT_EFI_ERROR (Status);
246
247 //
248 // Wakeup all APs for programming.
249 //
250 StartupAPsWorker (SetProcessorRegister, MpEvent);
251 //
252 // Programming BSP
253 //
254 SetProcessorRegister (CpuFeaturesData);
255
256 //
257 // Wait all processors to finish the task.
258 //
259 do {
260 Status = gBS->CheckEvent (MpEvent);
261 } while (Status == EFI_NOT_READY);
262 ASSERT_EFI_ERROR (Status);
263
264 //
265 // Switch to new BSP if required
266 //
267 if (CpuFeaturesData->BspNumber != OldBspNumber) {
268 SwitchNewBsp (CpuFeaturesData->BspNumber);
269 }
270 }
271