]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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 {
136 LockBox = BASE_CR (
137 Link,
138 SMM_LOCK_BOX_DATA,
139 Link
140 );
141 if (CompareGuid (&LockBox->Guid, Guid)) {
142 return LockBox;
143 }
144 }
145
146 return NULL;
147 }
148
149 /**
150 Get VendorTable by VendorGuid in Smst.
151
152 @param Signature Signature of SMM_S3_RESUME_STATE
153 @param Smst SMM system table
154 @param VendorGuid vendor guid
155
156 @return vendor table.
157 **/
158 VOID *
159 InternalSmstGetVendorTableByGuid (
160 IN UINT64 Signature,
161 IN EFI_SMM_SYSTEM_TABLE2 *Smst,
162 IN EFI_GUID *VendorGuid
163 )
164 {
165 EFI_CONFIGURATION_TABLE *SmmConfigurationTable;
166 UINTN NumberOfTableEntries;
167 UINTN Index;
168 EFI_SMM_SYSTEM_TABLE2_64 *Smst64;
169 EFI_CONFIGURATION_TABLE64 *SmmConfigurationTable64;
170
171 if ((sizeof (UINTN) == sizeof (UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
172 //
173 // 32 PEI + 64 DXE
174 //
175 Smst64 = (EFI_SMM_SYSTEM_TABLE2_64 *)Smst;
176 SmmConfigurationTable64 = (EFI_CONFIGURATION_TABLE64 *)(UINTN)Smst64->SmmConfigurationTable;
177 NumberOfTableEntries = (UINTN)Smst64->NumberOfTableEntries;
178 for (Index = 0; Index < NumberOfTableEntries; Index++) {
179 if (CompareGuid (&SmmConfigurationTable64[Index].VendorGuid, VendorGuid)) {
180 return (VOID *)(UINTN)SmmConfigurationTable64[Index].VendorTable;
181 }
182 }
183
184 return NULL;
185 } else {
186 SmmConfigurationTable = Smst->SmmConfigurationTable;
187 NumberOfTableEntries = Smst->NumberOfTableEntries;
188 for (Index = 0; Index < NumberOfTableEntries; Index++) {
189 if (CompareGuid (&SmmConfigurationTable[Index].VendorGuid, VendorGuid)) {
190 return (VOID *)SmmConfigurationTable[Index].VendorTable;
191 }
192 }
193
194 return NULL;
195 }
196 }
197
198 /**
199 Get SMM LockBox context.
200
201 @return SMM LockBox context.
202 **/
203 SMM_LOCK_BOX_CONTEXT *
204 InternalGetSmmLockBoxContext (
205 VOID
206 )
207 {
208 EFI_SMRAM_DESCRIPTOR *SmramDescriptor;
209 SMM_S3_RESUME_STATE *SmmS3ResumeState;
210 VOID *GuidHob;
211 SMM_LOCK_BOX_CONTEXT *SmmLockBoxContext;
212
213 GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid);
214 ASSERT (GuidHob != NULL);
215 SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *)GET_GUID_HOB_DATA (GuidHob);
216 SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart;
217
218 SmmLockBoxContext = (SMM_LOCK_BOX_CONTEXT *)InternalSmstGetVendorTableByGuid (
219 SmmS3ResumeState->Signature,
220 (EFI_SMM_SYSTEM_TABLE2 *)(UINTN)SmmS3ResumeState->Smst,
221 &gEfiSmmLockBoxCommunicationGuid
222 );
223 ASSERT (SmmLockBoxContext != NULL);
224
225 return SmmLockBoxContext;
226 }
227
228 /**
229 This function will restore confidential information from lockbox in SMRAM directly.
230
231 @param Guid the guid to identify the confidential information
232 @param Buffer the address of the restored confidential information
233 NULL means restored to original address, Length MUST be NULL at same time.
234 @param Length the length of the restored confidential information
235
236 @retval RETURN_SUCCESS the information is restored successfully.
237 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no
238 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.
239 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.
240 @retval RETURN_NOT_FOUND the requested GUID not found.
241 **/
242 EFI_STATUS
243 InternalRestoreLockBoxFromSmram (
244 IN GUID *Guid,
245 IN VOID *Buffer OPTIONAL,
246 IN OUT UINTN *Length OPTIONAL
247 )
248 {
249 PEI_SMM_ACCESS_PPI *SmmAccess;
250 UINTN Index;
251 EFI_STATUS Status;
252 SMM_LOCK_BOX_CONTEXT *SmmLockBoxContext;
253 LIST_ENTRY *LockBoxQueue;
254 SMM_LOCK_BOX_DATA *LockBox;
255 VOID *RestoreBuffer;
256
257 //
258 // Get needed resource
259 //
260 Status = PeiServicesLocatePpi (
261 &gPeiSmmAccessPpiGuid,
262 0,
263 NULL,
264 (VOID **)&SmmAccess
265 );
266 if (!EFI_ERROR (Status)) {
267 for (Index = 0; !EFI_ERROR (Status); Index++) {
268 Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);
269 }
270 }
271
272 //
273 // Get LockBox context
274 //
275 SmmLockBoxContext = InternalGetSmmLockBoxContext ();
276 LockBoxQueue = (LIST_ENTRY *)(UINTN)SmmLockBoxContext->LockBoxDataAddress;
277
278 //
279 // We do NOT check Buffer address in SMRAM, because if SMRAM not locked, we trust the caller.
280 //
281
282 //
283 // Restore this, Buffer and Length MUST be both NULL or both non-NULL
284 //
285
286 //
287 // Find LockBox
288 //
289 LockBox = InternalFindLockBoxByGuidFromSmram (LockBoxQueue, Guid);
290 if (LockBox == NULL) {
291 //
292 // Not found
293 //
294 return EFI_NOT_FOUND;
295 }
296
297 //
298 // Set RestoreBuffer
299 //
300 if (Buffer != NULL) {
301 //
302 // restore to new buffer
303 //
304 RestoreBuffer = Buffer;
305 } else {
306 //
307 // restore to original buffer
308 //
309 if ((LockBox->Attributes & LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) == 0) {
310 return EFI_WRITE_PROTECTED;
311 }
312
313 RestoreBuffer = (VOID *)(UINTN)LockBox->Buffer;
314 }
315
316 //
317 // Set RestoreLength
318 //
319 if (Length != NULL) {
320 if (*Length < (UINTN)LockBox->Length) {
321 //
322 // Input buffer is too small to hold all data.
323 //
324 *Length = (UINTN)LockBox->Length;
325 return EFI_BUFFER_TOO_SMALL;
326 }
327
328 *Length = (UINTN)LockBox->Length;
329 }
330
331 //
332 // Restore data
333 //
334 CopyMem (RestoreBuffer, (VOID *)(UINTN)LockBox->SmramBuffer, (UINTN)LockBox->Length);
335
336 //
337 // Done
338 //
339 return EFI_SUCCESS;
340 }
341
342 /**
343 This function will restore confidential information from all lockbox which have RestoreInPlace attribute.
344
345 @retval RETURN_SUCCESS the information is restored successfully.
346 **/
347 EFI_STATUS
348 InternalRestoreAllLockBoxInPlaceFromSmram (
349 VOID
350 )
351 {
352 PEI_SMM_ACCESS_PPI *SmmAccess;
353 UINTN Index;
354 EFI_STATUS Status;
355 SMM_LOCK_BOX_CONTEXT *SmmLockBoxContext;
356 LIST_ENTRY *LockBoxQueue;
357 SMM_LOCK_BOX_DATA *LockBox;
358 LIST_ENTRY *Link;
359
360 //
361 // Get needed resource
362 //
363 Status = PeiServicesLocatePpi (
364 &gPeiSmmAccessPpiGuid,
365 0,
366 NULL,
367 (VOID **)&SmmAccess
368 );
369 if (!EFI_ERROR (Status)) {
370 for (Index = 0; !EFI_ERROR (Status); Index++) {
371 Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);
372 }
373 }
374
375 //
376 // Get LockBox context
377 //
378 SmmLockBoxContext = InternalGetSmmLockBoxContext ();
379 LockBoxQueue = (LIST_ENTRY *)(UINTN)SmmLockBoxContext->LockBoxDataAddress;
380
381 //
382 // We do NOT check Buffer address in SMRAM, because if SMRAM not locked, we trust the caller.
383 //
384
385 //
386 // Restore all, Buffer and Length MUST be NULL
387 //
388 for (Link = InternalInitLinkDxe (LockBoxQueue);
389 Link != LockBoxQueue;
390 Link = InternalNextLinkDxe (Link))
391 {
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 //
406 // Done
407 //
408 return EFI_SUCCESS;
409 }
410
411 /**
412 This function will save confidential information to lockbox.
413
414 @param Guid the guid to identify the confidential information
415 @param Buffer the address of the confidential information
416 @param Length the length of the confidential information
417
418 @retval RETURN_SUCCESS the information is saved successfully.
419 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0
420 @retval RETURN_ALREADY_STARTED the requested GUID already exist.
421 @retval RETURN_OUT_OF_RESOURCES no enough resource to save the information.
422 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
423 @retval RETURN_NOT_STARTED it is too early to invoke this interface
424 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
425 **/
426 RETURN_STATUS
427 EFIAPI
428 SaveLockBox (
429 IN GUID *Guid,
430 IN VOID *Buffer,
431 IN UINTN Length
432 )
433 {
434 ASSERT (FALSE);
435
436 //
437 // No support to save at PEI phase
438 //
439 return RETURN_UNSUPPORTED;
440 }
441
442 /**
443 This function will set lockbox attributes.
444
445 @param Guid the guid to identify the confidential information
446 @param Attributes the attributes of the lockbox
447
448 @retval RETURN_SUCCESS the information is saved successfully.
449 @retval RETURN_INVALID_PARAMETER attributes is invalid.
450 @retval RETURN_NOT_FOUND the requested GUID not found.
451 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
452 @retval RETURN_NOT_STARTED it is too early to invoke this interface
453 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
454 **/
455 RETURN_STATUS
456 EFIAPI
457 SetLockBoxAttributes (
458 IN GUID *Guid,
459 IN UINT64 Attributes
460 )
461 {
462 ASSERT (FALSE);
463
464 //
465 // No support to save at PEI phase
466 //
467 return RETURN_UNSUPPORTED;
468 }
469
470 /**
471 This function will update confidential information to lockbox.
472
473 @param Guid the guid to identify the original confidential information
474 @param Offset the offset of the original confidential information
475 @param Buffer the address of the updated confidential information
476 @param Length the length of the updated confidential information
477
478 @retval RETURN_SUCCESS the information is saved successfully.
479 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or Buffer is NULL, or Length is 0.
480 @retval RETURN_NOT_FOUND the requested GUID not found.
481 @retval RETURN_BUFFER_TOO_SMALL for lockbox without attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
482 the original buffer to too small to hold new information.
483 @retval RETURN_OUT_OF_RESOURCES for lockbox with attribute LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY,
484 no enough resource to save the information.
485 @retval RETURN_ACCESS_DENIED it is too late to invoke this interface
486 @retval RETURN_NOT_STARTED it is too early to invoke this interface
487 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
488 **/
489 RETURN_STATUS
490 EFIAPI
491 UpdateLockBox (
492 IN GUID *Guid,
493 IN UINTN Offset,
494 IN VOID *Buffer,
495 IN UINTN Length
496 )
497 {
498 ASSERT (FALSE);
499
500 //
501 // No support to update at PEI phase
502 //
503 return RETURN_UNSUPPORTED;
504 }
505
506 /**
507 This function will restore confidential information from lockbox.
508
509 @param Guid the guid to identify the confidential information
510 @param Buffer the address of the restored confidential information
511 NULL means restored to original address, Length MUST be NULL at same time.
512 @param Length the length of the restored confidential information
513
514 @retval RETURN_SUCCESS the information is restored successfully.
515 @retval RETURN_INVALID_PARAMETER the Guid is NULL, or one of Buffer and Length is NULL.
516 @retval RETURN_WRITE_PROTECTED Buffer and Length are NULL, but the LockBox has no
517 LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.
518 @retval RETURN_BUFFER_TOO_SMALL the Length is too small to hold the confidential information.
519 @retval RETURN_NOT_FOUND the requested GUID not found.
520 @retval RETURN_NOT_STARTED it is too early to invoke this interface
521 @retval RETURN_ACCESS_DENIED not allow to restore to the address
522 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
523 **/
524 RETURN_STATUS
525 EFIAPI
526 RestoreLockBox (
527 IN GUID *Guid,
528 IN VOID *Buffer OPTIONAL,
529 IN OUT UINTN *Length OPTIONAL
530 )
531 {
532 EFI_STATUS Status;
533 EFI_PEI_SMM_COMMUNICATION_PPI *SmmCommunicationPpi;
534 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *LockBoxParameterRestore;
535 EFI_SMM_COMMUNICATE_HEADER *CommHeader;
536 UINT8 CommBuffer[sizeof (EFI_GUID) + sizeof (UINT64) + sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE)];
537 UINTN CommSize;
538 UINT64 MessageLength;
539
540 //
541 // Please aware that there is UINTN in EFI_SMM_COMMUNICATE_HEADER. It might be UINT64 in DXE, while it is UINT32 in PEI.
542 // typedef struct {
543 // EFI_GUID HeaderGuid;
544 // UINTN MessageLength;
545 // UINT8 Data[1];
546 // } EFI_SMM_COMMUNICATE_HEADER;
547 //
548
549 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreLockBox - Enter\n"));
550
551 //
552 // Basic check
553 //
554 if ((Guid == NULL) ||
555 ((Buffer == NULL) && (Length != NULL)) ||
556 ((Buffer != NULL) && (Length == NULL)))
557 {
558 return EFI_INVALID_PARAMETER;
559 }
560
561 //
562 // Get needed resource
563 //
564 Status = PeiServicesLocatePpi (
565 &gEfiPeiSmmCommunicationPpiGuid,
566 0,
567 NULL,
568 (VOID **)&SmmCommunicationPpi
569 );
570 if (EFI_ERROR (Status)) {
571 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib LocatePpi - (%r)\n", Status));
572 Status = InternalRestoreLockBoxFromSmram (Guid, Buffer, Length);
573 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreLockBox - Exit (%r)\n", Status));
574 return Status;
575 }
576
577 //
578 // Prepare parameter
579 //
580 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
581 CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof (gEfiSmmLockBoxCommunicationGuid));
582 if ((sizeof (UINTN) == sizeof (UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
583 MessageLength = sizeof (*LockBoxParameterRestore);
584 CopyMem (&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength)], &MessageLength, sizeof (MessageLength));
585 } else {
586 CommHeader->MessageLength = sizeof (*LockBoxParameterRestore);
587 }
588
589 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib CommBuffer - %x\n", &CommBuffer[0]));
590 if ((sizeof (UINTN) == sizeof (UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
591 LockBoxParameterRestore = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof (UINT64)];
592 } else {
593 LockBoxParameterRestore = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof (UINTN)];
594 }
595
596 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib LockBoxParameterRestore - %x\n", LockBoxParameterRestore));
597 LockBoxParameterRestore->Header.Command = EFI_SMM_LOCK_BOX_COMMAND_RESTORE;
598 LockBoxParameterRestore->Header.DataLength = sizeof (*LockBoxParameterRestore);
599 LockBoxParameterRestore->Header.ReturnStatus = (UINT64)-1;
600 if (Guid != 0) {
601 CopyMem (&LockBoxParameterRestore->Guid, Guid, sizeof (*Guid));
602 } else {
603 ZeroMem (&LockBoxParameterRestore->Guid, sizeof (*Guid));
604 }
605
606 LockBoxParameterRestore->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
607 if (Length != NULL) {
608 LockBoxParameterRestore->Length = (EFI_PHYSICAL_ADDRESS)*Length;
609 } else {
610 LockBoxParameterRestore->Length = 0;
611 }
612
613 //
614 // Send command
615 //
616 CommSize = sizeof (CommBuffer);
617 Status = SmmCommunicationPpi->Communicate (
618 SmmCommunicationPpi,
619 &CommBuffer[0],
620 &CommSize
621 );
622 if (Status == EFI_NOT_STARTED) {
623 //
624 // Pei SMM communication not ready yet, so we access SMRAM directly
625 //
626 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib Communicate - (%r)\n", Status));
627 Status = InternalRestoreLockBoxFromSmram (Guid, Buffer, Length);
628 LockBoxParameterRestore->Header.ReturnStatus = (UINT64)Status;
629 if (Length != NULL) {
630 LockBoxParameterRestore->Length = (UINT64)*Length;
631 }
632 }
633
634 if (Length != NULL) {
635 *Length = (UINTN)LockBoxParameterRestore->Length;
636 }
637
638 Status = (EFI_STATUS)LockBoxParameterRestore->Header.ReturnStatus;
639 if (Status != EFI_SUCCESS) {
640 // Need or MAX_BIT, because there might be case that SMM is X64 while PEI is IA32.
641 Status |= MAX_BIT;
642 }
643
644 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreLockBox - Exit (%r)\n", Status));
645
646 //
647 // Done
648 //
649 return Status;
650 }
651
652 /**
653 This function will restore confidential information from all lockbox which have RestoreInPlace attribute.
654
655 @retval RETURN_SUCCESS the information is restored successfully.
656 @retval RETURN_NOT_STARTED it is too early to invoke this interface
657 @retval RETURN_UNSUPPORTED the service is not supported by implementaion.
658 **/
659 RETURN_STATUS
660 EFIAPI
661 RestoreAllLockBoxInPlace (
662 VOID
663 )
664 {
665 EFI_STATUS Status;
666 EFI_PEI_SMM_COMMUNICATION_PPI *SmmCommunicationPpi;
667 EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *LockBoxParameterRestoreAllInPlace;
668 EFI_SMM_COMMUNICATE_HEADER *CommHeader;
669 UINT8 CommBuffer[sizeof (EFI_GUID) + sizeof (UINT64) + sizeof (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE)];
670 UINTN CommSize;
671 UINT64 MessageLength;
672
673 //
674 // Please aware that there is UINTN in EFI_SMM_COMMUNICATE_HEADER. It might be UINT64 in DXE, while it is UINT32 in PEI.
675 // typedef struct {
676 // EFI_GUID HeaderGuid;
677 // UINTN MessageLength;
678 // UINT8 Data[1];
679 // } EFI_SMM_COMMUNICATE_HEADER;
680 //
681
682 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreAllLockBoxInPlace - Enter\n"));
683
684 //
685 // Get needed resource
686 //
687 Status = PeiServicesLocatePpi (
688 &gEfiPeiSmmCommunicationPpiGuid,
689 0,
690 NULL,
691 (VOID **)&SmmCommunicationPpi
692 );
693 if (EFI_ERROR (Status)) {
694 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib LocatePpi - (%r)\n", Status));
695 Status = InternalRestoreAllLockBoxInPlaceFromSmram ();
696 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreAllLockBoxInPlace - Exit (%r)\n", Status));
697 return Status;
698 }
699
700 //
701 // Prepare parameter
702 //
703 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
704 CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof (gEfiSmmLockBoxCommunicationGuid));
705 if ((sizeof (UINTN) == sizeof (UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
706 MessageLength = sizeof (*LockBoxParameterRestoreAllInPlace);
707 CopyMem (&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength)], &MessageLength, sizeof (MessageLength));
708 } else {
709 CommHeader->MessageLength = sizeof (*LockBoxParameterRestoreAllInPlace);
710 }
711
712 if ((sizeof (UINTN) == sizeof (UINT32)) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {
713 LockBoxParameterRestoreAllInPlace = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof (UINT64)];
714 } else {
715 LockBoxParameterRestoreAllInPlace = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, MessageLength) + sizeof (UINTN)];
716 }
717
718 LockBoxParameterRestoreAllInPlace->Header.Command = EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE;
719 LockBoxParameterRestoreAllInPlace->Header.DataLength = sizeof (*LockBoxParameterRestoreAllInPlace);
720 LockBoxParameterRestoreAllInPlace->Header.ReturnStatus = (UINT64)-1;
721
722 //
723 // Send command
724 //
725 CommSize = sizeof (CommBuffer);
726 Status = SmmCommunicationPpi->Communicate (
727 SmmCommunicationPpi,
728 &CommBuffer[0],
729 &CommSize
730 );
731 if (Status == EFI_NOT_STARTED) {
732 //
733 // Pei SMM communication not ready yet, so we access SMRAM directly
734 //
735 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib Communicate - (%r)\n", Status));
736 Status = InternalRestoreAllLockBoxInPlaceFromSmram ();
737 LockBoxParameterRestoreAllInPlace->Header.ReturnStatus = (UINT64)Status;
738 }
739
740 ASSERT_EFI_ERROR (Status);
741
742 Status = (EFI_STATUS)LockBoxParameterRestoreAllInPlace->Header.ReturnStatus;
743 if (Status != EFI_SUCCESS) {
744 // Need or MAX_BIT, because there might be case that SMM is X64 while PEI is IA32.
745 Status |= MAX_BIT;
746 }
747
748 DEBUG ((DEBUG_INFO, "SmmLockBoxPeiLib RestoreAllLockBoxInPlace - Exit (%r)\n", Status));
749
750 //
751 // Done
752 //
753 return Status;
754 }