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