TianoCore EDK2 master
Loading...
Searching...
No Matches
CpuService.c
Go to the documentation of this file.
1
9#include "PiSmmCpuCommon.h"
10
11//
12// SMM CPU Service Protocol instance
13//
14EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService = {
21};
22
23//
24// EDKII SMM CPU Rendezvous Service Protocol instance
25//
26EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL mSmmCpuRendezvousService = {
28};
29
46EFIAPI
49 IN UINTN ProcessorNumber,
50 OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
51 )
52{
53 //
54 // Check parameter
55 //
56 if ((ProcessorNumber >= mMaxNumberOfCpus) || (ProcessorInfoBuffer == NULL)) {
57 return EFI_INVALID_PARAMETER;
58 }
59
60 if (gSmmCpuPrivate->ProcessorInfo[ProcessorNumber].ProcessorId == INVALID_APIC_ID) {
61 return EFI_NOT_FOUND;
62 }
63
64 //
65 // Fill in processor information
66 //
67 CopyMem (ProcessorInfoBuffer, &gSmmCpuPrivate->ProcessorInfo[ProcessorNumber], sizeof (EFI_PROCESSOR_INFORMATION));
68 return EFI_SUCCESS;
69}
70
83EFIAPI
86 IN UINTN ProcessorNumber
87 )
88{
89 //
90 // Check parameter
91 //
92 if (ProcessorNumber >= mMaxNumberOfCpus) {
93 return EFI_INVALID_PARAMETER;
94 }
95
96 if (gSmmCpuPrivate->ProcessorInfo[ProcessorNumber].ProcessorId == INVALID_APIC_ID) {
97 return EFI_NOT_FOUND;
98 }
99
100 if ((gSmmCpuPrivate->Operation[ProcessorNumber] != SmmCpuNone) ||
101 (gMmst->CurrentlyExecutingCpu == ProcessorNumber))
102 {
103 return EFI_UNSUPPORTED;
104 }
105
106 //
107 // Setting of the BSP for next SMI is pending until all SMI handlers are finished
108 //
109 gSmmCpuPrivate->Operation[ProcessorNumber] = SmmCpuSwitchBsp;
110 return EFI_SUCCESS;
111}
112
127EFIAPI
130 IN UINT64 ProcessorId,
131 OUT UINTN *ProcessorNumber
132 )
133{
134 UINTN Index;
135
136 if (!FeaturePcdGet (PcdCpuHotPlugSupport)) {
137 return EFI_UNSUPPORTED;
138 }
139
140 //
141 // Check parameter
142 //
143 if ((ProcessorNumber == NULL) || (ProcessorId == INVALID_APIC_ID)) {
144 return EFI_INVALID_PARAMETER;
145 }
146
147 //
148 // Check if the processor already exists
149 //
150
151 for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
152 if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == ProcessorId) {
153 return EFI_ALREADY_STARTED;
154 }
155 }
156
157 //
158 // Check CPU hot plug data. The CPU RAS handler should have created the mapping
159 // of the APIC ID to SMBASE.
160 //
161 for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
162 if ((mCpuHotPlugData.ApicId[Index] == ProcessorId) &&
163 (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == INVALID_APIC_ID))
164 {
165 gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId = ProcessorId;
166 gSmmCpuPrivate->ProcessorInfo[Index].StatusFlag = 0;
168 (UINT32)ProcessorId,
169 &gSmmCpuPrivate->ProcessorInfo[Index].Location.Package,
170 &gSmmCpuPrivate->ProcessorInfo[Index].Location.Core,
171 &gSmmCpuPrivate->ProcessorInfo[Index].Location.Thread
172 );
173
175 (UINT32)ProcessorId,
176 &gSmmCpuPrivate->ProcessorInfo[Index].ExtendedInformation.Location2.Package,
177 &gSmmCpuPrivate->ProcessorInfo[Index].ExtendedInformation.Location2.Die,
178 &gSmmCpuPrivate->ProcessorInfo[Index].ExtendedInformation.Location2.Tile,
179 &gSmmCpuPrivate->ProcessorInfo[Index].ExtendedInformation.Location2.Module,
180 &gSmmCpuPrivate->ProcessorInfo[Index].ExtendedInformation.Location2.Core,
181 &gSmmCpuPrivate->ProcessorInfo[Index].ExtendedInformation.Location2.Thread
182 );
183
184 *ProcessorNumber = Index;
185 gSmmCpuPrivate->Operation[Index] = SmmCpuAdd;
186 return EFI_SUCCESS;
187 }
188 }
189
190 return EFI_INVALID_PARAMETER;
191}
192
206EFIAPI
209 IN UINTN ProcessorNumber
210 )
211{
212 if (!FeaturePcdGet (PcdCpuHotPlugSupport)) {
213 return EFI_UNSUPPORTED;
214 }
215
216 //
217 // Check parameter
218 //
219 if ((ProcessorNumber >= mMaxNumberOfCpus) ||
220 (gSmmCpuPrivate->ProcessorInfo[ProcessorNumber].ProcessorId == INVALID_APIC_ID))
221 {
222 return EFI_INVALID_PARAMETER;
223 }
224
225 //
226 // Can't remove BSP
227 //
228 if (ProcessorNumber == gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu) {
229 return EFI_UNSUPPORTED;
230 }
231
232 if (gSmmCpuPrivate->Operation[ProcessorNumber] != SmmCpuNone) {
233 return EFI_UNSUPPORTED;
234 }
235
236 gSmmCpuPrivate->ProcessorInfo[ProcessorNumber].ProcessorId = INVALID_APIC_ID;
237 mCpuHotPlugData.ApicId[ProcessorNumber] = INVALID_APIC_ID;
238
239 //
240 // Removal of the processor from the CPU list is pending until all SMI handlers are finished
241 //
242 gSmmCpuPrivate->Operation[ProcessorNumber] = SmmCpuRemove;
243 return EFI_SUCCESS;
244}
245
258EFIAPI
261 OUT UINTN *ProcessorNumber
262 )
263{
264 UINTN Index;
265 UINT64 ApicId;
266
267 //
268 // Check parameter
269 //
270 if (ProcessorNumber == NULL) {
271 return EFI_INVALID_PARAMETER;
272 }
273
274 ApicId = GetApicId ();
275
276 for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
277 if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == ApicId) {
278 *ProcessorNumber = Index;
279 return EFI_SUCCESS;
280 }
281 }
282
283 //
284 // This should not happen
285 //
286 ASSERT (FALSE);
287 return EFI_NOT_FOUND;
288}
289
295VOID
297 VOID
298 )
299{
300 UINTN Index;
301
302 //
303 // Handle pending BSP switch operations
304 //
305 for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
306 if (gSmmCpuPrivate->Operation[Index] == SmmCpuSwitchBsp) {
307 gSmmCpuPrivate->Operation[Index] = SmmCpuNone;
308 mSmmMpSyncData->SwitchBsp = TRUE;
309 mSmmMpSyncData->CandidateBsp[Index] = TRUE;
310 }
311 }
312
313 //
314 // Handle pending hot-add operations
315 //
316 for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
317 if (gSmmCpuPrivate->Operation[Index] == SmmCpuAdd) {
318 gSmmCpuPrivate->Operation[Index] = SmmCpuNone;
319 mNumberOfCpus++;
320 }
321 }
322
323 //
324 // Handle pending hot-remove operations
325 //
326 for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
327 if (gSmmCpuPrivate->Operation[Index] == SmmCpuRemove) {
328 gSmmCpuPrivate->Operation[Index] = SmmCpuNone;
329 mNumberOfCpus--;
330 }
331 }
332}
333
352EFIAPI
355 IN EFI_EXCEPTION_TYPE ExceptionType,
356 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
357 )
358{
359 return RegisterCpuInterruptHandler (ExceptionType, InterruptHandler);
360}
361
374 IN EFI_HANDLE Handle
375 )
376{
377 EFI_STATUS Status;
378
379 Status = gMmst->MmInstallProtocolInterface (
380 &Handle,
381 &gEfiSmmCpuServiceProtocolGuid,
383 &mSmmCpuService
384 );
385 ASSERT_EFI_ERROR (Status);
386 if (EFI_ERROR (Status)) {
387 return Status;
388 }
389
390 Status = gMmst->MmInstallProtocolInterface (
391 &Handle,
392 &gEdkiiSmmCpuRendezvousProtocolGuid,
394 &mSmmCpuRendezvousService
395 );
396 ASSERT_EFI_ERROR (Status);
397 return Status;
398}
399
413EFIAPI
416 IN BOOLEAN BlockingMode
417 )
418{
419 EFI_STATUS Status;
420
421 //
422 // Return success immediately if all CPUs are already synchronized.
423 //
424 if (mSmmMpSyncData->AllApArrivedWithException) {
425 Status = EFI_SUCCESS;
426 goto ON_EXIT;
427 }
428
429 if (!BlockingMode) {
430 Status = EFI_TIMEOUT;
431 goto ON_EXIT;
432 }
433
434 if ((mSmmMpSyncData->EffectiveSyncMode != MmCpuSyncModeTradition) && !SmmCpuFeaturesNeedConfigureMtrrs ()) {
435 //
436 // There are some APs outside SMM, Wait for all avaiable APs to arrive.
437 //
439 Status = mSmmMpSyncData->AllApArrivedWithException ? EFI_SUCCESS : EFI_TIMEOUT;
440 } else {
441 //
442 // BSP has already waitted for APs to arrive SMM if SmmCpuSyncMode selected or need config MTRR.
443 //
444 Status = EFI_TIMEOUT;
445 }
446
447ON_EXIT:
448 if (!mSmmMpSyncData->AllApArrivedWithException) {
449 DEBUG ((DEBUG_INFO, "EdkiiSmmWaitForAllApArrival: Timeout to wait all APs arrival\n"));
450 }
451
452 return Status;
453}
UINT64 UINTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID(EFIAPI * EFI_CPU_INTERRUPT_HANDLER)(IN CONST EFI_EXCEPTION_TYPE InterruptType, IN CONST EFI_SYSTEM_CONTEXT SystemContext)
Definition: Cpu.h:52
EFI_STATUS EFIAPI SmmSwitchBsp(IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, IN UINTN ProcessorNumber)
Definition: CpuService.c:84
EFI_STATUS EFIAPI SmmCpuRendezvous(IN EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL *This, IN BOOLEAN BlockingMode)
Definition: CpuService.c:414
VOID SmmCpuUpdate(VOID)
Definition: CpuService.c:296
EFI_STATUS InitializeSmmCpuServices(IN EFI_HANDLE Handle)
Definition: CpuService.c:373
EFI_STATUS EFIAPI SmmRegisterExceptionHandler(IN EFI_SMM_CPU_SERVICE_PROTOCOL *This, IN EFI_EXCEPTION_TYPE ExceptionType, IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler)
Definition: CpuService.c:353
EFI_STATUS EFIAPI SmmAddProcessor(IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, IN UINT64 ProcessorId, OUT UINTN *ProcessorNumber)
Definition: CpuService.c:128
EFI_STATUS EFIAPI SmmWhoAmI(IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, OUT UINTN *ProcessorNumber)
Definition: CpuService.c:259
EFI_STATUS EFIAPI SmmGetProcessorInfo(IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, IN UINTN ProcessorNumber, OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer)
Definition: CpuService.c:47
EFI_STATUS EFIAPI SmmRemoveProcessor(IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This, IN UINTN ProcessorNumber)
Definition: CpuService.c:207
UINT32 EFIAPI GetApicId(VOID)
Definition: BaseXApicLib.c:337
VOID EFIAPI GetProcessorLocation2ByApicId(IN UINT32 InitialApicId, OUT UINT32 *Package OPTIONAL, OUT UINT32 *Die OPTIONAL, OUT UINT32 *Tile OPTIONAL, OUT UINT32 *Module OPTIONAL, OUT UINT32 *Core OPTIONAL, OUT UINT32 *Thread OPTIONAL)
VOID EFIAPI GetProcessorLocationByApicId(IN UINT32 InitialApicId, OUT UINT32 *Package OPTIONAL, OUT UINT32 *Core OPTIONAL, OUT UINT32 *Thread OPTIONAL)
Definition: BaseXApicLib.c:985
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
INTN EFI_EXCEPTION_TYPE
Definition: DebugSupport.h:35
BOOLEAN EFIAPI SmmCpuFeaturesNeedConfigureMtrrs(VOID)
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
VOID SmmWaitForApArrival(VOID)
Definition: MpService.c:231
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
EFI_INSTALL_PROTOCOL_INTERFACE MmInstallProtocolInterface
Definition: PiMmCis.h:327
UINTN CurrentlyExecutingCpu
Definition: PiMmCis.h:292
UINTN CurrentlyExecutingCpu
Definition: PiSmmCis.h:69
EXTENDED_PROCESSOR_INFORMATION ExtendedInformation
Definition: MpService.h:182
EFI_CPU_PHYSICAL_LOCATION Location
Definition: MpService.h:178
EFI_CPU_PHYSICAL_LOCATION2 Location2
Definition: MpService.h:140