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 
12 Module Name:
13 
14   SaveMemoryConfig.c
15 
16 Abstract:
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 
26 CHAR16    EfiMemoryConfigVariable[] = L"MemoryConfig";
27 
28 
29 EFI_STATUS
30 EFIAPI
SaveMemoryConfigEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)31 SaveMemoryConfigEntryPoint (
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