123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- /** @file
- Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "S3NvramSave.h"
- #include <Protocol/Decompress.h>
- #include <Library/CompressLib.h>
- #include <Protocol/VariableLock.h>
- /**
- This function will retrieve the S3 data from HOBs produced by MRC
- and will save it to NVRAM if the data is absent or different from
- the previously saved data.
- @param VOID
- @retval VOID
- **/
- VOID
- SaveS3StructToNvram (
- VOID
- )
- {
- EFI_STATUS Status;
- UINTN BufferSize;
- UINTN CurrentHobSize;
- UINTN S3ChunkSize;
- CHAR16 EfiMemoryConfigVariable[] = L"MemoryConfig0";
- EFI_HOB_GUID_TYPE *GuidHob = NULL;
- VOID *HobData = NULL;
- VOID *VariableData = NULL;
-
- UINTN CompressedDataSize;
- UINT32 ScratchSize;
- VOID *CompressedData = NULL;
- VOID *Scratch = NULL;
- EFI_DECOMPRESS_PROTOCOL *Decompress = NULL;
- VOID *CompressedVariableData = NULL;
- UINTN CompressedBufferSize;
- EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock = NULL;
-
- //
- // Get first S3 data HOB
- //
- GuidHob = GetFirstGuidHob (&gEfiMemoryConfigDataHobGuid);
- Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);
- DEBUG((DEBUG_INFO, "[SaveMemoryConfigEntryPoint] Locate Decompress protocol - %r\n", Status));
- if(EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return;
- }
-
- Status = gBS->LocateProtocol(&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLock);
- DEBUG((DEBUG_INFO, "[SaveMemoryConfigEntryPoint] Locate Variable Lock protocol - %r\n", Status));
- ASSERT_EFI_ERROR(Status);
- while (TRUE) {
- if (GuidHob == NULL) {
- break;
- }
- HobData = GET_GUID_HOB_DATA(GuidHob);
- CurrentHobSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
- DEBUG((EFI_D_INFO, " Current Hob Size(bytes) is: %d\n", CurrentHobSize));
- //
- // Use the HOB data to save Memory Configuration Data
- //
- BufferSize = CurrentHobSize;
- Status = gBS->AllocatePool (
- EfiBootServicesData,
- BufferSize,
- (VOID**)&VariableData
- );
- ASSERT (VariableData != NULL);
- S3ChunkSize = MAX_HOB_ENTRY_SIZE / 8;
- DEBUG((EFI_D_INFO, " S3ChunkSize Hob Size(bytes): %d\n", S3ChunkSize));
- while (CurrentHobSize) {
- if (S3ChunkSize > CurrentHobSize) {
- S3ChunkSize = CurrentHobSize;
- }
- BufferSize = S3ChunkSize;
- CompressedDataSize = 0;
- ScratchSize = 0;
- Status = gRT->GetVariable (
- EfiMemoryConfigVariable,
- &gEfiMemoryConfigDataGuid,
- NULL,
- &CompressedDataSize,
- NULL
- );
-
- if(Status == EFI_BUFFER_TOO_SMALL) {
- Status = gBS->AllocatePool (
- EfiBootServicesData,
- CompressedDataSize,
- (VOID**)&CompressedData
- );
- ASSERT (Status == EFI_SUCCESS);
- }
- if(!EFI_ERROR (Status))
- {
- Status = gRT->GetVariable (
- EfiMemoryConfigVariable,
- &gEfiMemoryConfigDataGuid,
- NULL,
- &CompressedDataSize,
- CompressedData
- );
- if (!EFI_ERROR (Status)) {
- Status = Decompress->GetInfo (
- Decompress,
- CompressedData,
- (UINT32)CompressedDataSize,
- (UINT32*)&BufferSize,
- &ScratchSize
- );
- }
- if (!EFI_ERROR (Status)) {
- Status = gBS->AllocatePool (
- EfiBootServicesData,
- ScratchSize,
- (VOID**)&Scratch
- );
- }
- if (!EFI_ERROR (Status)) {
- Status = Decompress->Decompress (
- Decompress,
- CompressedData,
- (UINT32)CompressedDataSize,
- VariableData,
- (UINT32)BufferSize,
- Scratch,
- ScratchSize
- );
- }
- if (EFI_ERROR (Status)) {
- DEBUG((EFI_D_ERROR, "Getting variables error: 0x%x\n", Status));
- ASSERT (Status == EFI_SUCCESS);
- }
- if(Scratch != NULL) {
- gBS->FreePool (Scratch);
- Scratch = NULL;
- }
- }
- if(CompressedData != NULL) {
- gBS->FreePool (CompressedData);
- CompressedData = NULL;
- }
- if ( (EFI_ERROR(Status)) || (CompareMem (HobData, VariableData, S3ChunkSize) != 0) ) {
- Status = gBS->AllocatePool (
- EfiBootServicesData,
- BufferSize,
- (VOID**)&CompressedVariableData
- );
- ASSERT (CompressedVariableData != NULL);
- if (Status == EFI_SUCCESS) {
- CompressedBufferSize = BufferSize;
- Status = Compress(HobData, S3ChunkSize, CompressedVariableData, &CompressedBufferSize);
- if (Status == EFI_BUFFER_TOO_SMALL){
- gBS->FreePool(CompressedVariableData);
- Status = gBS->AllocatePool(
- EfiBootServicesData,
- CompressedBufferSize,
- (VOID**)&CompressedVariableData
- );
- ASSERT (CompressedVariableData != NULL);
- Status = Compress(HobData, S3ChunkSize, CompressedVariableData, &CompressedBufferSize);
- }
- if(Status == EFI_SUCCESS) {
- Status = gRT->SetVariable (
- EfiMemoryConfigVariable,
- &gEfiMemoryConfigDataGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- CompressedBufferSize,
- CompressedVariableData
- );
- }
- if(CompressedVariableData != NULL) {
- gBS->FreePool(CompressedVariableData);
- CompressedVariableData = NULL;
- }
- }
-
- if (EFI_ERROR (Status)) {
- DEBUG((EFI_D_ERROR, "Set variable error. Status: 0x%x\n", Status));
- ASSERT_EFI_ERROR (Status);
- }
- }
- //
- // Lock the Memory Config Variable
- //
- Status = VariableLock->RequestToLock(VariableLock, EfiMemoryConfigVariable, &gEfiMemoryConfigDataGuid);
- ASSERT_EFI_ERROR(Status);
- HobData = (UINT8 *) (HobData) + S3ChunkSize;
-
- CurrentHobSize -= S3ChunkSize;
- EfiMemoryConfigVariable[12]++; // Increment number in the string
- }
- //
- // Get next S3 Config data hob, if none left, results NULL
- //
- GuidHob = GET_NEXT_HOB (GuidHob); // Increment to next HOB
- GuidHob = GetNextGuidHob (&gEfiMemoryConfigDataHobGuid, GuidHob); // Now search for next MemConfig HOB
- if(VariableData != NULL) {
- gBS->FreePool(VariableData);
- VariableData = NULL;
- }
- }
- return;
- }
- EFI_STATUS
- EFIAPI
- S3NvramSaveEntry (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- /**
- This is the main entry point of the S3 NVRAM Save module.
- @param ImageHandle - Handle for the image of this driver.
- @param SystemTable - Pointer to the EFI System Table.
- @retval EFI_SUCCESS - Module launched successfully.
- **/
- {
- EFI_STATUS Status = EFI_SUCCESS;
-
- //
- // Save the s3 strututre from MRC into NVRAM if needed
- //
- SaveS3StructToNvram();
-
- return Status;
-
- }
|