TianoCore EDK2 master
Loading...
Searching...
No Matches
PiSmmCpuDxeSmm.c
Go to the documentation of this file.
1
12#include "PiSmmCpuCommon.h"
14
15//
16// TRUE to indicate it's the MM_STANDALONE MM CPU driver.
17// FALSE to indicate it's the DXE_SMM_DRIVER SMM CPU driver.
18//
19const BOOLEAN mIsStandaloneMm = FALSE;
20
21//
22// SMM ready to lock flag
23//
24BOOLEAN mSmmReadyToLock = FALSE;
25
33BOOLEAN
35 VOID
36 )
37{
38 return FeaturePcdGet (PcdCpuSmmProfileEnable);
39}
40
45VOID
47 VOID
48 )
49{
50 EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;
51
52 if (mSmmReadyToLock) {
54
55 //
56 // Start SMM Profile feature
57 //
58 if (mSmmProfileEnabled) {
60 }
61
62 //
63 // Check if all Aps enter SMM. In Relaxed-AP Sync Mode, BSP will not wait for
64 // all Aps arrive. However,PerformRemainingTasks() needs to wait all Aps arrive before calling
65 // SetMemMapAttributes() and ConfigSmmCodeAccessCheck() when mSmmReadyToLock
66 // is true. In SetMemMapAttributes(), SmmSetMemoryAttributesEx() will call
67 // FlushTlbForAll() that need to start up the aps. So it need to let all
68 // aps arrive. Same as SetMemMapAttributes(), ConfigSmmCodeAccessCheck()
69 // also will start up the aps.
70 //
71 if (EFI_ERROR (SmmCpuRendezvous (NULL, TRUE))) {
72 DEBUG ((DEBUG_ERROR, "PerformRemainingTasks: fail to wait for all AP check in SMM!\n"));
73 }
74
75 //
76 // Update Page Table for outside SMRAM.
77 //
78 if (mSmmProfileEnabled) {
80 } else {
82 }
83
84 //
85 // gEdkiiPiSmmMemoryAttributesTableGuid should have been published at EndOfDxe by SmmCore
86 // Note: gEdkiiPiSmmMemoryAttributesTableGuid is not always installed since it depends on
87 // the memory protection attribute setting in MM Core.
88 //
89 SmmGetSystemConfigurationTable (&gEdkiiPiSmmMemoryAttributesTableGuid, (VOID **)&MemoryAttributesTable);
90
91 //
92 // Set critical region attribute in page table according to the MemoryAttributesTable
93 //
94 if (MemoryAttributesTable != NULL) {
95 SetMemMapAttributes (MemoryAttributesTable);
96 }
97
98 //
99 // Set page table itself to be read-only
100 //
102
103 //
104 // Configure SMM Code Access Check feature if available.
105 //
107
108 //
109 // Measure performance of SmmCpuFeaturesCompleteSmmReadyToLock() from caller side
110 // as the implementation is provided by platform.
111 //
112 PERF_START (NULL, "SmmCompleteReadyToLock", NULL, 0);
114 PERF_END (NULL, "SmmCompleteReadyToLock", NULL, 0);
115
116 //
117 // Clean SMM ready to lock flag
118 //
119 mSmmReadyToLock = FALSE;
120
122 }
123}
124
129VOID
131 VOID
132 )
133{
135
138 );
139
140 if (Fadt == NULL) {
141 ASSERT (Fadt != NULL);
142 return;
143 }
144
145 mSmiCommandPort = Fadt->SmiCmd;
146 DEBUG ((DEBUG_INFO, "mSmiCommandPort = %x\n", mSmiCommandPort));
147}
148
162EFIAPI
164 IN CONST EFI_GUID *Protocol,
165 IN VOID *Interface,
166 IN EFI_HANDLE Handle
167 )
168{
169 //
170 // Cache a copy of UEFI memory map before we start profiling feature.
171 //
173
174 //
175 // Skip SMM profile initialization if feature is disabled
176 //
177 if (mSmmProfileEnabled) {
178 //
179 // Get Software SMI from FADT
180 //
182
183 //
184 // Initialize protected memory range for patching page table later.
185 //
187 }
188
189 //
190 // Set SMM ready to lock flag and return
191 //
192 mSmmReadyToLock = TRUE;
193 return EFI_SUCCESS;
194}
195
205VOID
207 IN OUT BOOLEAN *RelaxedMode, OPTIONAL
208 IN OUT UINT64 *SyncTimeout, OPTIONAL
209 IN OUT UINT64 *SyncTimeout2 OPTIONAL
210 )
211{
212 if (RelaxedMode != NULL) {
213 *RelaxedMode = (BOOLEAN)(PcdGet8 (PcdCpuSmmSyncMode) == MmCpuSyncModeRelaxedAp);
214 }
215
216 if (SyncTimeout != NULL) {
217 *SyncTimeout = PcdGet64 (PcdCpuSmmApSyncTimeout);
218 }
219
220 if (SyncTimeout2 != NULL) {
221 *SyncTimeout2 = PcdGet64 (PcdCpuSmmApSyncTimeout2);
222 }
223}
224
229VOID
231 VOID
232 )
233{
234 mAcpiS3Enable = PcdGetBool (PcdAcpiS3Enable);
235}
236
243UINTN
245 VOID
246 )
247{
248 return PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
249}
250
261 OUT UINTN *NumberOfCpus,
262 OUT UINTN *MaxNumberOfCpus
263 )
264{
265 EFI_STATUS Status;
266 UINTN Index;
267 UINTN NumberOfEnabledProcessors;
268 UINTN NumberOfProcessors;
269 EFI_MP_SERVICES_PROTOCOL *MpService;
270 EFI_PROCESSOR_INFORMATION *ProcessorInfo;
271
272 if ((NumberOfCpus == NULL) || (MaxNumberOfCpus == NULL)) {
273 ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
274 return NULL;
275 }
276
277 ProcessorInfo = NULL;
278 *NumberOfCpus = 0;
279 *MaxNumberOfCpus = 0;
280
282 Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpService);
283 if (EFI_ERROR (Status)) {
284 ASSERT_EFI_ERROR (Status);
285 return NULL;
286 }
287
289 Status = MpService->GetNumberOfProcessors (MpService, &NumberOfProcessors, &NumberOfEnabledProcessors);
290 if (EFI_ERROR (Status)) {
291 ASSERT_EFI_ERROR (Status);
292 return NULL;
293 }
294
295 ASSERT (NumberOfProcessors <= GetSupportedMaxLogicalProcessorNumber ());
296
298 ProcessorInfo = AllocateZeroPool (sizeof (EFI_PROCESSOR_INFORMATION) * NumberOfProcessors);
299 if (ProcessorInfo == NULL) {
300 ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
301 return NULL;
302 }
303
305 for (Index = 0; Index < NumberOfProcessors; Index++) {
306 Status = MpService->GetProcessorInfo (MpService, Index | CPU_V2_EXTENDED_TOPOLOGY, &ProcessorInfo[Index]);
307 if (EFI_ERROR (Status)) {
308 FreePool (ProcessorInfo);
309 DEBUG ((DEBUG_ERROR, "%a: Failed to get processor information for processor %d\n", __func__, Index));
310 ASSERT_EFI_ERROR (Status);
311 return NULL;
312 }
313 }
314
315 *NumberOfCpus = NumberOfEnabledProcessors;
316
317 ASSERT (*NumberOfCpus <= GetSupportedMaxLogicalProcessorNumber ());
318 //
319 // If support CPU hot plug, we need to allocate resources for possibly hot-added processors
320 //
321 if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
322 *MaxNumberOfCpus = GetSupportedMaxLogicalProcessorNumber ();
323 } else {
324 *MaxNumberOfCpus = *NumberOfCpus;
325 }
326
327 return ProcessorInfo;
328}
329
341EFIAPI
343 IN EFI_HANDLE ImageHandle,
344 IN EFI_SYSTEM_TABLE *SystemTable
345 )
346{
347 EFI_STATUS Status;
348 VOID *Registration;
349
350 //
351 // Save the PcdPteMemoryEncryptionAddressOrMask value into a global variable.
352 // Make sure AddressEncMask is contained to smallest supported address field.
353 //
354 mAddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;
355 DEBUG ((DEBUG_INFO, "mAddressEncMask = 0x%lx\n", mAddressEncMask));
356
357 Status = PiSmmCpuEntryCommon ();
358
359 ASSERT_EFI_ERROR (Status);
360
361 //
362 // Install the SMM Configuration Protocol onto a new handle on the handle database.
363 // The entire SMM Configuration Protocol is allocated from SMRAM, so only a pointer
364 // to an SMRAM address will be present in the handle database
365 //
366 Status = SystemTable->BootServices->InstallMultipleProtocolInterfaces (
367 &gSmmCpuPrivate->SmmCpuHandle,
368 &gEfiSmmConfigurationProtocolGuid,
369 &gSmmCpuPrivate->SmmConfiguration,
370 NULL
371 );
372 ASSERT_EFI_ERROR (Status);
373
374 //
375 // Expose address of CPU Hot Plug Data structure if CPU hot plug is supported.
376 //
377 if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
378 Status = PcdSet64S (PcdCpuHotPlugDataAddress, (UINT64)(UINTN)&mCpuHotPlugData);
379 ASSERT_EFI_ERROR (Status);
380 }
381
382 //
383 // Register SMM Ready To Lock Protocol notification
384 //
385 Status = gMmst->MmRegisterProtocolNotify (
386 &gEfiSmmReadyToLockProtocolGuid,
388 &Registration
389 );
390 ASSERT_EFI_ERROR (Status);
391
392 return Status;
393}
UINT64 UINTN
#define EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
Definition: Acpi20.h:480
EFI_STATUS EFIAPI SmmCpuRendezvous(IN EDKII_SMM_CPU_RENDEZVOUS_PROTOCOL *This, IN BOOLEAN BlockingMode)
Definition: CpuService.c:414
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#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
#define CPU_V2_EXTENDED_TOPOLOGY
Definition: MpService.h:53
VOID UpdateUefiMemMapAttributes(VOID)
VOID GetUefiMemoryMap(VOID)
VOID EFIAPI SmmCpuFeaturesCompleteSmmReadyToLock(VOID)
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define PcdGet8(TokenName)
Definition: PcdLib.h:336
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
#define PcdSet64S(TokenName, Value)
Definition: PcdLib.h:511
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
#define PERF_FUNCTION_END()
#define PERF_END(Handle, Token, Module, TimeStamp)
#define PERF_FUNCTION_BEGIN()
#define PERF_START(Handle, Token, Module, TimeStamp)
VOID ConfigSmmCodeAccessCheck(VOID)
EFI_STATUS PiSmmCpuEntryCommon(VOID)
EFI_STATUS EFIAPI SmmGetSystemConfigurationTable(IN EFI_GUID *TableGuid, OUT VOID **Table)
VOID SetMemMapAttributes(EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable)
VOID SetPageTableAttributes(VOID)
VOID GetAcpiS3EnableFlag(VOID)
VOID PerformRemainingTasks(VOID)
EFI_PROCESSOR_INFORMATION * GetMpInformationFromMpServices(OUT UINTN *NumberOfCpus, OUT UINTN *MaxNumberOfCpus)
EFI_STATUS EFIAPI SmmReadyToLockEventNotify(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
VOID GetSmmCpuSyncConfigData(IN OUT BOOLEAN *RelaxedMode, OPTIONAL IN OUT UINT64 *SyncTimeout, OPTIONAL IN OUT UINT64 *SyncTimeout2 OPTIONAL)
BOOLEAN IsSmmProfileEnabled(VOID)
EFI_STATUS EFIAPI PiCpuSmmEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
VOID GetSmiCommandPort(VOID)
UINTN GetSupportedMaxLogicalProcessorNumber(VOID)
VOID SmmProfileStart(VOID)
Definition: SmmProfile.c:682
VOID InitProtectedMemRange(VOID)
Definition: SmmProfile.c:420
VOID SmmProfileUpdateMemoryAttributes(VOID)
Definition: SmmProfile.c:597
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_ACPI_COMMON_HEADER *EFIAPI EfiLocateFirstAcpiTable(IN UINT32 Signature)
Definition: Acpi.c:441
Definition: Base.h:213