TianoCore EDK2 master
Loading...
Searching...
No Matches
PiSmmCommunicationPei.c
Go to the documentation of this file.
1
9#include <PiPei.h>
10#include <PiDxe.h>
11#include <PiSmm.h>
14#include <Library/BaseLib.h>
16#include <Library/HobLib.h>
17#include <Library/DebugLib.h>
20#include <Ppi/SmmAccess.h>
21#include <Ppi/SmmControl.h>
22#include <Guid/AcpiS3Context.h>
23
25
65#if defined (MDE_CPU_IA32)
66typedef struct {
68 UINT64 SmmFirmwareVendor;
69 UINT64 SmmFirmwareRevision;
71 UINT64 SmmIoMemRead;
72 UINT64 SmmIoMemWrite;
73 UINT64 SmmIoIoRead;
74 UINT64 SmmIoIoWrite;
75 UINT64 SmmAllocatePool;
76 UINT64 SmmFreePool;
77 UINT64 SmmAllocatePages;
78 UINT64 SmmFreePages;
79 UINT64 SmmStartupThisAp;
80 UINT64 CurrentlyExecutingCpu;
81 UINT64 NumberOfCpus;
82 UINT64 CpuSaveStateSize;
83 UINT64 CpuSaveState;
84 UINT64 NumberOfTableEntries;
85 UINT64 SmmConfigurationTable;
86} EFI_SMM_SYSTEM_TABLE2_64;
87
88typedef struct {
89 EFI_GUID VendorGuid;
90 UINT64 VendorTable;
91} EFI_CONFIGURATION_TABLE64;
92#endif
93
94#if defined (MDE_CPU_X64)
95typedef EFI_SMM_SYSTEM_TABLE2 EFI_SMM_SYSTEM_TABLE2_64;
96typedef EFI_CONFIGURATION_TABLE EFI_CONFIGURATION_TABLE64;
97#endif
98
114EFIAPI
117 IN OUT VOID *CommBuffer,
118 IN OUT UINTN *CommSize
119 );
120
121EFI_PEI_SMM_COMMUNICATION_PPI mSmmCommunicationPpi = { Communicate };
122
123EFI_PEI_PPI_DESCRIPTOR mPpiList = {
124 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
125 &gEfiPeiSmmCommunicationPpiGuid,
126 &mSmmCommunicationPpi
127};
128
136 VOID
137 )
138{
139 EFI_HOB_GUID_TYPE *GuidHob;
140 EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext;
141
142 GuidHob = GetFirstGuidHob (&gEfiPeiSmmCommunicationPpiGuid);
143 ASSERT (GuidHob != NULL);
144
145 SmmCommunicationContext = (EFI_SMM_COMMUNICATION_CONTEXT *)GET_GUID_HOB_DATA (GuidHob);
146
147 return SmmCommunicationContext;
148}
149
155VOID
157 IN EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext
158 )
159{
161 UINTN BufferSize;
162
163 BufferSize = sizeof (*SmmCommunicationContext);
164 Hob.Raw = BuildGuidHob (
165 &gEfiPeiSmmCommunicationPpiGuid,
166 BufferSize
167 );
168 ASSERT (Hob.Raw);
169
170 CopyMem ((VOID *)Hob.Raw, SmmCommunicationContext, sizeof (*SmmCommunicationContext));
171}
172
182VOID *
184 IN UINT64 Signature,
186 IN EFI_GUID *VendorGuid
187 )
188{
189 EFI_CONFIGURATION_TABLE *SmmConfigurationTable;
190 UINTN NumberOfTableEntries;
191 UINTN Index;
192 EFI_SMM_SYSTEM_TABLE2_64 *Smst64;
193 EFI_CONFIGURATION_TABLE64 *SmmConfigurationTable64;
194
195 if ((sizeof (UINTN) == sizeof (UINT32)) && (Signature == SMM_S3_RESUME_SMM_64)) {
196 //
197 // 32 PEI + 64 DXE
198 //
199 Smst64 = (EFI_SMM_SYSTEM_TABLE2_64 *)Smst;
200 DEBUG ((DEBUG_INFO, "InitCommunicationContext - SmmConfigurationTable: %x\n", Smst64->SmmConfigurationTable));
201 DEBUG ((DEBUG_INFO, "InitCommunicationContext - NumberOfTableEntries: %x\n", Smst64->NumberOfTableEntries));
202 SmmConfigurationTable64 = (EFI_CONFIGURATION_TABLE64 *)(UINTN)Smst64->SmmConfigurationTable;
203 NumberOfTableEntries = (UINTN)Smst64->NumberOfTableEntries;
204 for (Index = 0; Index < NumberOfTableEntries; Index++) {
205 if (CompareGuid (&SmmConfigurationTable64[Index].VendorGuid, VendorGuid)) {
206 return (VOID *)(UINTN)SmmConfigurationTable64[Index].VendorTable;
207 }
208 }
209
210 return NULL;
211 } else {
212 DEBUG ((DEBUG_INFO, "InitCommunicationContext - SmmConfigurationTable: %x\n", Smst->SmmConfigurationTable));
213 DEBUG ((DEBUG_INFO, "InitCommunicationContext - NumberOfTableEntries: %x\n", Smst->NumberOfTableEntries));
214 SmmConfigurationTable = Smst->SmmConfigurationTable;
215 NumberOfTableEntries = Smst->NumberOfTableEntries;
216 for (Index = 0; Index < NumberOfTableEntries; Index++) {
217 if (CompareGuid (&SmmConfigurationTable[Index].VendorGuid, VendorGuid)) {
218 return (VOID *)SmmConfigurationTable[Index].VendorTable;
219 }
220 }
221
222 return NULL;
223 }
224}
225
229VOID
231 VOID
232 )
233{
234 EFI_SMRAM_DESCRIPTOR *SmramDescriptor;
235 SMM_S3_RESUME_STATE *SmmS3ResumeState;
236 VOID *GuidHob;
237 EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext;
238
239 GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid);
240 ASSERT (GuidHob != NULL);
241 SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *)GET_GUID_HOB_DATA (GuidHob);
242 SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart;
243
244 DEBUG ((DEBUG_INFO, "InitCommunicationContext - SmmS3ResumeState: %x\n", SmmS3ResumeState));
245 DEBUG ((DEBUG_INFO, "InitCommunicationContext - Smst: %x\n", SmmS3ResumeState->Smst));
246
248 SmmS3ResumeState->Signature,
249 (EFI_SMM_SYSTEM_TABLE2 *)(UINTN)SmmS3ResumeState->Smst,
250 &gEfiPeiSmmCommunicationPpiGuid
251 );
252 ASSERT (SmmCommunicationContext != NULL);
253
254 SetCommunicationContext (SmmCommunicationContext);
255
256 return;
257}
258
274EFIAPI
277 IN OUT VOID *CommBuffer,
278 IN OUT UINTN *CommSize
279 )
280{
281 EFI_STATUS Status;
282 PEI_SMM_CONTROL_PPI *SmmControl;
283 PEI_SMM_ACCESS_PPI *SmmAccess;
284 UINT8 SmiCommand;
285 UINTN Size;
286 EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext;
287
288 DEBUG ((DEBUG_INFO, "PiSmmCommunicationPei Communicate Enter\n"));
289
290 if (CommBuffer == NULL) {
291 return EFI_INVALID_PARAMETER;
292 }
293
294 //
295 // Get needed resource
296 //
297 Status = PeiServicesLocatePpi (
298 &gPeiSmmControlPpiGuid,
299 0,
300 NULL,
301 (VOID **)&SmmControl
302 );
303 if (EFI_ERROR (Status)) {
304 return EFI_NOT_STARTED;
305 }
306
307 Status = PeiServicesLocatePpi (
308 &gPeiSmmAccessPpiGuid,
309 0,
310 NULL,
311 (VOID **)&SmmAccess
312 );
313 if (EFI_ERROR (Status)) {
314 return EFI_NOT_STARTED;
315 }
316
317 //
318 // Check SMRAM locked, it should be done after SMRAM lock.
319 //
320 if (!SmmAccess->LockState) {
321 DEBUG ((DEBUG_INFO, "PiSmmCommunicationPei LockState - %x\n", (UINTN)SmmAccess->LockState));
322 return EFI_NOT_STARTED;
323 }
324
325 SmmCommunicationContext = GetCommunicationContext ();
326 DEBUG ((DEBUG_INFO, "PiSmmCommunicationPei BufferPtrAddress - 0x%016lx, BufferPtr: 0x%016lx\n", SmmCommunicationContext->BufferPtrAddress, *(EFI_PHYSICAL_ADDRESS *)(UINTN)SmmCommunicationContext->BufferPtrAddress));
327
328 //
329 // No need to check if BufferPtr is 0, because it is in PEI phase.
330 //
331 *(EFI_PHYSICAL_ADDRESS *)(UINTN)SmmCommunicationContext->BufferPtrAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CommBuffer;
332 DEBUG ((DEBUG_INFO, "PiSmmCommunicationPei CommBuffer - %x\n", (UINTN)CommBuffer));
333
334 //
335 // Send command
336 //
337 SmiCommand = (UINT8)SmmCommunicationContext->SwSmiNumber;
338 Size = sizeof (SmiCommand);
339 Status = SmmControl->Trigger (
341 SmmControl,
342 (INT8 *)&SmiCommand,
343 &Size,
344 FALSE,
345 0
346 );
347 ASSERT_EFI_ERROR (Status);
348
349 //
350 // Setting BufferPtr to 0 means this transaction is done.
351 //
352 *(EFI_PHYSICAL_ADDRESS *)(UINTN)SmmCommunicationContext->BufferPtrAddress = 0;
353
354 DEBUG ((DEBUG_INFO, "PiSmmCommunicationPei Communicate Exit\n"));
355
356 return EFI_SUCCESS;
357}
358
369EFIAPI
371 IN EFI_PEI_FILE_HANDLE FileHandle,
372 IN CONST EFI_PEI_SERVICES **PeiServices
373 )
374{
375 EFI_STATUS Status;
376 PEI_SMM_ACCESS_PPI *SmmAccess;
377 EFI_BOOT_MODE BootMode;
378 UINTN Index;
379
380 BootMode = GetBootModeHob ();
381 if (BootMode != BOOT_ON_S3_RESUME) {
382 return EFI_UNSUPPORTED;
383 }
384
385 Status = PeiServicesLocatePpi (
386 &gPeiSmmAccessPpiGuid,
387 0,
388 NULL,
389 (VOID **)&SmmAccess
390 );
391 if (EFI_ERROR (Status)) {
392 return EFI_NOT_STARTED;
393 }
394
395 //
396 // Check SMRAM locked, it should be done before SMRAM lock.
397 //
398 if (SmmAccess->LockState) {
399 DEBUG ((DEBUG_INFO, "PiSmmCommunicationPei LockState - %x\n", (UINTN)SmmAccess->LockState));
400 return EFI_ACCESS_DENIED;
401 }
402
403 //
404 // Open all SMRAM
405 //
406 for (Index = 0; !EFI_ERROR (Status); Index++) {
407 Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);
408 }
409
411
412 PeiServicesInstallPpi (&mPpiList);
413
414 return RETURN_SUCCESS;
415}
UINT64 UINTN
CONST EFI_PEI_SERVICES **EFIAPI GetPeiServicesTablePointer(VOID)
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
VOID *EFIAPI BuildGuidHob(IN CONST EFI_GUID *Guid, IN UINTN DataLength)
Definition: HobLib.c:336
EFI_BOOT_MODE EFIAPI GetBootModeHob(VOID)
Definition: HobLib.c:240
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
EFI_STATUS EFIAPI PeiServicesInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
EFI_STATUS EFIAPI SmmInstallConfigurationTable(IN CONST EFI_SMM_SYSTEM_TABLE2 *SystemTable, IN CONST EFI_GUID *Guid, IN VOID *Table, IN UINTN TableSize)
EFI_STATUS EFIAPI SmmFreePages(IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages)
Definition: Page.c:934
EFI_STATUS EFIAPI SmmAllocatePages(IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN NumberOfPages, OUT EFI_PHYSICAL_ADDRESS *Memory)
Definition: Page.c:723
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define RETURN_SUCCESS
Definition: Base.h:1066
#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
UINT32 EFI_BOOT_MODE
Definition: PiBootMode.h:18
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
EFI_STATUS EFIAPI PiSmmCommunicationPeiEntryPoint(IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices)
VOID SetCommunicationContext(IN EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext)
VOID * InternalSmstGetVendorTableByGuid(IN UINT64 Signature, IN EFI_SMM_SYSTEM_TABLE2 *Smst, IN EFI_GUID *VendorGuid)
VOID InitCommunicationContext(VOID)
EFI_STATUS EFIAPI Communicate(IN CONST EFI_PEI_SMM_COMMUNICATION_PPI *This, IN OUT VOID *CommBuffer, IN OUT UINTN *CommSize)
EFI_SMM_COMMUNICATION_CONTEXT * GetCommunicationContext(VOID)
EFI_STATUS EFIAPI SmmFreePool(IN VOID *Buffer)
Definition: Pool.c:445
EFI_STATUS EFIAPI SmmAllocatePool(IN EFI_MEMORY_TYPE PoolType, IN UINTN Size, OUT VOID **Buffer)
Definition: Pool.c:338
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_STATUS EFIAPI SmmStartupThisAp(IN EFI_AP_PROCEDURE Procedure, IN UINTN CpuIndex, IN OUT VOID *ProcArguments OPTIONAL)
Definition: MpService.c:1434
EFI_PHYSICAL_ADDRESS CpuStart
Definition: PiMultiPhase.h:127
Definition: Base.h:213