1b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney/** @file 2b303605e1b7e113b4311daf161c6c3289350447bMichael KinneyThis is the driver that locates the MemoryConfigurationData HOB, if it 3b303605e1b7e113b4311daf161c6c3289350447bMichael Kinneyexists, and saves the data to nvRAM. 4b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 5b303605e1b7e113b4311daf161c6c3289350447bMichael KinneyCopyright (c) 2013-2015 Intel Corporation. 6b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 7b303605e1b7e113b4311daf161c6c3289350447bMichael KinneyThis program and the accompanying materials 8b303605e1b7e113b4311daf161c6c3289350447bMichael Kinneyare licensed and made available under the terms and conditions of the BSD License 9b303605e1b7e113b4311daf161c6c3289350447bMichael Kinneywhich accompanies this distribution. The full text of the license may be found at 10b303605e1b7e113b4311daf161c6c3289350447bMichael Kinneyhttp://opensource.org/licenses/bsd-license.php 11b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 12b303605e1b7e113b4311daf161c6c3289350447bMichael KinneyTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 13b303605e1b7e113b4311daf161c6c3289350447bMichael KinneyWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 14b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 15b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney**/ 16b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 17b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney#include <Library/DebugLib.h> 18b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney#include <Library/HobLib.h> 19b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney#include <Library/MemoryAllocationLib.h> 20b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney#include <Library/UefiBootServicesTableLib.h> 21b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney#include <Library/UefiRuntimeServicesTableLib.h> 22b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney#include <Library/BaseMemoryLib.h> 23b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney#include <Library/UefiDriverEntryPoint.h> 24b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 25b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney#include <Guid/MemoryConfigData.h> 26b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney#include <Guid/DebugMask.h> 27b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 28b303605e1b7e113b4311daf161c6c3289350447bMichael KinneyEFI_STATUS 29b303605e1b7e113b4311daf161c6c3289350447bMichael KinneyEFIAPI 30b303605e1b7e113b4311daf161c6c3289350447bMichael KinneySaveMemoryConfigEntryPoint ( 31b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney IN EFI_HANDLE ImageHandle, 32b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney IN EFI_SYSTEM_TABLE *SystemTable 33b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney ) 34b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney/*++ 35b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 36b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney Routine Description: 37b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney This is the standard EFI driver point that detects whether there is a 38b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney MemoryConfigurationData HOB and, if so, saves its data to nvRAM. 39b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 40b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney Arguments: 41b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney ImageHandle - Handle for the image of this driver 42b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney SystemTable - Pointer to the EFI System Table 43b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 44b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney Returns: 45b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney EFI_SUCCESS - if the data is successfully saved or there was no data 46b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney EFI_NOT_FOUND - if the HOB list could not be located. 47b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney EFI_UNLOAD_IMAGE - It is not success 48b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 49b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney--*/ 50b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney{ 51b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney EFI_STATUS Status; 52b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney VOID *HobList; 53b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney EFI_HOB_GUID_TYPE *GuidHob; 54b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney VOID *HobData; 55b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney VOID *VariableData; 56b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney UINTN DataSize; 57b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney UINTN BufferSize; 58b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 59b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney DataSize = 0; 60b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney VariableData = NULL; 61b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney GuidHob = NULL; 62b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney HobList = NULL; 63b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney HobData = NULL; 64b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney Status = EFI_UNSUPPORTED; 65b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 66b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney // 67b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney // Get the HOB list. If it is not present, then ASSERT. 68b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney // 69b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney HobList = GetHobList (); 70b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney ASSERT (HobList != NULL); 71b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 72b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney // 73b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney // Search for the Memory Configuration GUID HOB. If it is not present, then 74b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney // there's nothing we can do. It may not exist on the update path. 75b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney // 76b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney GuidHob = GetNextGuidHob (&gEfiMemoryConfigDataGuid, HobList); 77b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney if (GuidHob != NULL) { 78b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney HobData = GET_GUID_HOB_DATA (GuidHob); 79b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob); 80b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney // 81b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney // Use the HOB to save Memory Configuration Data 82b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney // 83b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney BufferSize = DataSize; 84b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney VariableData = AllocatePool (BufferSize); 85b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney ASSERT (VariableData != NULL); 86b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney Status = gRT->GetVariable ( 87b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney EFI_MEMORY_CONFIG_DATA_NAME, 88b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney &gEfiMemoryConfigDataGuid, 89b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney NULL, 90b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney &BufferSize, 91b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney VariableData 92b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney ); 93b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney if (Status == EFI_BUFFER_TOO_SMALL) { 94b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney gBS->FreePool (VariableData); 95b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney VariableData = AllocatePool (BufferSize); 96b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney ASSERT (VariableData != NULL); 97b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney Status = gRT->GetVariable ( 98b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney EFI_MEMORY_CONFIG_DATA_NAME, 99b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney &gEfiMemoryConfigDataGuid, 100b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney NULL, 101b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney &BufferSize, 102b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney VariableData 103b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney ); 104b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney } 105b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 106b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney if (EFI_ERROR(Status) || BufferSize != DataSize || CompareMem (HobData, VariableData, DataSize) != 0) { 107b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney Status = gRT->SetVariable ( 108b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney EFI_MEMORY_CONFIG_DATA_NAME, 109b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney &gEfiMemoryConfigDataGuid, 110b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), 111b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney DataSize, 112b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney HobData 113b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney ); 114b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney ASSERT((Status == EFI_SUCCESS) || (Status == EFI_OUT_OF_RESOURCES)); 115b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney } 116b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 117b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney gBS->FreePool (VariableData); 118b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney } 119b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney 120b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney // 121b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney // This driver does not produce any protocol services, so always unload it. 122b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney // 123b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney return Status; 124b303605e1b7e113b4311daf161c6c3289350447bMichael Kinney} 125