1/**
2  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
3  This program and the accompanying materials
4  are licensed and made available under the terms and conditions of the BSD License
5  which accompanies this distribution.  The full text of the license may be found at
6  http://opensource.org/licenses/bsd-license.php
7
8  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10
11
12Module Name:
13
14  SaveMemoryConfig.c
15
16Abstract:
17  This is the driver that locates the MemoryConfigurationData HOB, if it
18  exists, and saves the data to nvRAM.
19
20
21
22--*/
23
24#include "SaveMemoryConfig.h"
25
26CHAR16    EfiMemoryConfigVariable[] = L"MemoryConfig";
27
28
29EFI_STATUS
30EFIAPI
31SaveMemoryConfigEntryPoint (
32  IN EFI_HANDLE         ImageHandle,
33  IN EFI_SYSTEM_TABLE   *SystemTable
34  )
35/*++
36
37  Routine Description:
38    This is the standard EFI driver point that detects whether there is a
39    MemoryConfigurationData HOB and, if so, saves its data to nvRAM.
40
41  Arguments:
42    ImageHandle   - Handle for the image of this driver
43    SystemTable   - Pointer to the EFI System Table
44
45  Returns:
46    EFI_SUCCESS   - if the data is successfully saved or there was no data
47    EFI_NOT_FOUND - if the HOB list could not be located.
48    EFI_UNLOAD_IMAGE - It is not success
49
50--*/
51{
52  EFI_STATUS                      Status=EFI_SUCCESS;
53  VOID                            *MemHobData;
54  VOID                            *VariableData;
55  UINTN                           BufferSize;
56  BOOLEAN                         MfgMode;
57  EFI_PLATFORM_SETUP_ID           *BootModeBuffer;
58  EFI_PLATFORM_INFO_HOB           *PlatformInfoHobPtr;
59  MEM_INFO_PROTOCOL               *MemInfoProtocol;
60  EFI_HANDLE                      Handle;
61  UINT8							              Channel, Slot;
62  VOID                            *GuidHob;
63
64  VariableData   = NULL;
65  MfgMode        = FALSE;
66  Handle         = NULL;
67  BootModeBuffer = NULL;
68  MemHobData     = NULL;
69  PlatformInfoHobPtr = NULL;
70  BufferSize     = 0;
71
72  //
73  // Get Platform Info HOB
74  //
75  GuidHob = GetFirstGuidHob (&gEfiPlatformInfoGuid);
76  if (GuidHob == NULL) {
77    Status = EFI_NOT_FOUND;
78  }
79  ASSERT_EFI_ERROR (Status);
80
81  PlatformInfoHobPtr = GET_GUID_HOB_DATA (GuidHob);
82
83  //
84  // Get the BootMode guid hob
85  //
86  GuidHob = GetFirstGuidHob (&gEfiPlatformBootModeGuid);
87  if (GuidHob == NULL) {
88    Status = EFI_NOT_FOUND;
89  }
90  ASSERT_EFI_ERROR (Status);
91
92  BootModeBuffer = GET_GUID_HOB_DATA (GuidHob);
93
94
95  //
96  // Check whether in Manufacturing Mode
97  //
98  if (BootModeBuffer) {
99    if ( !CompareMem (   //EfiCompareMem
100            &BootModeBuffer->SetupName,
101            MANUFACTURE_SETUP_NAME,
102            StrSize (MANUFACTURE_SETUP_NAME)  //EfiStrSize
103            ) ) {
104      MfgMode = TRUE;
105    }
106  }
107
108  if (MfgMode) {
109    //
110    // Don't save Memory Configuration in Manufacturing Mode. Clear memory configuration.
111    //
112    Status = gRT->SetVariable (
113              EfiMemoryConfigVariable,
114              &gEfiVlv2VariableGuid,
115              EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
116              0,
117              NULL
118              );
119  } else {
120
121    MemInfoProtocol = (MEM_INFO_PROTOCOL*)AllocateZeroPool(sizeof(MEM_INFO_PROTOCOL));
122    if (PlatformInfoHobPtr != NULL) {
123      MemInfoProtocol->MemInfoData.memSize  = 0;
124      for (Channel = 0; Channel < CH_NUM; Channel ++){
125        for (Slot = 0; Slot < DIMM_NUM; Slot ++){
126          MemInfoProtocol->MemInfoData.dimmSize[Slot + (Channel * DIMM_NUM)] = PlatformInfoHobPtr->MemData.DimmSize[Slot + (Channel * DIMM_NUM)];
127        }
128      }
129  	  MemInfoProtocol->MemInfoData.memSize       = PlatformInfoHobPtr->MemData.MemSize;
130  	  MemInfoProtocol->MemInfoData.EccSupport    = PlatformInfoHobPtr->MemData.EccSupport;
131      MemInfoProtocol->MemInfoData.ddrFreq       = PlatformInfoHobPtr->MemData.DdrFreq;
132      MemInfoProtocol->MemInfoData.ddrType       = PlatformInfoHobPtr->MemData.DdrType;
133      if (MemInfoProtocol->MemInfoData.memSize == 0){
134        //
135        // We hardcode if MRC didn't fill these info in
136        //
137        MemInfoProtocol->MemInfoData.memSize     = 0x800; //per 1MB
138        MemInfoProtocol->MemInfoData.dimmSize[0] = 0x800;
139        MemInfoProtocol->MemInfoData.dimmSize[1] = 0;
140        MemInfoProtocol->MemInfoData.EccSupport  = FALSE;
141        MemInfoProtocol->MemInfoData.ddrType     = 5; //DDRType_LPDDR3
142      }
143
144      Status = gBS->InstallMultipleProtocolInterfaces (
145             &Handle,
146             &gMemInfoProtocolGuid,
147             MemInfoProtocol,
148             NULL
149             );
150    }
151
152    Status = EFI_SUCCESS;
153    if (BOOT_WITH_MINIMAL_CONFIGURATION != GetBootModeHob()){
154      //
155      // Get the Memory Config guid hob
156      //
157      GuidHob = GetFirstGuidHob (&gEfiMemoryConfigDataGuid);
158      if (GuidHob == NULL) {
159        Status = EFI_NOT_FOUND;
160      }
161      ASSERT_EFI_ERROR (Status);
162
163      MemHobData = GET_GUID_HOB_DATA (GuidHob);
164      BufferSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
165
166      Status = gRT->GetVariable (
167                  EfiMemoryConfigVariable,
168                  &gEfiVlv2VariableGuid,
169                  NULL,
170                  &BufferSize,
171                  VariableData
172                  );
173      if (EFI_ERROR(Status) && (MemHobData != NULL)) {
174        Status = gRT->SetVariable (
175                      EfiMemoryConfigVariable,
176                      &gEfiVlv2VariableGuid,
177                      (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS),
178                      BufferSize,
179                      MemHobData
180                      );
181      }
182    }
183
184  } // if-else MfgMode
185
186  return EFI_SUCCESS;
187}
188