]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.c
MdeModulePkg: Change OPTIONAL keyword usage style
[mirror_edk2.git] / MdeModulePkg / Library / SmmLockBoxLib / SmmLockBoxPeiLib.c
CommitLineData
993532d0 1/** @file\r
2\r
481ffd6f 3Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>\r
993532d0 4\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
993532d0 6\r
7**/\r
8\r
9#include <PiPei.h>\r
10#include <PiDxe.h>\r
11#include <PiSmm.h>\r
12#include <Library/PeiServicesTablePointerLib.h>\r
13#include <Library/PeiServicesLib.h>\r
14#include <Library/BaseLib.h>\r
15#include <Library/BaseMemoryLib.h>\r
16#include <Library/LockBoxLib.h>\r
17#include <Library/HobLib.h>\r
18#include <Library/DebugLib.h>\r
19#include <Library/PcdLib.h>\r
20#include <Protocol/SmmCommunication.h>\r
21#include <Ppi/SmmCommunication.h>\r
22#include <Ppi/SmmAccess.h>\r
23#include <Guid/AcpiS3Context.h>\r
24#include <Guid/SmmLockBox.h>\r
25\r
26#include "SmmLockBoxLibPrivate.h"\r
27\r
28#if defined (MDE_CPU_IA32)\r
29typedef struct _LIST_ENTRY64 LIST_ENTRY64;\r
30struct _LIST_ENTRY64 {\r
31 LIST_ENTRY64 *ForwardLink;\r
32 UINT32 Reserved1;\r
33 LIST_ENTRY64 *BackLink;\r
34 UINT32 Reserved2;\r
35};\r
36\r
37typedef struct {\r
38 EFI_TABLE_HEADER Hdr;\r
39 UINT64 SmmFirmwareVendor;\r
40 UINT64 SmmFirmwareRevision;\r
41 UINT64 SmmInstallConfigurationTable;\r
42 UINT64 SmmIoMemRead;\r
43 UINT64 SmmIoMemWrite;\r
44 UINT64 SmmIoIoRead;\r
45 UINT64 SmmIoIoWrite;\r
46 UINT64 SmmAllocatePool;\r
47 UINT64 SmmFreePool;\r
48 UINT64 SmmAllocatePages;\r
49 UINT64 SmmFreePages;\r
50 UINT64 SmmStartupThisAp;\r
51 UINT64 CurrentlyExecutingCpu;\r
52 UINT64 NumberOfCpus;\r
53 UINT64 CpuSaveStateSize;\r
54 UINT64 CpuSaveState;\r
55 UINT64 NumberOfTableEntries;\r
56 UINT64 SmmConfigurationTable;\r
57} EFI_SMM_SYSTEM_TABLE2_64;\r
58\r
59typedef struct {\r
60 EFI_GUID VendorGuid;\r
61 UINT64 VendorTable;\r
62} EFI_CONFIGURATION_TABLE64;\r
63#endif\r
64\r
65#if defined (MDE_CPU_X64)\r
66typedef LIST_ENTRY LIST_ENTRY64;\r
67typedef EFI_SMM_SYSTEM_TABLE2 EFI_SMM_SYSTEM_TABLE2_64;\r
68typedef EFI_CONFIGURATION_TABLE EFI_CONFIGURATION_TABLE64;\r
69#endif\r
70\r
71/**\r
72 This function return first node of LinkList queue.\r
73\r
74 @param LockBoxQueue LinkList queue\r
75\r
76 @return first node of LinkList queue\r
77**/\r
78LIST_ENTRY *\r
79InternalInitLinkDxe (\r
80 IN LIST_ENTRY *LinkList\r
81 )\r
82{\r
83 if ((sizeof(UINTN) == sizeof(UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) ) {\r
84 //\r
85 // 32 PEI + 64 DXE\r
86 //\r
87 return (LIST_ENTRY *)(((LIST_ENTRY64 *)LinkList)->ForwardLink);\r
88 } else {\r
89 return LinkList->ForwardLink;\r
90 }\r
91}\r
92\r
93/**\r
94 This function return next node of LinkList.\r
95\r
96 @param Link LinkList node\r
97\r
98 @return next node of LinkList\r
99**/\r
100LIST_ENTRY *\r
101InternalNextLinkDxe (\r
102 IN LIST_ENTRY *Link\r
103 )\r
104{\r
105 if ((sizeof(UINTN) == sizeof(UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) ) {\r
106 //\r
107 // 32 PEI + 64 DXE\r
108 //\r
109 return (LIST_ENTRY *)(((LIST_ENTRY64 *)Link)->ForwardLink);\r
110 } else {\r
111 return Link->ForwardLink;\r
112 }\r
113}\r
114\r
115/**\r
116 This function find LockBox by GUID from SMRAM.\r
117\r
118 @param LockBoxQueue The LockBox queue in SMRAM\r
119 @param Guid The guid to indentify the LockBox\r
120\r
121 @return LockBoxData\r
122**/\r
123SMM_LOCK_BOX_DATA *\r
124InternalFindLockBoxByGuidFromSmram (\r
125 IN LIST_ENTRY *LockBoxQueue,\r
126 IN EFI_GUID *Guid\r
127 )\r
128{\r
129 LIST_ENTRY *Link;\r
130 SMM_LOCK_BOX_DATA *LockBox;\r
131\r
132 for (Link = InternalInitLinkDxe (LockBoxQueue);\r
133 Link != LockBoxQueue;\r
134 Link = InternalNextLinkDxe (Link)) {\r
135 LockBox = BASE_CR (\r
136 Link,\r
137 SMM_LOCK_BOX_DATA,\r
138 Link\r
139 );\r
140 if (CompareGuid (&LockBox->Guid, Guid)) {\r
141 return LockBox;\r
142 }\r
143 }\r
144 return NULL;\r
145}\r
146\r
147/**\r
148 Get VendorTable by VendorGuid in Smst.\r
149\r
150 @param Signature Signature of SMM_S3_RESUME_STATE\r
151 @param Smst SMM system table\r
152 @param VendorGuid vendor guid\r
153\r
154 @return vendor table.\r
155**/\r
156VOID *\r
157InternalSmstGetVendorTableByGuid (\r
158 IN UINT64 Signature,\r
159 IN EFI_SMM_SYSTEM_TABLE2 *Smst,\r
160 IN EFI_GUID *VendorGuid\r
161 )\r
162{\r
163 EFI_CONFIGURATION_TABLE *SmmConfigurationTable;\r
164 UINTN NumberOfTableEntries;\r
165 UINTN Index;\r
166 EFI_SMM_SYSTEM_TABLE2_64 *Smst64;\r
167 EFI_CONFIGURATION_TABLE64 *SmmConfigurationTable64;\r
168\r
169 if ((sizeof(UINTN) == sizeof(UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {\r
170 //\r
171 // 32 PEI + 64 DXE\r
172 //\r
173 Smst64 = (EFI_SMM_SYSTEM_TABLE2_64 *)Smst;\r
174 SmmConfigurationTable64 = (EFI_CONFIGURATION_TABLE64 *)(UINTN)Smst64->SmmConfigurationTable;\r
175 NumberOfTableEntries = (UINTN)Smst64->NumberOfTableEntries;\r
176 for (Index = 0; Index < NumberOfTableEntries; Index++) {\r
177 if (CompareGuid (&SmmConfigurationTable64[Index].VendorGuid, VendorGuid)) {\r
178 return (VOID *)(UINTN)SmmConfigurationTable64[Index].VendorTable;\r
179 }\r
180 }\r
181 return NULL;\r
182 } else {\r
183 SmmConfigurationTable = Smst->SmmConfigurationTable;\r
184 NumberOfTableEntries = Smst->NumberOfTableEntries;\r
185 for (Index = 0; Index < NumberOfTableEntries; Index++) {\r
186 if (CompareGuid (&SmmConfigurationTable[Index].VendorGuid, VendorGuid)) {\r
187 return (VOID *)SmmConfigurationTable[Index].VendorTable;\r
188 }\r
189 }\r
190 return NULL;\r
191 }\r
192}\r
193\r
194/**\r
195 Get SMM LockBox context.\r
196\r
197 @return SMM LockBox context.\r
198**/\r
199SMM_LOCK_BOX_CONTEXT *\r
200InternalGetSmmLockBoxContext (\r
201 VOID\r
202 )\r
203{\r
204 EFI_SMRAM_DESCRIPTOR *SmramDescriptor;\r
205 SMM_S3_RESUME_STATE *SmmS3ResumeState;\r
206 VOID *GuidHob;\r
207 SMM_LOCK_BOX_CONTEXT *SmmLockBoxContext;\r
208\r
209 GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid);\r
210 ASSERT (GuidHob != NULL);\r
211 SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *) GET_GUID_HOB_DATA (GuidHob);\r
212 SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart;\r
213\r
214 SmmLockBoxContext = (SMM_LOCK_BOX_CONTEXT *)InternalSmstGetVendorTableByGuid (\r
215 SmmS3ResumeState->Signature,\r
216 (EFI_SMM_SYSTEM_TABLE2 *)(UINTN)SmmS3ResumeState->Smst,\r
217 &gEfiSmmLockBoxCommunicationGuid\r
218 );\r
219 ASSERT (SmmLockBoxContext != NULL);\r
220\r
221 return SmmLockBoxContext;\r
222}\r
223\r
224/**\r
225 This function will restore confidential information from lockbox in SMRAM directly.\r
226\r
227 @param Guid the guid to identify the confidential information\r
228 @param Buffer the address of the restored confidential information\r
229 NULL means restored to original address, Length MUST be NULL at same time.\r
230 @param Length the length of the restored confidential information\r
231\r
232 @retval RETURN_SUCCESS the information is restored successfully.\r
d1102dba 233 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no\r
993532d0 234 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.\r
235 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.\r
236 @retval RETURN_NOT_FOUND the requested GUID not found.\r
237**/\r
238EFI_STATUS\r
239InternalRestoreLockBoxFromSmram (\r
240 IN GUID *Guid,\r
e3917e22 241 IN VOID *Buffer OPTIONAL,\r
993532d0 242 IN OUT UINTN *Length OPTIONAL\r
243 )\r
244{\r
245 PEI_SMM_ACCESS_PPI *SmmAccess;\r
246 UINTN Index;\r
247 EFI_STATUS Status;\r
248 SMM_LOCK_BOX_CONTEXT *SmmLockBoxContext;\r
249 LIST_ENTRY *LockBoxQueue;\r
250 SMM_LOCK_BOX_DATA *LockBox;\r
251 VOID *RestoreBuffer;\r
252\r
253 //\r
254 // Get needed resource\r
255 //\r
256 Status = PeiServicesLocatePpi (\r
257 &gPeiSmmAccessPpiGuid,\r
258 0,\r
259 NULL,\r
260 (VOID **)&SmmAccess\r
261 );\r
262 if (!EFI_ERROR (Status)) {\r
263 for (Index = 0; !EFI_ERROR (Status); Index++) {\r
264 Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);\r
265 }\r
266 }\r
267\r
268 //\r
269 // Get LockBox context\r
270 //\r
271 SmmLockBoxContext = InternalGetSmmLockBoxContext ();\r
272 LockBoxQueue = (LIST_ENTRY *)(UINTN)SmmLockBoxContext->LockBoxDataAddress;\r
273\r
274 //\r
275 // We do NOT check Buffer address in SMRAM, because if SMRAM not locked, we trust the caller.\r
276 //\r
277\r
278 //\r
279 // Restore this, Buffer and Length MUST be both NULL or both non-NULL\r
280 //\r
281\r
282 //\r
283 // Find LockBox\r
284 //\r
285 LockBox = InternalFindLockBoxByGuidFromSmram (LockBoxQueue, Guid);\r
286 if (LockBox == NULL) {\r
287 //\r
288 // Not found\r
289 //\r
290 return EFI_NOT_FOUND;\r
291 }\r
292\r
293 //\r
294 // Set RestoreBuffer\r
295 //\r
296 if (Buffer != NULL) {\r
297 //\r
298 // restore to new buffer\r
299 //\r
300 RestoreBuffer = Buffer;\r
301 } else {\r
302 //\r
303 // restore to original buffer\r
304 //\r
305 if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) == 0) {\r
306 return EFI_WRITE_PROTECTED;\r
307 }\r
308 RestoreBuffer = (VOID *)(UINTN)LockBox->Buffer;\r
309 }\r
310\r
311 //\r
312 // Set RestoreLength\r
313 //\r
314 if (Length != NULL) {\r
315 if (*Length < (UINTN)LockBox->Length) {\r
316 //\r
317 // Input buffer is too small to hold all data.\r
318 //\r
319 *Length = (UINTN)LockBox->Length;\r
320 return EFI_BUFFER_TOO_SMALL;\r
321 }\r
322 *Length = (UINTN)LockBox->Length;\r
323 }\r
324\r
325 //\r
326 // Restore data\r
327 //\r
328 CopyMem (RestoreBuffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);\r
329\r
330 //\r
331 // Done\r
332 //\r
333 return EFI_SUCCESS;\r
334}\r
335\r
336/**\r
337 This function will restore confidential information from all lockbox which have RestoreInPlace attribute.\r
338\r
339 @retval RETURN_SUCCESS the information is restored successfully.\r
340**/\r
341EFI_STATUS\r
342InternalRestoreAllLockBoxInPlaceFromSmram (\r
343 VOID\r
344 )\r
345{\r
346 PEI_SMM_ACCESS_PPI *SmmAccess;\r
347 UINTN Index;\r
348 EFI_STATUS Status;\r
349 SMM_LOCK_BOX_CONTEXT *SmmLockBoxContext;\r
350 LIST_ENTRY *LockBoxQueue;\r
351 SMM_LOCK_BOX_DATA *LockBox;\r
352 LIST_ENTRY *Link;\r
353\r
354 //\r
355 // Get needed resource\r
356 //\r
357 Status = PeiServicesLocatePpi (\r
358 &gPeiSmmAccessPpiGuid,\r
359 0,\r
360 NULL,\r
361 (VOID **)&SmmAccess\r
362 );\r
363 if (!EFI_ERROR (Status)) {\r
364 for (Index = 0; !EFI_ERROR (Status); Index++) {\r
365 Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);\r
366 }\r
367 }\r
368\r
369 //\r
370 // Get LockBox context\r
371 //\r
372 SmmLockBoxContext = InternalGetSmmLockBoxContext ();\r
373 LockBoxQueue = (LIST_ENTRY *)(UINTN)SmmLockBoxContext->LockBoxDataAddress;\r
374\r
375 //\r
376 // We do NOT check Buffer address in SMRAM, because if SMRAM not locked, we trust the caller.\r
377 //\r
378\r
379 //\r
380 // Restore all, Buffer and Length MUST be NULL\r
381 //\r
382 for (Link = InternalInitLinkDxe (LockBoxQueue);\r
383 Link != LockBoxQueue;\r
384 Link = InternalNextLinkDxe (Link)) {\r
385 LockBox = BASE_CR (\r
386 Link,\r
387 SMM_LOCK_BOX_DATA,\r
388 Link\r
389 );\r
390 if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0) {\r
391 //\r
392 // Restore data\r
393 //\r
394 CopyMem ((VOID *)(UINTN)LockBox->Buffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);\r
395 }\r
396 }\r
397 //\r
398 // Done\r
399 //\r
400 return EFI_SUCCESS;\r
401}\r
402\r
403/**\r
404 This function will save confidential information to lockbox.\r
405\r
406 @param Guid the guid to identify the confidential information\r
407 @param Buffer the address of the confidential information\r
408 @param Length the length of the confidential information\r
409\r
410 @retval RETURN_SUCCESS the information is saved successfully.\r
411 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0\r
412 @retval RETURN_ALREADY_STARTED the requested GUID already exist.\r
413 @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.\r
414 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface\r
415 @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
416 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
417**/\r
418RETURN_STATUS\r
419EFIAPI\r
420SaveLockBox (\r
421 IN GUID *Guid,\r
422 IN VOID *Buffer,\r
423 IN UINTN Length\r
424 )\r
425{\r
426 ASSERT (FALSE);\r
427\r
428 //\r
429 // No support to save at PEI phase\r
430 //\r
431 return RETURN_UNSUPPORTED;\r
432}\r
433\r
434/**\r
435 This function will set lockbox attributes.\r
436\r
437 @param Guid the guid to identify the confidential information\r
438 @param Attributes the attributes of the lockbox\r
439\r
440 @retval RETURN_SUCCESS the information is saved successfully.\r
441 @retval RETURN_INVALID_PARAMETER attributes is invalid.\r
442 @retval RETURN_NOT_FOUND the requested GUID not found.\r
443 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface\r
444 @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
445 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
446**/\r
447RETURN_STATUS\r
448EFIAPI\r
449SetLockBoxAttributes (\r
450 IN GUID *Guid,\r
451 IN UINT64 Attributes\r
452 )\r
453{\r
454 ASSERT (FALSE);\r
455\r
456 //\r
457 // No support to save at PEI phase\r
458 //\r
459 return RETURN_UNSUPPORTED;\r
460}\r
461\r
462/**\r
463 This function will update confidential information to lockbox.\r
464\r
465 @param Guid the guid to identify the original confidential information\r
466 @param Offset the offset of the original confidential information\r
467 @param Buffer the address of the updated confidential information\r
468 @param Length the length of the updated confidential information\r
469\r
470 @retval RETURN_SUCCESS the information is saved successfully.\r
471 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0.\r
472 @retval RETURN_NOT_FOUND the requested GUID not found.\r
99383667
HW
473 @retval RETURN_BUFFER_TOO_SMALL for lockbox without attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,\r
474 the original buffer to too small to hold new information.\r
475 @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,\r
476 no enough resource to save the information.\r
993532d0 477 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface\r
478 @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
479 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
480**/\r
481RETURN_STATUS\r
482EFIAPI\r
483UpdateLockBox (\r
484 IN GUID *Guid,\r
485 IN UINTN Offset,\r
486 IN VOID *Buffer,\r
487 IN UINTN Length\r
488 )\r
489{\r
490 ASSERT (FALSE);\r
491\r
492 //\r
493 // No support to update at PEI phase\r
494 //\r
495 return RETURN_UNSUPPORTED;\r
496}\r
497\r
498/**\r
499 This function will restore confidential information from lockbox.\r
500\r
501 @param Guid the guid to identify the confidential information\r
502 @param Buffer the address of the restored confidential information\r
503 NULL means restored to original address, Length MUST be NULL at same time.\r
504 @param Length the length of the restored confidential information\r
505\r
506 @retval RETURN_SUCCESS the information is restored successfully.\r
507 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL.\r
d1102dba 508 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no\r
993532d0 509 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.\r
510 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.\r
511 @retval RETURN_NOT_FOUND the requested GUID not found.\r
512 @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
513 @retval RETURN_ACCESS_DENIED not allow to restore to the address\r
514 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
515**/\r
516RETURN_STATUS\r
517EFIAPI\r
518RestoreLockBox (\r
519 IN GUID *Guid,\r
e3917e22 520 IN VOID *Buffer OPTIONAL,\r
993532d0 521 IN OUT UINTN *Length OPTIONAL\r
522 )\r
523{\r
524 EFI_STATUS Status;\r
525 EFI_PEI_SMM_COMMUNICATION_PPI *SmmCommunicationPpi;\r
526 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *LockBoxParameterRestore;\r
527 EFI_SMM_COMMUNICATE_HEADER *CommHeader;\r
528 UINT8 CommBuffer[sizeof(EFI_GUID) + sizeof(UINT64) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE)];\r
529 UINTN CommSize;\r
530 UINT64 MessageLength;\r
531\r
532 //\r
533 // Please aware that there is UINTN in EFI_SMM_COMMUNICATE_HEADER. It might be UINT64 in DXE, while it is UINT32 in PEI.\r
534 // typedef struct {\r
535 // EFI_GUID HeaderGuid;\r
536 // UINTN MessageLength;\r
537 // UINT8 Data[1];\r
538 // } EFI_SMM_COMMUNICATE_HEADER;\r
539 //\r
540\r
481ffd6f 541 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreLockBox - Enter\n"));\r
993532d0 542\r
543 //\r
544 // Basic check\r
545 //\r
546 if ((Guid == NULL) ||\r
547 ((Buffer == NULL) && (Length != NULL)) ||\r
548 ((Buffer != NULL) && (Length == NULL))) {\r
549 return EFI_INVALID_PARAMETER;\r
550 }\r
551\r
552 //\r
553 // Get needed resource\r
554 //\r
555 Status = PeiServicesLocatePpi (\r
556 &gEfiPeiSmmCommunicationPpiGuid,\r
557 0,\r
558 NULL,\r
559 (VOID **)&SmmCommunicationPpi\r
560 );\r
561 if (EFI_ERROR (Status)) {\r
481ffd6f 562 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib LocatePpi - (%r)\n", Status));\r
bd3afeb1 563 Status = InternalRestoreLockBoxFromSmram (Guid, Buffer, Length);\r
481ffd6f 564 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreLockBox - Exit (%r)\n", Status));\r
bd3afeb1 565 return Status;\r
993532d0 566 }\r
567\r
568 //\r
569 // Prepare parameter\r
570 //\r
571 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];\r
572 CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid));\r
573 if ((sizeof(UINTN) == sizeof(UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) ) {\r
574 MessageLength = sizeof(*LockBoxParameterRestore);\r
575 CopyMem (&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength)], &MessageLength, sizeof(MessageLength));\r
576 } else {\r
577 CommHeader->MessageLength = sizeof(*LockBoxParameterRestore);\r
578 }\r
579\r
481ffd6f 580 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib CommBuffer - %x\n", &CommBuffer[0]));\r
993532d0 581 if ((sizeof(UINTN) == sizeof(UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) ) {\r
582 LockBoxParameterRestore = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof(UINT64)];\r
583 } else {\r
584 LockBoxParameterRestore = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof(UINTN)];\r
585 }\r
481ffd6f 586 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib LockBoxParameterRestore - %x\n", LockBoxParameterRestore));\r
993532d0 587 LockBoxParameterRestore->Header.Command = EFI_SMM_LOCK_BOX_COMMAND_RESTORE;\r
588 LockBoxParameterRestore->Header.DataLength = sizeof(*LockBoxParameterRestore);\r
589 LockBoxParameterRestore->Header.ReturnStatus = (UINT64)-1;\r
590 if (Guid != 0) {\r
591 CopyMem (&LockBoxParameterRestore->Guid, Guid, sizeof(*Guid));\r
592 } else {\r
593 ZeroMem (&LockBoxParameterRestore->Guid, sizeof(*Guid));\r
594 }\r
595 LockBoxParameterRestore->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;\r
596 if (Length != NULL) {\r
597 LockBoxParameterRestore->Length = (EFI_PHYSICAL_ADDRESS)*Length;\r
598 } else {\r
599 LockBoxParameterRestore->Length = 0;\r
600 }\r
601\r
602 //\r
603 // Send command\r
604 //\r
605 CommSize = sizeof(CommBuffer);\r
606 Status = SmmCommunicationPpi->Communicate (\r
607 SmmCommunicationPpi,\r
608 &CommBuffer[0],\r
609 &CommSize\r
610 );\r
611 if (Status == EFI_NOT_STARTED) {\r
612 //\r
613 // Pei SMM communication not ready yet, so we access SMRAM directly\r
614 //\r
481ffd6f 615 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib Communicate - (%r)\n", Status));\r
993532d0 616 Status = InternalRestoreLockBoxFromSmram (Guid, Buffer, Length);\r
617 LockBoxParameterRestore->Header.ReturnStatus = (UINT64)Status;\r
618 if (Length != NULL) {\r
619 LockBoxParameterRestore->Length = (UINT64)*Length;\r
620 }\r
621 }\r
993532d0 622\r
623 if (Length != NULL) {\r
624 *Length = (UINTN)LockBoxParameterRestore->Length;\r
625 }\r
626\r
627 Status = (EFI_STATUS)LockBoxParameterRestore->Header.ReturnStatus;\r
628 if (Status != EFI_SUCCESS) {\r
629 // Need or MAX_BIT, because there might be case that SMM is X64 while PEI is IA32.\r
630 Status |= MAX_BIT;\r
631 }\r
632\r
481ffd6f 633 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreLockBox - Exit (%r)\n", Status));\r
993532d0 634\r
635 //\r
636 // Done\r
637 //\r
638 return Status;\r
639}\r
640\r
641/**\r
642 This function will restore confidential information from all lockbox which have RestoreInPlace attribute.\r
643\r
644 @retval RETURN_SUCCESS the information is restored successfully.\r
645 @retval RETURN_NOT_STARTED it is too early to invoke this interface\r
646 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.\r
647**/\r
648RETURN_STATUS\r
649EFIAPI\r
650RestoreAllLockBoxInPlace (\r
651 VOID\r
652 )\r
653{\r
654 EFI_STATUS Status;\r
655 EFI_PEI_SMM_COMMUNICATION_PPI *SmmCommunicationPpi;\r
656 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *LockBoxParameterRestoreAllInPlace;\r
657 EFI_SMM_COMMUNICATE_HEADER *CommHeader;\r
658 UINT8 CommBuffer[sizeof(EFI_GUID) + sizeof(UINT64) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE)];\r
659 UINTN CommSize;\r
660 UINT64 MessageLength;\r
661\r
662 //\r
663 // Please aware that there is UINTN in EFI_SMM_COMMUNICATE_HEADER. It might be UINT64 in DXE, while it is UINT32 in PEI.\r
664 // typedef struct {\r
665 // EFI_GUID HeaderGuid;\r
666 // UINTN MessageLength;\r
667 // UINT8 Data[1];\r
668 // } EFI_SMM_COMMUNICATE_HEADER;\r
669 //\r
670\r
481ffd6f 671 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreAllLockBoxInPlace - Enter\n"));\r
993532d0 672\r
673 //\r
674 // Get needed resource\r
675 //\r
676 Status = PeiServicesLocatePpi (\r
677 &gEfiPeiSmmCommunicationPpiGuid,\r
678 0,\r
679 NULL,\r
680 (VOID **)&SmmCommunicationPpi\r
681 );\r
682 if (EFI_ERROR (Status)) {\r
481ffd6f 683 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib LocatePpi - (%r)\n", Status));\r
bd3afeb1 684 Status = InternalRestoreAllLockBoxInPlaceFromSmram ();\r
481ffd6f 685 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreAllLockBoxInPlace - Exit (%r)\n", Status));\r
bd3afeb1 686 return Status;\r
993532d0 687 }\r
688\r
689 //\r
690 // Prepare parameter\r
691 //\r
692 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];\r
693 CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid));\r
694 if ((sizeof(UINTN) == sizeof(UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) ) {\r
695 MessageLength = sizeof(*LockBoxParameterRestoreAllInPlace);\r
696 CopyMem (&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength)], &MessageLength, sizeof(MessageLength));\r
697 } else {\r
698 CommHeader->MessageLength = sizeof(*LockBoxParameterRestoreAllInPlace);\r
699 }\r
700\r
701 if ((sizeof(UINTN) == sizeof(UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) ) {\r
702 LockBoxParameterRestoreAllInPlace = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof(UINT64)];\r
703 } else {\r
704 LockBoxParameterRestoreAllInPlace = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof(UINTN)];\r
705 }\r
706 LockBoxParameterRestoreAllInPlace->Header.Command = EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE;\r
707 LockBoxParameterRestoreAllInPlace->Header.DataLength = sizeof(*LockBoxParameterRestoreAllInPlace);\r
708 LockBoxParameterRestoreAllInPlace->Header.ReturnStatus = (UINT64)-1;\r
709\r
710 //\r
711 // Send command\r
712 //\r
713 CommSize = sizeof(CommBuffer);\r
714 Status = SmmCommunicationPpi->Communicate (\r
715 SmmCommunicationPpi,\r
716 &CommBuffer[0],\r
717 &CommSize\r
718 );\r
719 if (Status == EFI_NOT_STARTED) {\r
720 //\r
721 // Pei SMM communication not ready yet, so we access SMRAM directly\r
722 //\r
481ffd6f 723 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib Communicate - (%r)\n", Status));\r
993532d0 724 Status = InternalRestoreAllLockBoxInPlaceFromSmram ();\r
725 LockBoxParameterRestoreAllInPlace->Header.ReturnStatus = (UINT64)Status;\r
726 }\r
727 ASSERT_EFI_ERROR (Status);\r
728\r
729 Status = (EFI_STATUS)LockBoxParameterRestoreAllInPlace->Header.ReturnStatus;\r
730 if (Status != EFI_SUCCESS) {\r
731 // Need or MAX_BIT, because there might be case that SMM is X64 while PEI is IA32.\r
732 Status |= MAX_BIT;\r
733 }\r
734\r
481ffd6f 735 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreAllLockBoxInPlace - Exit (%r)\n", Status));\r
993532d0 736\r
737 //\r
738 // Done\r
739 //\r
740 return Status;\r
741}\r