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