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