/** @file
This is the driver that locates the MemoryConfigurationData HOB, if it
exists, and saves the data to nvRAM.
Copyright (c) 2017, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/**
This is the standard EFI driver point that detects whether there is a
MemoryConfigurationData HOB and, if so, saves its data to nvRAM.
@param[in] ImageHandle Handle for the image of this driver
@param[in] SystemTable Pointer to the EFI System Table
@retval EFI_UNSUPPORTED
**/
EFI_STATUS
EFIAPI
SaveMemoryConfigEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_HOB_GUID_TYPE *GuidHob;
VOID *HobData;
VOID *VariableData;
UINTN DataSize;
UINTN BufferSize;
EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;
DataSize = 0;
VariableData = NULL;
GuidHob = NULL;
HobData = NULL;
//
// Search for the Memory Configuration GUID HOB. If it is not present, then
// there's nothing we can do. It may not exist on the update path.
//
GuidHob = GetFirstGuidHob (&gFspNonVolatileStorageHobGuid);
if (GuidHob != NULL) {
HobData = GET_GUID_HOB_DATA (GuidHob);
DataSize = GET_GUID_HOB_DATA_SIZE(GuidHob);
if (DataSize > 0) {
//
// Use the HOB to save Memory Configuration Data
//
BufferSize = DataSize;
VariableData = AllocatePool (BufferSize);
if (VariableData == NULL) {
return EFI_UNSUPPORTED;
}
Status = gRT->GetVariable (
L"MemoryConfig",
&gFspNonVolatileStorageHobGuid,
NULL,
&BufferSize,
VariableData
);
if (Status == EFI_BUFFER_TOO_SMALL) {
FreePool (VariableData);
VariableData = AllocatePool (BufferSize);
if (VariableData == NULL) {
return EFI_UNSUPPORTED;
}
Status = gRT->GetVariable (
L"MemoryConfig",
&gFspNonVolatileStorageHobGuid,
NULL,
&BufferSize,
VariableData
);
}
if ( (EFI_ERROR(Status)) || BufferSize != DataSize || 0 != CompareMem (HobData, VariableData, DataSize)) {
Status = gRT->SetVariable (
L"MemoryConfig",
&gFspNonVolatileStorageHobGuid,
(EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS),
DataSize,
HobData
);
ASSERT_EFI_ERROR (Status);
DEBUG((DEBUG_INFO, "Restored Size is 0x%x\n", DataSize));
}
//
// Mark MemoryConfig to read-only if the Variable Lock protocol exists
//
Status = gBS->LocateProtocol(&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLock);
if (!EFI_ERROR(Status)) {
Status = VariableLock->RequestToLock(VariableLock, L"MemoryConfig", &gFspNonVolatileStorageHobGuid);
ASSERT_EFI_ERROR(Status);
}
FreePool (VariableData);
} else {
DEBUG((DEBUG_INFO, "Memory save size is %d\n", DataSize));
}
} else {
DEBUG((DEBUG_ERROR, "Memory S3 Data HOB was not found\n"));
}
//
// This driver does not produce any protocol services, so always unload it.
//
return EFI_REQUEST_UNLOAD_IMAGE;
}