207 lines
7.8 KiB
C
207 lines
7.8 KiB
C
/** @file
|
|
DXE Chipset Services Library.
|
|
|
|
This file contains only one function that is DxeCsSvcSetSmbiosMemoryData().
|
|
The function DxeCsSvcSetSmbiosMemoryData() use chipset services to collection
|
|
information of memory and set to SMBIOS.
|
|
|
|
;***************************************************************************
|
|
;* Copyright (c) 2014 - 2022, 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.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Protocol/MemInfo.h>
|
|
#include <CommonSmbiosMemory.h>
|
|
#include <Guid/SlotStatusGuid.h>
|
|
#include <Library/HobLib.h>
|
|
#include <Register/SaRegsHostBridge.h>
|
|
#include <Register/IgdRegs.h>
|
|
//#include <SaRegs.h>
|
|
#include <ConfigBlock.h>
|
|
#include "MemoryConfig.h"
|
|
|
|
//
|
|
// Refer to SmbiosMemory.h
|
|
//
|
|
#define MAX_RANK_CAPACITY (4 * 1024 * 1024)
|
|
|
|
|
|
/**
|
|
To collection information of memory and set to SMBIOS.
|
|
|
|
@param[in, out] ChipsetSmbiosMemData Point to SMBIOS memory data
|
|
|
|
@retval EFI_SUCCESS This function always return successfully.
|
|
*/
|
|
EFI_STATUS
|
|
SetSmbiosMemoryData (
|
|
IN OUT H2O_SMBIOS_MEM_CONFIG_DATA *ChipsetSmbiosMemData
|
|
)
|
|
{
|
|
//
|
|
// Unused code.
|
|
// Temporary to mask code and keep function interface for forward compatibility, the function remove will be next generation.
|
|
//
|
|
// EFI_STATUS Status;
|
|
// EFI_PHYSICAL_ADDRESS BaseAddress;
|
|
// UINT8 DimmIndex;
|
|
// UINT8 ChannelMode;
|
|
// MEM_INFO_PROTOCOL *MemInfoHob;
|
|
// UINT8 SlotIndex;
|
|
// SLOT_STATUS_INFO *SlotStatusInfo;
|
|
// VOID *HOB;
|
|
// VOID *HobList;
|
|
// UINT16 MaxSockets;
|
|
//
|
|
// SlotIndex = 0;
|
|
// MaxSockets = 0;
|
|
// HOB = NULL;
|
|
// HobList = NULL;
|
|
// SlotStatusInfo = NULL;
|
|
//
|
|
// Status = gBS->LocateProtocol (&gMemInfoProtocolGuid, NULL, (VOID **)&MemInfoHob);
|
|
//
|
|
// //
|
|
// // These are Chipset specific.
|
|
// //
|
|
// //
|
|
// // Detect ECC
|
|
// // Mobile system doesn't support ECC.
|
|
// //
|
|
// ChipsetSmbiosMemData->ArrayLocationData.MemoryErrorCorrection = MemoryErrorCorrectionNone;
|
|
// if (!EFI_ERROR(Status) && MemInfoHob->MemInfoData.EccSupport) {
|
|
// ChipsetSmbiosMemData->ArrayLocationData.MemoryErrorCorrection = MemoryErrorCorrectionSingleBitEcc;
|
|
// }
|
|
//
|
|
// //
|
|
// // Data for TYPE 16 SMBIOS Structure
|
|
// //
|
|
//
|
|
// //
|
|
// // Create physical array and associated data for all mainboard memory
|
|
// //
|
|
// ChipsetSmbiosMemData->ArrayLocationData.Location = MemoryArrayLocationSystemBoard;
|
|
// ChipsetSmbiosMemData->ArrayLocationData.Use = MemoryArrayUseSystemMemory;
|
|
//
|
|
// //
|
|
// // These are Chipset specific.
|
|
// //
|
|
// //
|
|
// // Detect ECC
|
|
// // Mobile system doesn't support ECC.
|
|
// //
|
|
// ChipsetSmbiosMemData->ArrayLocationData.MemoryErrorCorrection = MemoryErrorCorrectionNone;
|
|
// if (MemInfoHob->MemInfoData.EccSupport) {
|
|
// ChipsetSmbiosMemData->ArrayLocationData.MemoryErrorCorrection = MemoryErrorCorrectionSingleBitEcc;
|
|
// }
|
|
// //
|
|
// // Get Present Socket Number.
|
|
// //
|
|
// HOB = GetFirstGuidHob(&gSlotStatusGuid);
|
|
//
|
|
// if ( HOB != NULL ) {
|
|
// SlotStatusInfo = (SLOT_STATUS_INFO *)((UINT8 *)HOB + sizeof (EFI_HOB_GUID_TYPE));
|
|
// for (SlotIndex = 0; SlotIndex < ((SlotStatusInfo->MaxChannel) * (SlotStatusInfo->MaxDimmsInChannel)); SlotIndex++) {
|
|
// if (SlotStatusInfo->SlotStatus [SlotIndex] != NOT_PRESENT) {
|
|
// MaxSockets++;
|
|
// }
|
|
// }
|
|
//
|
|
// } else {
|
|
// MaxSockets = MAX_SOCKETS;
|
|
// }
|
|
// //
|
|
// // The MemoryCapacity is in kilobytes
|
|
// //
|
|
// ChipsetSmbiosMemData->ArrayLocationData.MaximumCapacity = MAX_RANK_CAPACITY * MEM_CFG_MAX_RANKS_PER_DIMM * MaxSockets;;
|
|
// ChipsetSmbiosMemData->ArrayLocationData.NumberOfMemoryDevices = MaxSockets;
|
|
//
|
|
// //
|
|
// // Get Memory size parameters for each rank from the chipset registers
|
|
// //
|
|
//
|
|
// //
|
|
// // We start from a base address of 0 for rank 0. We read the DRAM Row
|
|
// // Boundary Registers to find the end address of each rank.
|
|
// // Now, the size of each rank can be computed from subtracting the base
|
|
// // address of that rank from the end address read from the DRB. The
|
|
// // base address variable is then incremented by the size of each rank.
|
|
// //
|
|
// BaseAddress = 0;
|
|
//
|
|
// //
|
|
// // Channel 0
|
|
// //
|
|
// for (DimmIndex = 0; DimmIndex < MEM_CFG_MAX_DIMMS; DimmIndex++) {
|
|
// ChipsetSmbiosMemData->RowConfArray[DimmIndex].BaseAddress = BaseAddress;
|
|
// ChipsetSmbiosMemData->RowConfArray[DimmIndex*MEM_CFG_MAX_DIMMS].RowLength = LShiftU64(MemInfoHob->MemInfoData.dimmSize[DimmIndex], 20);
|
|
// BaseAddress += ChipsetSmbiosMemData->RowConfArray[DimmIndex].RowLength;
|
|
// }
|
|
//
|
|
// //
|
|
// // If the channel mode is Dual Channel Assymmetric, the the DRB registers for
|
|
// // Channel 1 start are offset from the last rank DRB value in Channel 0.
|
|
// // Otherwise they are offset from 0
|
|
// //
|
|
// // Leave it as Interleaved for now
|
|
// //
|
|
// ChannelMode = 1;
|
|
// if (ChannelMode == 1) {
|
|
// BaseAddress = 0;
|
|
// }
|
|
//
|
|
// //
|
|
// // Channel 1
|
|
// //
|
|
// for (DimmIndex = MEM_CFG_MAX_DIMMS; DimmIndex < MEM_CFG_MAX_DIMMS * MEM_CFG_MAX_CHANNELS; DimmIndex++) {
|
|
// ChipsetSmbiosMemData->RowConfArray[DimmIndex].BaseAddress = BaseAddress;
|
|
// ChipsetSmbiosMemData->RowConfArray[DimmIndex*MEM_CFG_MAX_DIMMS].RowLength = LShiftU64(MemInfoHob->MemInfoData.dimmSize[DimmIndex], 20);
|
|
// BaseAddress += ChipsetSmbiosMemData->RowConfArray[DimmIndex].RowLength;
|
|
// }
|
|
//
|
|
// ChipsetSmbiosMemData->MemoryDeviceData.ConfiguredMemoryClockSpeed = MemInfoHob->MemInfoData.ddrFreq;
|
|
//
|
|
// if (FeaturePcdGet (PcdUseClockRateAsTheUnitOfConfiguredClockSpeed)) {
|
|
// if (ChipsetSmbiosMemData->MemoryDeviceData.ConfiguredMemoryClockSpeed != 0) {
|
|
// ChipsetSmbiosMemData->MemoryDeviceData.ConfiguredMemoryClockSpeed /= 2;
|
|
// }
|
|
// }
|
|
//
|
|
// ChipsetSmbiosMemData->Interleaved = ChannelMode;
|
|
//
|
|
// ChipsetSmbiosMemData->MemoryDeviceData.FormFactor = MemoryFormFactorSodimm;
|
|
//
|
|
// //
|
|
// // Generate Memory Device Mapped Address info (Type 18)
|
|
// //
|
|
// ChipsetSmbiosMemData->Memory32bitErrorInfo.ErrorType = MemoryErrorOk;
|
|
// ChipsetSmbiosMemData->Memory32bitErrorInfo.ErrorGranularity = MemoryGranularityOtherUnknown;
|
|
// ChipsetSmbiosMemData->Memory32bitErrorInfo.ErrorOperation = MemoryErrorOperationUnknown;
|
|
// ChipsetSmbiosMemData->Memory32bitErrorInfo.VendorSyndrome = 0;
|
|
// ChipsetSmbiosMemData->Memory32bitErrorInfo.MemoryArrayErrorAddress = 0x80000000;
|
|
// ChipsetSmbiosMemData->Memory32bitErrorInfo.DeviceErrorAddress = 0x80000000;
|
|
// ChipsetSmbiosMemData->Memory32bitErrorInfo.ErrorResolution = 0x80000000;
|
|
//
|
|
// //
|
|
// // Memory Controller Information (Type 5 Obsolete)
|
|
// //
|
|
// ChipsetSmbiosMemData->MemoryControllerInfo.ErrDetectMethod = ErrorDetectingMethodNone;
|
|
// ChipsetSmbiosMemData->MemoryControllerInfo.ErrCorrectCapability.None = 1;
|
|
// ChipsetSmbiosMemData->MemoryControllerInfo.SupportInterleave = MemoryInterleaveOneWay;
|
|
// ChipsetSmbiosMemData->MemoryControllerInfo.CurrentInterleave = MemoryInterleaveOneWay;
|
|
// ChipsetSmbiosMemData->MemoryControllerInfo.MaxMemoryModuleSize = 0x0D;
|
|
// ChipsetSmbiosMemData->MemoryControllerInfo.SupportSpeed.Other = 1;
|
|
// ChipsetSmbiosMemData->MemoryControllerInfo.SupportMemoryType = 1;
|
|
// ChipsetSmbiosMemData->MemoryControllerInfo.AssociatedMemorySlotNum = (UINT8)MaxSockets;
|
|
|
|
return EFI_UNSUPPORTED;
|
|
}
|