/** @file
|
*
|
* Copyright (c) 2015, Hisilicon Limited. All rights reserved.
|
* Copyright (c) 2015, Linaro Limited. All rights reserved.
|
*
|
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
*
|
**/
|
|
|
#include "MemorySubClass.h"
|
|
EFI_SMBIOS_PROTOCOL *mSmbios = NULL;
|
EFI_HII_HANDLE mHiiHandle;
|
|
UINT8 mMaxSkt;
|
UINT8 mMaxCh;
|
|
VOID
|
SmbiosGetManufacturer (
|
IN UINT8 MfgIdLSB,
|
IN UINT8 MfgIdMSB,
|
OUT CHAR16 *Manufacturer
|
)
|
{
|
UINT32 Index = 0;
|
|
(VOID)StrCpyS(Manufacturer, SMBIOS_STRING_MAX_LENGTH - 1, L"Unknown");
|
while (JEP106[Index].MfgIdLSB != 0xFF && JEP106[Index].MfgIdMSB != 0xFF )
|
{
|
if (JEP106[Index].MfgIdLSB == MfgIdLSB && JEP106[Index].MfgIdMSB == MfgIdMSB)
|
{
|
(VOID)StrCpyS (Manufacturer, SMBIOS_STRING_MAX_LENGTH - 1, JEP106[Index].Name);
|
break;
|
}
|
Index++;
|
}
|
}
|
|
VOID
|
SmbiosGetPartNumber (
|
IN GBL_INTERFACE *pGblData,
|
IN UINT8 Skt,
|
IN UINT8 Ch,
|
IN UINT8 Dimm,
|
OUT CHAR16 *PartNumber
|
)
|
{
|
CHAR16 StringBuffer2[SMBIOS_STRING_MAX_LENGTH];
|
UINT32 Index2;
|
|
(VOID)StrCpyS(PartNumber, SMBIOS_STRING_MAX_LENGTH - 1, L"");
|
if (pGblData->Channel[Skt][Ch].Dimm[Dimm].DramType == SPD_TYPE_DDR3)
|
{
|
for (Index2 = 0; Index2 < SPD_MODULE_PART; Index2++)
|
{
|
UnicodeSPrint (StringBuffer2, SMBIOS_STRING_MAX_LENGTH - 1, L"%c", pGblData->Channel[Skt][Ch].Dimm[Dimm].SpdModPart[Index2]);
|
(VOID)StrCatS(PartNumber, SMBIOS_STRING_MAX_LENGTH - 1, StringBuffer2);
|
}
|
}
|
else
|
{
|
for (Index2 = 0; Index2 < SPD_MODULE_PART_DDR4; Index2++)
|
{
|
UnicodeSPrint (StringBuffer2, SMBIOS_STRING_MAX_LENGTH - 1, L"%c", pGblData->Channel[Skt][Ch].Dimm[Dimm].SpdModPartDDR4[Index2]);
|
(VOID)StrCatS(PartNumber, SMBIOS_STRING_MAX_LENGTH - 1, StringBuffer2);
|
}
|
}
|
|
return;
|
}
|
|
VOID
|
SmbiosGetSerialNumber (
|
IN GBL_INTERFACE *pGblData,
|
IN UINT8 Skt,
|
IN UINT8 Ch,
|
IN UINT8 Dimm,
|
OUT CHAR16 *SerialNumber
|
)
|
{
|
UINT32 Temp;
|
|
Temp = SwapBytes32 (pGblData->Channel[Skt][Ch].Dimm[Dimm].SpdSerialNum);
|
|
UnicodeSPrint(SerialNumber, SMBIOS_STRING_MAX_LENGTH, L"0x%08x", Temp);
|
|
return;
|
}
|
|
BOOLEAN
|
IsDimmPresent (
|
IN GBL_INTERFACE *pGblData,
|
IN UINT8 Skt,
|
IN UINT8 Ch,
|
IN UINT8 Dimm
|
)
|
{
|
if (pGblData->Channel[Skt][Ch].Enabled == FALSE ||
|
pGblData->Channel[Skt][Ch].Dimm[Dimm].Enabled == FALSE)
|
{
|
return FALSE;
|
}
|
else
|
{
|
return TRUE;
|
}
|
}
|
|
UINT8
|
SmbiosGetMemoryType (
|
IN GBL_INTERFACE *pGblData,
|
IN UINT8 Skt,
|
IN UINT8 Ch,
|
IN UINT8 Dimm
|
)
|
{
|
UINT8 MemoryType;
|
|
if(!IsDimmPresent(pGblData, Skt, Ch, Dimm))
|
{
|
return MemoryTypeUnknown;
|
}
|
|
if (pGblData->Channel[Skt][Ch].Dimm[Dimm].DramType == SPD_TYPE_DDR3)
|
{
|
MemoryType = MemoryTypeDdr3;
|
}
|
else if (pGblData->Channel[Skt][Ch].Dimm[Dimm].DramType == SPD_TYPE_DDR4)
|
{
|
MemoryType = MemoryTypeDdr4;
|
}
|
else
|
{
|
MemoryType = MemoryTypeUnknown;
|
}
|
|
return MemoryType;
|
}
|
|
VOID
|
SmbiosGetTypeDetail (
|
IN GBL_INTERFACE *pGblData,
|
IN UINT8 Skt,
|
IN UINT8 Ch,
|
IN UINT8 Dimm,
|
IN OUT MEMORY_DEVICE_TYPE_DETAIL *TypeDetail
|
)
|
{
|
if (NULL == TypeDetail)
|
{
|
return;
|
}
|
|
if(!IsDimmPresent(pGblData, Skt, Ch, Dimm))
|
{
|
TypeDetail->Unknown = 1;
|
return;
|
}
|
|
switch (pGblData->Channel[Skt][Ch].Dimm[Dimm].ModuleType)
|
{
|
case SPD_UDIMM:
|
TypeDetail->Unbuffered = 1;
|
break;
|
|
case SPD_LRDIMM:
|
TypeDetail->LrDimm = 1;
|
break;
|
|
case SPD_RDIMM:
|
TypeDetail->Registered = 1;
|
break;
|
|
default:
|
TypeDetail->Unknown = 1;
|
break;
|
}
|
}
|
|
VOID
|
SmbiosGetDimmVoltageInfo (
|
IN GBL_INTERFACE *pGblData,
|
IN UINT8 Skt,
|
IN UINT8 Ch,
|
IN UINT8 Dimm,
|
IN OUT SMBIOS_TABLE_TYPE17 *Type17Record
|
|
)
|
{
|
if(!IsDimmPresent(pGblData, Skt, Ch, Dimm))
|
{
|
return;
|
}
|
|
if (pGblData->Channel[Skt][Ch].Dimm[Dimm].DramType == SPD_TYPE_DDR3)
|
{
|
Type17Record->MinimumVoltage = 1250;
|
Type17Record->MaximumVoltage = 1500;
|
|
switch (pGblData->Channel[Skt][Ch].Dimm[Dimm].SpdVdd)
|
{
|
case SPD_VDD_150:
|
Type17Record->ConfiguredVoltage = 1500;
|
break;
|
|
case SPD_VDD_135:
|
Type17Record->ConfiguredVoltage = 1350;
|
break;
|
|
case SPD_VDD_125:
|
Type17Record->ConfiguredVoltage = 1250;
|
break;
|
|
default:
|
break;
|
}
|
}
|
else if (pGblData->Channel[Skt][Ch].Dimm[Dimm].DramType == SPD_TYPE_DDR4)
|
{
|
Type17Record->MinimumVoltage = 1200;
|
Type17Record->MaximumVoltage = 2000;
|
switch (pGblData->Channel[Skt][Ch].Dimm[Dimm].SpdVdd)
|
{
|
case SPD_VDD_120:
|
Type17Record->ConfiguredVoltage = 1200;
|
break;
|
|
default:
|
break;
|
}
|
}
|
}
|
|
VOID
|
SmbiosGetMemoryDevicesNumber (
|
IN OUT UINT16 *NumberOfDevices
|
)
|
{
|
UINT8 Skt, Ch, Dimm;
|
|
for(Skt = 0; Skt < mMaxSkt; Skt++)
|
{
|
for(Ch = 0; Ch < mMaxCh; Ch++)
|
{
|
for(Dimm = 0; Dimm < OemGetDimmSlot(Skt, Ch); Dimm++)
|
{
|
(*NumberOfDevices)++;
|
}
|
}
|
}
|
}
|
|
UINT8
|
SmbiosGetPartitionWidth (
|
)
|
{
|
|
UINT8 Skt, Ch, Dimm;
|
UINT8 PartitionWidth = 0;
|
|
for(Skt = 0; Skt < mMaxSkt; Skt++)
|
{
|
for(Ch = 0; Ch < mMaxCh; Ch++)
|
{
|
for(Dimm = 0; Dimm < OemGetDimmSlot(Skt, Ch); Dimm++)
|
{
|
PartitionWidth++;
|
}
|
}
|
}
|
|
return PartitionWidth;
|
}
|
|
EFI_STATUS
|
SmbiosAddType16Table (
|
IN GBL_INTERFACE *pGblData,
|
OUT EFI_SMBIOS_HANDLE *MemArraySmbiosHandle
|
)
|
{
|
EFI_STATUS Status;
|
UINT64 MemoryCapacity;
|
SMBIOS_TABLE_TYPE16 *Type16Record;
|
|
UINT16 NumberOfMemoryDevices = 0;
|
|
SmbiosGetMemoryDevicesNumber (&NumberOfMemoryDevices);
|
|
MemoryCapacity = (UINT64) LShiftU64 (NumberOfMemoryDevices * MAX_DIMM_SIZE, 20); // GB to KB.
|
|
//
|
// Type 16 SMBIOS Record
|
//
|
Type16Record = AllocateZeroPool(sizeof(SMBIOS_TABLE_TYPE16) + 1 + 1);
|
if (NULL == Type16Record)
|
{
|
return EFI_OUT_OF_RESOURCES;
|
}
|
|
Type16Record->Hdr.Type = EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY;
|
Type16Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE16);
|
Type16Record->Hdr.Handle = 0x0;
|
Type16Record->Location = MemoryArrayLocationSystemBoard;
|
Type16Record->Use = MemoryArrayUseSystemMemory;
|
Type16Record->MemoryErrorInformationHandle = 0xFFFE;
|
Type16Record->NumberOfMemoryDevices = NumberOfMemoryDevices;
|
|
if(pGblData->EccEn)
|
{
|
Type16Record->MemoryErrorCorrection = MemoryErrorCorrectionSingleBitEcc;
|
}
|
else
|
{
|
Type16Record->MemoryErrorCorrection = MemoryErrorCorrectionNone;
|
}
|
|
if (MemoryCapacity >= 0x80000000)
|
{
|
Type16Record->MaximumCapacity = 0x80000000; // in KB;
|
Type16Record->ExtendedMaximumCapacity = MemoryCapacity << 10; // Extended Max capacity should be stored in bytes.
|
}
|
else
|
{
|
Type16Record->MaximumCapacity = (UINT32)MemoryCapacity; // Max capacity should be stored in kilo bytes.
|
Type16Record->ExtendedMaximumCapacity = 0;
|
}
|
|
*MemArraySmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
|
Status = mSmbios->Add (mSmbios, NULL, MemArraySmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)Type16Record);
|
if(EFI_ERROR(Status))
|
{
|
DEBUG((EFI_D_ERROR, "[%a]:[%dL] Smbios Type16 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
|
}
|
|
FreePool(Type16Record);
|
return Status;
|
}
|
|
EFI_STATUS
|
SmbiosAddType19Table (
|
IN GBL_INTERFACE *pGblData,
|
IN EFI_SMBIOS_HANDLE MemArraySmbiosHandle
|
)
|
{
|
EFI_STATUS Status;
|
UINT32 MemInfoTotalMem;
|
UINT64 TotalMemorySize;
|
EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle;
|
SMBIOS_TABLE_TYPE19 *Type19Record;
|
|
MemInfoTotalMem = pGblData->MemSize; // In MB
|
|
if (MemInfoTotalMem == 0)
|
{
|
return EFI_NOT_FOUND;
|
}
|
|
TotalMemorySize = (UINT64) LShiftU64 (MemInfoTotalMem, 10); // MB to KB.
|
|
//
|
// Type 19 SMBIOS Record
|
//
|
Type19Record = AllocateZeroPool(sizeof(SMBIOS_TABLE_TYPE19) + 1 + 1);
|
if (NULL == Type19Record)
|
{
|
return EFI_OUT_OF_RESOURCES;
|
}
|
|
Type19Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS;
|
Type19Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19);
|
Type19Record->Hdr.Handle = 0x0;
|
Type19Record->StartingAddress = 0x0;
|
Type19Record->EndingAddress = (UINT32) (TotalMemorySize - 1); // in KB;
|
Type19Record->MemoryArrayHandle = MemArraySmbiosHandle;
|
Type19Record->PartitionWidth = SmbiosGetPartitionWidth ();
|
Type19Record->ExtendedStartingAddress = 0x0;
|
Type19Record->ExtendedEndingAddress = 0x0;
|
|
MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
|
Status = mSmbios->Add (mSmbios, NULL, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER *)Type19Record);
|
if(EFI_ERROR(Status))
|
{
|
DEBUG((EFI_D_ERROR, "[%a]:[%dL] Smbios Type19 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
|
}
|
|
FreePool(Type19Record);
|
return Status;
|
}
|
|
|
EFI_STATUS
|
SmbiosAddType17Table (
|
IN GBL_INTERFACE *pGblData,
|
IN UINT8 Skt,
|
IN UINT8 Ch,
|
IN UINT8 Dimm,
|
IN EFI_SMBIOS_HANDLE MemArraySmbiosHandle
|
)
|
{
|
EFI_STATUS Status;
|
SMBIOS_TABLE_TYPE17 *Type17Record;
|
EFI_SMBIOS_HANDLE MemDevSmbiosHandle;
|
UINTN TableSize;
|
|
UINTN StringBufferSize;
|
EFI_STRING StringBuffer;
|
UINT16 MemInfoMemFreq;
|
UINT16 MemoryTotalWidth;
|
UINT16 MemoryDataWidth;
|
UINT16 MemoryDeviceSize;
|
UINT16 MemorySpeed;
|
UINT8 Attributes;
|
UINT32 MemoryDeviceExtendSize;
|
UINT16 CfgMemorySpeed;
|
|
CHAR8 *OptionalStrStart;
|
UINTN DeviceLocatorStrLen;
|
UINTN BankLocatorStrLen;
|
UINTN ManufactureStrLen;
|
UINTN SerialNumberStrLen;
|
UINTN AssertTagStrLen;
|
UINTN PartNumberStrLen;
|
EFI_STRING DeviceLocatorStr;
|
EFI_STRING BankLocatorStr;
|
EFI_STRING ManufactureStr;
|
EFI_STRING SerialNumberStr;
|
EFI_STRING AssertTagStr;
|
EFI_STRING PartNumberStr;
|
EFI_STRING_ID DeviceLocator;
|
|
Type17Record = NULL;
|
DeviceLocatorStr = NULL;
|
BankLocatorStr = NULL;
|
ManufactureStr = NULL;
|
SerialNumberStr = NULL;
|
AssertTagStr = NULL;
|
PartNumberStr = NULL;
|
|
MemoryTotalWidth = 0;
|
MemoryDataWidth = 0;
|
MemoryDeviceSize = 0;
|
MemoryDeviceExtendSize = 0;
|
MemorySpeed = 0;
|
Attributes = 0;
|
CfgMemorySpeed = 0;
|
|
//
|
// Allocate Buffers
|
//
|
StringBufferSize = (sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH;
|
StringBuffer = AllocateZeroPool (StringBufferSize);
|
if(NULL == StringBuffer)
|
{
|
return EFI_OUT_OF_RESOURCES;
|
}
|
|
|
//
|
// Manufacture
|
//
|
ManufactureStr = AllocateZeroPool (StringBufferSize);
|
if(NULL == ManufactureStr)
|
{
|
Status = EFI_OUT_OF_RESOURCES;
|
goto FREE_STR_BUF;
|
}
|
UnicodeSPrint(ManufactureStr, SMBIOS_STRING_MAX_LENGTH - 1, L"NO DIMM");
|
|
//
|
// SerialNumber
|
//
|
SerialNumberStr = AllocateZeroPool (StringBufferSize);
|
if(NULL == SerialNumberStr)
|
{
|
Status = EFI_OUT_OF_RESOURCES;
|
goto FREE_STR_MAN;
|
}
|
UnicodeSPrint(SerialNumberStr, SMBIOS_STRING_MAX_LENGTH - 1, L"NO DIMM");
|
|
//
|
// AssetTag
|
//
|
AssertTagStr = AllocateZeroPool (StringBufferSize);
|
if(NULL == AssertTagStr)
|
{
|
Status = EFI_OUT_OF_RESOURCES;
|
goto FREE_STR_SN;
|
}
|
UnicodeSPrint(AssertTagStr, SMBIOS_STRING_MAX_LENGTH - 1, L"NO DIMM");
|
|
//
|
// PartNumber
|
//
|
PartNumberStr = AllocateZeroPool (StringBufferSize);
|
if(NULL == PartNumberStr)
|
{
|
Status = EFI_OUT_OF_RESOURCES;
|
goto FREE_STR_AST;
|
}
|
UnicodeSPrint(PartNumberStr, SMBIOS_STRING_MAX_LENGTH - 1, L"NO DIMM");
|
|
|
if(IsDimmPresent(pGblData, Skt, Ch, Dimm))
|
{
|
MemoryDataWidth = pGblData->Channel[Skt][Ch].Dimm[Dimm].PrimaryBusWidth;
|
MemoryTotalWidth = MemoryDataWidth + pGblData->Channel[Skt][Ch].Dimm[Dimm].ExtensionBusWidth;
|
|
MemoryDeviceSize = pGblData->Channel[Skt][Ch].Dimm[Dimm].DimmSize; //in MB
|
MemoryDeviceExtendSize = 0;
|
|
if (MemoryDeviceSize >= 0x7fff)
|
{
|
MemoryDeviceExtendSize = MemoryDeviceSize; // in MB
|
MemoryDeviceSize = 0x7fff; // max value
|
}
|
|
MemInfoMemFreq = pGblData->Freq;
|
MemorySpeed = pGblData->Channel[Skt][Ch].Dimm[Dimm].DimmSpeed;
|
Attributes = pGblData->Channel[Skt][Ch].Dimm[Dimm].RankNum;
|
CfgMemorySpeed = MemInfoMemFreq;
|
|
//
|
// Manufacturer
|
//
|
SmbiosGetManufacturer (pGblData->Channel[Skt][Ch].Dimm[Dimm].SpdMMfgId & 0xFF,
|
pGblData->Channel[Skt][Ch].Dimm[Dimm].SpdMMfgId >> 8,
|
ManufactureStr
|
);
|
|
//
|
// SerialNumber
|
//
|
SmbiosGetSerialNumber(pGblData, Skt, Ch, Dimm, SerialNumberStr);
|
|
//
|
// AssetTag
|
//
|
UnicodeSPrint(AssertTagStr, SMBIOS_STRING_MAX_LENGTH - 1, L"Unknown");
|
|
//
|
// PartNumber
|
//
|
SmbiosGetPartNumber(pGblData, Skt, Ch, Dimm, PartNumberStr);
|
}
|
|
//
|
// DeviceLocator
|
//
|
DeviceLocatorStr = AllocateZeroPool ((sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH);
|
if(NULL == DeviceLocatorStr)
|
{
|
Status = EFI_OUT_OF_RESOURCES;
|
goto FREE_STR_PN;
|
}
|
DeviceLocator = gDimmToDevLocator[Skt][Ch][Dimm];
|
if (DeviceLocator != 0xFFFF)
|
{
|
UnicodeSPrint(DeviceLocatorStr, SMBIOS_STRING_MAX_LENGTH, L"DIMM%x%x%x ", Skt, Ch, Dimm);
|
StringBuffer = HiiGetPackageString (&gEfiCallerIdGuid, DeviceLocator, NULL);
|
(VOID)StrCatS(DeviceLocatorStr, SMBIOS_STRING_MAX_LENGTH, StringBuffer);
|
}
|
else
|
{
|
UnicodeSPrint(DeviceLocatorStr, SMBIOS_STRING_MAX_LENGTH, L"DIMM%x%x%x", Skt, Ch, Dimm);
|
}
|
DeviceLocatorStrLen = StrLen (DeviceLocatorStr);
|
|
//
|
// BankLocator
|
//
|
BankLocatorStr = AllocateZeroPool ((sizeof (CHAR16)) * SMBIOS_STRING_MAX_LENGTH);
|
if(NULL == BankLocatorStr)
|
{
|
Status = EFI_OUT_OF_RESOURCES;
|
goto FREE_STR_DEV;
|
}
|
UnicodeSPrint(BankLocatorStr, SMBIOS_STRING_MAX_LENGTH, L"SOCKET %x CHANNEL %x DIMM %x", Skt, Ch, Dimm);
|
BankLocatorStrLen = StrLen (BankLocatorStr);
|
|
ManufactureStrLen = StrLen (ManufactureStr);
|
SerialNumberStrLen = StrLen (SerialNumberStr);
|
AssertTagStrLen = StrLen (AssertTagStr);
|
PartNumberStrLen = StrLen (PartNumberStr);
|
|
//
|
// Report Type 17 SMBIOS Record
|
//
|
TableSize = sizeof(SMBIOS_TABLE_TYPE17) + DeviceLocatorStrLen + 1 + BankLocatorStrLen + 1 + ManufactureStrLen + 1 + SerialNumberStrLen + 1 + AssertTagStrLen + 1 + PartNumberStrLen + 1 + 1;
|
Type17Record = AllocateZeroPool (TableSize);
|
if(NULL == Type17Record)
|
{
|
Status = EFI_OUT_OF_RESOURCES;
|
goto FREE_BL;
|
}
|
|
Type17Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_DEVICE;
|
Type17Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE17);
|
Type17Record->Hdr.Handle = 0;
|
Type17Record->MemoryArrayHandle = MemArraySmbiosHandle;
|
Type17Record->MemoryErrorInformationHandle = 0xFFFE;
|
Type17Record->TotalWidth = MemoryTotalWidth;
|
Type17Record->DataWidth = MemoryDataWidth;
|
Type17Record->Size = MemoryDeviceSize; // in MB
|
Type17Record->FormFactor = MemoryFormFactorDimm;
|
Type17Record->DeviceLocator = 1;
|
Type17Record->BankLocator = 2;
|
Type17Record->MemoryType = SmbiosGetMemoryType (pGblData, Skt, Ch, Dimm);
|
|
Type17Record->TypeDetail.Synchronous = 1;
|
|
SmbiosGetTypeDetail (pGblData, Skt, Ch, Dimm, &(Type17Record->TypeDetail));
|
|
Type17Record->Speed = MemorySpeed; // in MHZ
|
Type17Record->Manufacturer = 3;
|
Type17Record->SerialNumber = 4;
|
Type17Record->AssetTag = 5;
|
Type17Record->PartNumber = 6;
|
Type17Record->Attributes = Attributes;
|
Type17Record->ExtendedSize = MemoryDeviceExtendSize;
|
Type17Record->ConfiguredMemoryClockSpeed = CfgMemorySpeed;
|
//
|
// Add for smbios 2.8.0
|
//
|
SmbiosGetDimmVoltageInfo (pGblData, Skt, Ch, Dimm, Type17Record);
|
|
OptionalStrStart = (CHAR8 *) (Type17Record + 1);
|
Status = UnicodeStrToAsciiStrS (DeviceLocatorStr, OptionalStrStart, DeviceLocatorStrLen + 1);
|
ASSERT_EFI_ERROR (Status);
|
Status = UnicodeStrToAsciiStrS (BankLocatorStr, OptionalStrStart + DeviceLocatorStrLen + 1, BankLocatorStrLen + 1);
|
ASSERT_EFI_ERROR (Status);
|
Status = UnicodeStrToAsciiStrS (ManufactureStr, OptionalStrStart + DeviceLocatorStrLen + 1 + BankLocatorStrLen + 1, ManufactureStrLen + 1);
|
ASSERT_EFI_ERROR (Status);
|
Status = UnicodeStrToAsciiStrS (SerialNumberStr, OptionalStrStart + DeviceLocatorStrLen + 1 + BankLocatorStrLen + 1 + ManufactureStrLen + 1, SerialNumberStrLen + 1);
|
ASSERT_EFI_ERROR (Status);
|
Status = UnicodeStrToAsciiStrS (AssertTagStr, OptionalStrStart + DeviceLocatorStrLen + 1 + BankLocatorStrLen + 1 + ManufactureStrLen + 1 + SerialNumberStrLen + 1, AssertTagStrLen + 1);
|
ASSERT_EFI_ERROR (Status);
|
Status = UnicodeStrToAsciiStrS (PartNumberStr, OptionalStrStart + DeviceLocatorStrLen + 1 + BankLocatorStrLen + 1 + ManufactureStrLen + 1 + SerialNumberStrLen + 1 + AssertTagStrLen + 1, PartNumberStrLen + 1);
|
ASSERT_EFI_ERROR (Status);
|
|
MemDevSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
|
Status = mSmbios->Add (mSmbios, NULL, &MemDevSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type17Record);
|
if(EFI_ERROR(Status))
|
{
|
DEBUG((EFI_D_ERROR, "[%a]:[%dL] Smbios Type17 Table Log Failed! %r \n", __FUNCTION__, __LINE__, Status));
|
}
|
|
FreePool (Type17Record);
|
|
FREE_BL:
|
FreePool (BankLocatorStr);
|
|
FREE_STR_DEV:
|
FreePool (DeviceLocatorStr);
|
|
FREE_STR_PN:
|
FreePool (PartNumberStr);
|
|
FREE_STR_AST:
|
FreePool (AssertTagStr);
|
|
FREE_STR_SN:
|
FreePool (SerialNumberStr);
|
|
FREE_STR_MAN:
|
FreePool (ManufactureStr);
|
|
FREE_STR_BUF:
|
FreePool (StringBuffer);
|
|
return Status;
|
}
|
|
|
/**
|
Standard EFI driver point. This driver locates the MemoryConfigurationData Variable,
|
if it exists, add the related SMBIOS tables by PI SMBIOS protocol.
|
|
@param ImageHandle Handle for the image of this driver
|
@param SystemTable Pointer to the EFI System Table
|
|
@retval EFI_SUCCESS The data was successfully stored.
|
|
**/
|
EFI_STATUS
|
EFIAPI
|
MemorySubClassEntryPoint(
|
IN EFI_HANDLE ImageHandle,
|
IN EFI_SYSTEM_TABLE *SystemTable
|
)
|
{
|
EFI_STATUS Status;
|
EFI_SMBIOS_PROTOCOL *Smbios;
|
EFI_HOB_GUID_TYPE *GuidHob;
|
GBL_INTERFACE *pGblData;
|
EFI_SMBIOS_HANDLE MemArraySmbiosHandle;
|
UINT8 Skt, Ch, Dimm;
|
|
GuidHob = GetFirstGuidHob(&gHisiEfiMemoryMapGuid);
|
if(NULL == GuidHob)
|
{
|
DEBUG((EFI_D_ERROR, "Could not get MemoryMap Guid hob. %r\n"));
|
return EFI_NOT_FOUND;
|
}
|
pGblData = (GBL_INTERFACE*) GET_GUID_HOB_DATA(GuidHob);
|
|
//
|
// Locate dependent protocols
|
//
|
Status = gBS->LocateProtocol(&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);
|
if (EFI_ERROR(Status))
|
{
|
DEBUG((EFI_D_ERROR, "Could not locate SMBIOS protocol. %r\n", Status));
|
return Status;
|
}
|
mSmbios = Smbios;
|
|
//
|
// Add our default strings to the HII database. They will be modified later.
|
//
|
mHiiHandle = OemGetPackages();
|
if(NULL == mHiiHandle)
|
{
|
return EFI_OUT_OF_RESOURCES;
|
}
|
|
mMaxSkt = OemGetSocketNumber();
|
mMaxCh = OemGetDdrChannel();
|
// Get DIMM slot number on Socket 0 Channel 0
|
// TODO: Assume all channels have same slot number
|
|
Status = SmbiosAddType16Table (pGblData, &MemArraySmbiosHandle);
|
if(EFI_ERROR(Status))
|
{
|
DEBUG((EFI_D_ERROR, "Smbios Add Type16 Table Failed. %r\n", Status));
|
return Status;
|
}
|
|
Status = SmbiosAddType19Table (pGblData, MemArraySmbiosHandle);
|
if(EFI_ERROR(Status))
|
{
|
DEBUG((EFI_D_ERROR, "Smbios Add Type19 Table Failed. %r\n", Status));
|
return Status;
|
}
|
|
for(Skt = 0; Skt < mMaxSkt; Skt++)
|
{
|
for(Ch = 0; Ch < mMaxCh; Ch++)
|
{
|
for(Dimm = 0; Dimm < OemGetDimmSlot(Skt, Ch); Dimm++)
|
{
|
Status = SmbiosAddType17Table (pGblData, Skt, Ch, Dimm, MemArraySmbiosHandle);
|
if(EFI_ERROR(Status))
|
{
|
DEBUG((EFI_D_ERROR, "Smbios Add Type17 Table Failed. %r\n", Status));
|
}
|
}
|
}
|
}
|
|
return Status;
|
}
|