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