diff options
author | Leif Lindholm <leif.lindholm@linaro.org> | 2017-08-03 12:24:30 +0100 |
---|---|---|
committer | Leif Lindholm <leif.lindholm@linaro.org> | 2017-08-03 12:24:30 +0100 |
commit | 600081b52debde8d06585fdaf09fac16d323670f (patch) | |
tree | fef3287095bb56eba411c0b31c525283978b71fb /Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe | |
parent | f4d38e50c0f24eb78eb003a94f583025621c63db (diff) | |
download | edk2-platforms-600081b52debde8d06585fdaf09fac16d323670f.tar.xz |
Platform,Silicon: Import Hisilicon D02,D03,D05 and HiKey
Imported from commit efd798c1eb of
https://git.linaro.org/uefi/OpenPlatformPkg.git
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Diffstat (limited to 'Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe')
4 files changed, 930 insertions, 0 deletions
diff --git a/Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClass.c b/Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClass.c new file mode 100644 index 0000000000..da714c9e22 --- /dev/null +++ b/Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClass.c @@ -0,0 +1,762 @@ +/** @file
+*
+* Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+* Copyright (c) 2015, Linaro Limited. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+
+#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 pGBL_DATA 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 pGBL_DATA 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 pGBL_DATA pGblData,
+ IN UINT8 Skt,
+ IN UINT8 Ch,
+ IN UINT8 Dimm
+)
+{
+ if (pGblData->Channel[Skt][Ch].Status == FALSE ||
+ pGblData->Channel[Skt][Ch].Dimm[Dimm].Status == FALSE)
+ {
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+UINT8
+SmbiosGetMemoryType (
+ IN pGBL_DATA 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 pGBL_DATA 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 pGBL_DATA 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 pGBL_DATA 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 pGBL_DATA 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 pGBL_DATA 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);
+ UnicodeStrToAsciiStr (DeviceLocatorStr, OptionalStrStart);
+ UnicodeStrToAsciiStr (BankLocatorStr, OptionalStrStart + DeviceLocatorStrLen + 1);
+ UnicodeStrToAsciiStr (ManufactureStr, OptionalStrStart + DeviceLocatorStrLen + 1 + BankLocatorStrLen + 1);
+ UnicodeStrToAsciiStr (SerialNumberStr, OptionalStrStart + DeviceLocatorStrLen + 1 + BankLocatorStrLen + 1 + ManufactureStrLen + 1);
+ UnicodeStrToAsciiStr (AssertTagStr, OptionalStrStart + DeviceLocatorStrLen + 1 + BankLocatorStrLen + 1 + ManufactureStrLen + 1 + SerialNumberStrLen + 1);
+ UnicodeStrToAsciiStr (PartNumberStr, OptionalStrStart + DeviceLocatorStrLen + 1 + BankLocatorStrLen + 1 + ManufactureStrLen + 1 + SerialNumberStrLen + 1 + AssertTagStrLen + 1);
+
+ 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;
+ pGBL_DATA 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 = (pGBL_DATA) 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;
+}
diff --git a/Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClass.h b/Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClass.h new file mode 100644 index 0000000000..c35ce39d61 --- /dev/null +++ b/Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClass.h @@ -0,0 +1,79 @@ +/** @file
+*
+* Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+* Copyright (c) 2015, Linaro Limited. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+
+#ifndef _MEMORY_SUBCLASS_DRIVER_H
+#define _MEMORY_SUBCLASS_DRIVER_H
+
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/HiiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/HobLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PcdLib.h>
+
+#include <Library/HwMemInitLib.h>
+#include <Guid/DebugMask.h>
+#include <Guid/MemoryMapData.h>
+#include <Library/PlatformSysCtrlLib.h>
+#include <Library/OemMiscLib.h>
+
+//
+// This is the generated header file which includes whatever needs to be exported (strings + IFR)
+//
+
+extern UINT8 MemorySubClassStrings[];
+
+#define MAX_DIMM_SIZE 32 // In GB
+
+struct SPD_JEDEC_MANUFACTURER
+{
+ UINT8 MfgIdLSB;
+ UINT8 MfgIdMSB;
+ CHAR16 *Name;
+};
+
+struct SPD_JEDEC_MANUFACTURER JEP106[] = {
+ { 0, 0x10, L"NEC"},
+ { 0, 0x2c, L"Micron"},
+ { 0, 0x3d, L"Tektronix"},
+ { 0, 0x97, L"TI"},
+ { 0, 0xad, L"Hynix"},
+ { 0, 0xb3, L"IDT"},
+ { 0, 0xc1, L"Infineon"},
+ { 0, 0xce, L"Samsung"},
+ { 1, 0x94, L"Smart"},
+ { 1, 0x98, L"Kingston"},
+ { 2, 0xc8, L"Agilent"},
+ { 2, 0xfe, L"Elpida"},
+ { 3, 0x0b, L"Nanya"},
+ { 4, 0x43, L"Ramaxel"},
+ { 4, 0xb3, L"Inphi"},
+ { 5, 0x51, L"Qimonda"},
+ { 5, 0x57, L"AENEON"},
+ { 0xFF, 0xFF, L""}
+};
+
+
+
+#endif
diff --git a/Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassDxe.inf b/Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassDxe.inf new file mode 100644 index 0000000000..93a2bcac37 --- /dev/null +++ b/Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassDxe.inf @@ -0,0 +1,59 @@ +#/** @file
+#
+# Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+# Copyright (c) 2015, Linaro Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = MemorySubClass
+ FILE_GUID = 62194F1A-5A0D-4B33-9EF0-7D05C6CB923A
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = MemorySubClassEntryPoint
+
+[Sources]
+ MemorySubClassStrings.uni
+ MemorySubClass.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+ Silicon/Hisilicon/HisiPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ HobLib
+ HiiLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ BaseLib
+ DebugLib
+ PrintLib
+ PlatformSysCtrlLib
+ PcdLib
+
+[Protocols]
+ gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+
+[Pcd]
+
+[Guids]
+ gHisiEfiMemoryMapGuid
+
+[Depex]
+ gEfiSmbiosProtocolGuid
+
+
diff --git a/Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassStrings.uni b/Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassStrings.uni new file mode 100644 index 0000000000..edf8464e5c --- /dev/null +++ b/Silicon/Hisilicon/Drivers/Smbios/MemorySubClassDxe/MemorySubClassStrings.uni @@ -0,0 +1,30 @@ +// *++
+//
+// Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+// Copyright (c) 2015, Linaro Limited. All rights reserved.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// --*/
+
+/=#
+
+#langdef en-US "English"
+
+//
+// Begin English Language Strings
+//
+
+#string STR_MEMORY_SUBCLASS_UNKNOWN #language en-US "Unknown"
+
+//
+// End English Language Strings
+//
+
|