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