1 /** @file 2 3 Copyright (c) 2010 - 2011, 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 748