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