13cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/** 23cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR> 33cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei This program and the accompanying materials 43cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei are licensed and made available under the terms and conditions of the BSD License 53cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei which accompanies this distribution. The full text of the license may be found at 63cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei http://opensource.org/licenses/bsd-license.php 73cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 83cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 93cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 123cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiModule Name: 133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SaveMemoryConfig.c 153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 163cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiAbstract: 173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei This is the driver that locates the MemoryConfigurationData HOB, if it 183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei exists, and saves the data to nvRAM. 193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei--*/ 233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei#include "SaveMemoryConfig.h" 253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 263cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiCHAR16 EfiMemoryConfigVariable[] = L"MemoryConfig"; 273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 293cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFI_STATUS 303cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiEFIAPI 313cbfba02fef9dae07a041fdbf2e89611d72d6f90David WeiSaveMemoryConfigEntryPoint ( 323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_HANDLE ImageHandle, 333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei IN EFI_SYSTEM_TABLE *SystemTable 343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) 353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei/*++ 363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Routine Description: 383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei This is the standard EFI driver point that detects whether there is a 393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemoryConfigurationData HOB and, if so, saves its data to nvRAM. 403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Arguments: 423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ImageHandle - Handle for the image of this driver 433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei SystemTable - Pointer to the EFI System Table 443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Returns: 463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_SUCCESS - if the data is successfully saved or there was no data 473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_NOT_FOUND - if the HOB list could not be located. 483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_UNLOAD_IMAGE - It is not success 493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei--*/ 513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei{ 523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_STATUS Status=EFI_SUCCESS; 533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VOID *MemHobData; 543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VOID *VariableData; 553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINTN BufferSize; 563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BOOLEAN MfgMode; 573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_PLATFORM_SETUP_ID *BootModeBuffer; 583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_PLATFORM_INFO_HOB *PlatformInfoHobPtr; 593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MEM_INFO_PROTOCOL *MemInfoProtocol; 603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_HANDLE Handle; 613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei UINT8 Channel, Slot; 623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VOID *GuidHob; 633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VariableData = NULL; 653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MfgMode = FALSE; 663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Handle = NULL; 673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BootModeBuffer = NULL; 683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemHobData = NULL; 693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PlatformInfoHobPtr = NULL; 703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BufferSize = 0; 713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Get Platform Info HOB 743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei GuidHob = GetFirstGuidHob (&gEfiPlatformInfoGuid); 763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (GuidHob == NULL) { 773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = EFI_NOT_FOUND; 783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT_EFI_ERROR (Status); 803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei PlatformInfoHobPtr = GET_GUID_HOB_DATA (GuidHob); 823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Get the BootMode guid hob 853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei GuidHob = GetFirstGuidHob (&gEfiPlatformBootModeGuid); 873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (GuidHob == NULL) { 883cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = EFI_NOT_FOUND; 893cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 903cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT_EFI_ERROR (Status); 913cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 923cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BootModeBuffer = GET_GUID_HOB_DATA (GuidHob); 933cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 943cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 953cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 963cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Check whether in Manufacturing Mode 973cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 983cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (BootModeBuffer) { 993cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if ( !CompareMem ( //EfiCompareMem 1003cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &BootModeBuffer->SetupName, 1013cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MANUFACTURE_SETUP_NAME, 1023cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei StrSize (MANUFACTURE_SETUP_NAME) //EfiStrSize 1033cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ) ) { 1043cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MfgMode = TRUE; 1053cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1063cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1073cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1083cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (MfgMode) { 1093cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1103cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Don't save Memory Configuration in Manufacturing Mode. Clear memory configuration. 1113cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1123cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gRT->SetVariable ( 1133cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EfiMemoryConfigVariable, 1143cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &gEfiVlv2VariableGuid, 1153cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 1163cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 0, 1173cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL 1183cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 1193cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } else { 1203cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1213cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemInfoProtocol = (MEM_INFO_PROTOCOL*)AllocateZeroPool(sizeof(MEM_INFO_PROTOCOL)); 1223cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (PlatformInfoHobPtr != NULL) { 1233cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemInfoProtocol->MemInfoData.memSize = 0; 1243cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei for (Channel = 0; Channel < CH_NUM; Channel ++){ 1253cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei for (Slot = 0; Slot < DIMM_NUM; Slot ++){ 1266f2ef18e8097c4fa11dd6ff5fdd0152c2c61ffc5Tim He MemInfoProtocol->MemInfoData.dimmSize[Slot + (Channel * DIMM_NUM)] = PlatformInfoHobPtr->MemData.DimmSize[Slot + (Channel * DIMM_NUM)]; 1273cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1283cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1293cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemInfoProtocol->MemInfoData.memSize = PlatformInfoHobPtr->MemData.MemSize; 1303cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemInfoProtocol->MemInfoData.EccSupport = PlatformInfoHobPtr->MemData.EccSupport; 1313cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemInfoProtocol->MemInfoData.ddrFreq = PlatformInfoHobPtr->MemData.DdrFreq; 1323cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemInfoProtocol->MemInfoData.ddrType = PlatformInfoHobPtr->MemData.DdrType; 1333cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (MemInfoProtocol->MemInfoData.memSize == 0){ 1343cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1353cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // We hardcode if MRC didn't fill these info in 1363cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1373cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemInfoProtocol->MemInfoData.memSize = 0x800; //per 1MB 1383cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemInfoProtocol->MemInfoData.dimmSize[0] = 0x800; 1393cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemInfoProtocol->MemInfoData.dimmSize[1] = 0; 1403cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemInfoProtocol->MemInfoData.EccSupport = FALSE; 1413cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemInfoProtocol->MemInfoData.ddrType = 5; //DDRType_LPDDR3 1423cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1433cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1443cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gBS->InstallMultipleProtocolInterfaces ( 1453cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &Handle, 1463cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &gMemInfoProtocolGuid, 1473cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemInfoProtocol, 1483cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL 1493cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 1503cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1513cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1523cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = EFI_SUCCESS; 1533cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (BOOT_WITH_MINIMAL_CONFIGURATION != GetBootModeHob()){ 1543cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1553cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // Get the Memory Config guid hob 1563cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei // 1573cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei GuidHob = GetFirstGuidHob (&gEfiMemoryConfigDataGuid); 1583cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (GuidHob == NULL) { 1593cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = EFI_NOT_FOUND; 1603cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1613cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ASSERT_EFI_ERROR (Status); 1623cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1633cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemHobData = GET_GUID_HOB_DATA (GuidHob); 1643cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BufferSize = GET_GUID_HOB_DATA_SIZE (GuidHob); 1653cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1663cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gRT->GetVariable ( 1673cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EfiMemoryConfigVariable, 1683cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &gEfiVlv2VariableGuid, 1693cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei NULL, 1703cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &BufferSize, 1713cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei VariableData 1723cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 1733cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei if (EFI_ERROR(Status) && (MemHobData != NULL)) { 1743cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei Status = gRT->SetVariable ( 1753cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei EfiMemoryConfigVariable, 1763cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei &gEfiVlv2VariableGuid, 1773cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS), 1783cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei BufferSize, 1793cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei MemHobData 1803cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei ); 1813cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1823cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } 1833cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1843cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei } // if-else MfgMode 1853cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei 1863cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei return EFI_SUCCESS; 1873cbfba02fef9dae07a041fdbf2e89611d72d6f90David Wei} 188