264 lines
12 KiB
C
264 lines
12 KiB
C
/** @file
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2014 - 2021, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
/** @file
|
|
Platform Policy Initialization Driver.
|
|
|
|
@copyright
|
|
INTEL CONFIDENTIAL
|
|
Copyright 1999 - 2017 Intel Corporation.
|
|
|
|
The source code contained or described herein and all documents related to the
|
|
source code ("Material") are owned by Intel Corporation or its suppliers or
|
|
licensors. Title to the Material remains with Intel Corporation or its suppliers
|
|
and licensors. The Material may contain trade secrets and proprietary and
|
|
confidential information of Intel Corporation and its suppliers and licensors,
|
|
and is protected by worldwide copyright and trade secret laws and treaty
|
|
provisions. No part of the Material may be used, copied, reproduced, modified,
|
|
published, uploaded, posted, transmitted, distributed, or disclosed in any way
|
|
without Intel's prior express written permission.
|
|
|
|
No license under any patent, copyright, trade secret or other intellectual
|
|
property right is granted to or conferred upon you by disclosure or delivery
|
|
of the Materials, either expressly, by implication, inducement, estoppel or
|
|
otherwise. Any license under such intellectual property rights must be
|
|
express and approved by Intel in writing.
|
|
|
|
Unless otherwise agreed by Intel in writing, you may not remove or alter
|
|
this notice or any other notice embedded in Materials by Intel or
|
|
Intel's suppliers or licensors in any way.
|
|
|
|
This file contains a 'Sample Driver' and is licensed as such under the terms
|
|
of your license agreement with Intel or your vendor. This file may be modified
|
|
by the user, subject to the additional terms of the license agreement.
|
|
|
|
@par Specification Reference:
|
|
**/
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/HobLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <MemInfoHob.h>
|
|
#include <Protocol/MemInfo.h>
|
|
#include <IndustryStandard/SmBios.h>
|
|
|
|
VOID
|
|
DumpMemInfo (
|
|
IN MEM_INFO_PROTOCOL *MemoryInfo
|
|
);
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
MemInfoEntry (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE Handle = NULL;
|
|
MEM_INFO_PROTOCOL *MemoryInfoProtocol;
|
|
UINT8 Node;
|
|
UINT8 Channel;
|
|
UINT8 Dimm;
|
|
MEMORY_INFO_DATA_HOB *MemInfo;
|
|
MEMORY_INFO_DATA *MemInfoData;
|
|
CONTROLLER_INFO *ControllerInfo;
|
|
CHANNEL_INFO *ChannelInfo;
|
|
DIMM_INFO *DimmInfo;
|
|
MEMORY_TIMING *MemoryTiming;
|
|
MRC_CH_TIMING *Timing;
|
|
UINT8 Profile;
|
|
UINT32 Index;
|
|
EFI_HOB_GUID_TYPE *GuidHob;
|
|
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, "\nMemInfo Entry\n"));
|
|
|
|
MemInfo = NULL;
|
|
|
|
//
|
|
// Search for the Memory Configuration GUID HOB. If it is not present, then
|
|
// there's nothing we can do. It may not exist on the update path.
|
|
//
|
|
GuidHob = NULL;
|
|
GuidHob = (EFI_HOB_GUID_TYPE *) GetFirstGuidHob (&gSiMemoryInfoDataGuid);
|
|
ASSERT (GuidHob != NULL);
|
|
if (GuidHob == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
MemInfo = (MEMORY_INFO_DATA_HOB *) GET_GUID_HOB_DATA (GuidHob);
|
|
|
|
//
|
|
// Allocate and set MemoryInfo structure to known value
|
|
//
|
|
MemoryInfoProtocol = NULL;
|
|
MemoryInfoProtocol = AllocateZeroPool (sizeof (MEM_INFO_PROTOCOL));
|
|
ASSERT (MemoryInfoProtocol != NULL);
|
|
if (MemoryInfoProtocol == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
MemInfoData = &MemoryInfoProtocol->MemInfoData;
|
|
MemInfoData->Profile = MemInfo->MemoryProfile;
|
|
MemInfoData->XmpProfileEnable = MemInfo->XmpProfileEnable;
|
|
MemInfoData->memSize = (UINT32) (MemInfo->TotalPhysicalMemorySize);
|
|
MemInfoData->ddrFreq = (UINT16) MemInfo->ConfiguredMemoryClockSpeed;
|
|
MemInfoData->ddrFreqMax = (UINT16) MemInfo->MaximumMemoryClockSpeed;
|
|
MemInfoData->EccSupport = MemInfo->EccSupport;
|
|
MemInfoData->Ratio = MemInfo->Ratio;
|
|
MemInfoData->RefClk = MemInfo->RefClk;
|
|
switch (MemInfo->MemoryType) {
|
|
case MemoryTypeDdr4:
|
|
MemInfoData->DdrType = MRC_DDR_TYPE_DDR4;
|
|
break;
|
|
|
|
case MemoryTypeLpddr4:
|
|
MemInfoData->DdrType = MRC_DDR_TYPE_LPDDR4;
|
|
break;
|
|
|
|
case MemoryTypeDdr5:
|
|
MemInfoData->DdrType = MRC_DDR_TYPE_DDR5;
|
|
break;
|
|
|
|
case MemoryTypeLpddr5:
|
|
MemInfoData->DdrType = MRC_DDR_TYPE_LPDDR5;
|
|
break;
|
|
|
|
default:
|
|
MemInfoData->DdrType = MRC_DDR_TYPE_UNKNOWN;
|
|
break;
|
|
}
|
|
|
|
for (Profile = 0; Profile < PROFILE_NUM; Profile++) {
|
|
MemInfoData->VddVoltage[Profile] = (UINT16) MemInfo->VddVoltage[Profile];
|
|
}
|
|
Index = 0;
|
|
for (Node = 0; Node < NODE_NUM; Node++) {
|
|
ControllerInfo = &MemInfo->Controller[Node];
|
|
for (Channel = 0; Channel < CH_NUM; Channel++) {
|
|
ChannelInfo = &ControllerInfo->ChannelInfo[Channel];
|
|
if (ChannelInfo->Status == CHANNEL_PRESENT) {
|
|
//
|
|
// Updating memory timings to MemInfoProtocol from MemInfoHob for each memory profile.
|
|
//
|
|
for (Profile = 0; Profile < PROFILE_NUM; Profile++) {
|
|
MemoryTiming = &MemInfoData->Timing[Profile];
|
|
Timing = &ChannelInfo->Timing[Profile];
|
|
MemoryTiming->tCK = Timing->tCK;
|
|
MemoryTiming->tCL = Timing->tCL;
|
|
MemoryTiming->tCWL = Timing->tCWL;
|
|
MemoryTiming->tFAW = Timing->tFAW;
|
|
MemoryTiming->tRAS = Timing->tRAS;
|
|
MemoryTiming->tRCDtRP = Timing->tRCDtRP;
|
|
MemoryTiming->tREFI = Timing->tREFI;
|
|
MemoryTiming->tRFC = Timing->tRFC;
|
|
MemoryTiming->tRPab = Timing->tRPab;
|
|
MemoryTiming->tRRD = Timing->tRRD;
|
|
MemoryTiming->tRTP = Timing->tRTP;
|
|
MemoryTiming->tWR = Timing->tWR;
|
|
MemoryTiming->tWTR = Timing->tWTR;
|
|
MemoryTiming->NMode = (UINT8) Timing->NMode;
|
|
}
|
|
}
|
|
for (Dimm = 0; Dimm < DIMM_NUM; Dimm++, Index++) {
|
|
DimmInfo = &ChannelInfo->DimmInfo[Dimm];
|
|
MemInfoData->dimmSize[Index] = (UINT16) DimmInfo->DimmCapacity;
|
|
MemInfoData->DimmStatus[Index] = DimmInfo->Status;
|
|
MemInfoData->RankInDimm[Index] = DimmInfo->RankInDimm;
|
|
/**
|
|
Get pointer of SPD data read from MRC for SMBIOS driver to report w/o reading SMBus again.
|
|
MRC only provides SMBIOS data and Manufacturing data after first boot is saved to NVRAM.
|
|
**/
|
|
MemInfoData->DimmsSpdData[Index] = (DimmInfo->Status < DIMM_NOT_PRESENT) ? (UINT8 *) &(DimmInfo->SpdSave) : NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, "Install MemInfo Protocol\n"));
|
|
//
|
|
// Install MemInfo Protocol.
|
|
//
|
|
Handle = NULL;
|
|
Status = gBS->InstallProtocolInterface (
|
|
&Handle,
|
|
&gMemInfoProtocolGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
MemoryInfoProtocol
|
|
);
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
//
|
|
// Dump MemInfo
|
|
//
|
|
DumpMemInfo (MemoryInfoProtocol);
|
|
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, "MemInfo Exit\n"));
|
|
|
|
return Status;
|
|
}
|
|
|
|
VOID
|
|
DumpMemInfo (
|
|
IN MEM_INFO_PROTOCOL *MemoryInfo
|
|
)
|
|
{
|
|
UINTN Count;
|
|
|
|
Count = 0;
|
|
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, "\n"));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, "MemoryInfo ( Address : 0x%x )\n", MemoryInfo));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " |-MemInfoData ( Address : 0x%x )\n", &MemoryInfo->MemInfoData));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " |-memSize : %x\n", MemoryInfo->MemInfoData.memSize));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " |-ddrFreq : %x\n", MemoryInfo->MemInfoData.ddrFreq));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " |-EccSupport : %x\n", MemoryInfo->MemInfoData.EccSupport));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " |-RefClk : %x\n", MemoryInfo->MemInfoData.RefClk));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " |-Ratio : %x\n", MemoryInfo->MemInfoData.Ratio));
|
|
for (Count = 0; Count < ( NODE_NUM * CH_NUM * DIMM_NUM ); Count = Count + 1 ) {
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " |-dimmSize[%d] : %x\n", Count, MemoryInfo->MemInfoData.dimmSize[Count]));
|
|
}
|
|
for (Count = 0; Count < (NODE_NUM * CH_NUM * DIMM_NUM); Count = Count + 1) {
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " |-DimmStatus[%d] : %x\n", Count, MemoryInfo->MemInfoData.DimmStatus[Count]));
|
|
}
|
|
for (Count = 0; Count < (NODE_NUM * CH_NUM * DIMM_NUM); Count = Count + 1) {
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " |-RankInDimm[%d] : %x\n", Count, MemoryInfo->MemInfoData.RankInDimm[Count]));
|
|
}
|
|
for (Count = 0; Count < PROFILE_NUM; Count = Count + 1) {
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " |-VddVoltage[%d] : %x\n", Count, MemoryInfo->MemInfoData.VddVoltage[Count]));
|
|
}
|
|
for (Count = 0; Count < PROFILE_NUM; Count = Count + 1) {
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " |-Timing[%d] ( Address : 0x%x )\n", Count, MemoryInfo->MemInfoData.Timing[Count]));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-tCK : %x\n", MemoryInfo->MemInfoData.Timing[Count].tCK));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-NMode : %x\n", MemoryInfo->MemInfoData.Timing[Count].NMode));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-tCL : %x\n", MemoryInfo->MemInfoData.Timing[Count].tCL));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-tCWL : %x\n", MemoryInfo->MemInfoData.Timing[Count].tCWL));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-tFAW : %x\n", MemoryInfo->MemInfoData.Timing[Count].tFAW));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-tRAS : %x\n", MemoryInfo->MemInfoData.Timing[Count].tRAS));
|
|
// DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-tRC : %x\n", MemoryInfo->MemInfoData.Timing[Count].tRC));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-tRCDtRP : %x\n", MemoryInfo->MemInfoData.Timing[Count].tRCDtRP));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-tREFI : %x\n", MemoryInfo->MemInfoData.Timing[Count].tREFI));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-tRFC : %x\n", MemoryInfo->MemInfoData.Timing[Count].tRFC));
|
|
// DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-tRP : %x\n", MemoryInfo->MemInfoData.Timing[Count].tRP));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-tRPab : %x\n", MemoryInfo->MemInfoData.Timing[Count].tRPab));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-tRRD : %x\n", MemoryInfo->MemInfoData.Timing[Count].tRRD));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-tRTP : %x\n", MemoryInfo->MemInfoData.Timing[Count].tRTP));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-tWR : %x\n", MemoryInfo->MemInfoData.Timing[Count].tWR));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " | |-tWTR : %x\n", MemoryInfo->MemInfoData.Timing[Count].tWTR));
|
|
}
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " |-Profile : %x\n", MemoryInfo->MemInfoData.Profile));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " |-XmpProfileEnable : %x\n", MemoryInfo->MemInfoData.XmpProfileEnable));
|
|
DEBUG ((DEBUG_INFO | DEBUG_ERROR, " |-DdrType : %x\n", MemoryInfo->MemInfoData.DdrType));
|
|
|
|
return;
|
|
}
|