This adds support SMBIOS Tables Type 16, 17, 19 for information of Physical Memory, Memory Device and Memory Array Mapped Address.
Signed-off-by: Minh Nguyen <minhnguy...@os.amperecomputing.com> --- Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 6 + Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h | 24 + Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxeDataTable.c | 26 +- Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type16/PlatformPhysicalMemoryArrayData.c | 48 ++ Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type16/PlatformPhysicalMemoryArrayFunction.c | 44 ++ Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type17/PlatformMemoryDeviceData.c | 63 +++ Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type17/PlatformMemoryDeviceFunction.c | 475 ++++++++++++++++++++ Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type19/PlatformMemoryArrayMappedAddressData.c | 47 ++ Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type19/PlatformMemoryArrayMappedAddressFunction.c | 150 +++++++ Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLibCommon.c | 42 ++ Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxeStrings.uni | 1 + Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type17/PlatformMemoryDevice.uni | 16 + 12 files changed, 941 insertions(+), 1 deletion(-) diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf index 83ff918fc42d..13ae38de01f8 100755 --- a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf @@ -25,6 +25,12 @@ [Sources] Type09/PlatformSystemSlotFunction.c Type11/PlatformOemStringData.c Type11/PlatformOemStringFunction.c + Type16/PlatformPhysicalMemoryArrayData.c + Type16/PlatformPhysicalMemoryArrayFunction.c + Type17/PlatformMemoryDeviceData.c + Type17/PlatformMemoryDeviceFunction.c + Type19/PlatformMemoryArrayMappedAddressData.c + Type19/PlatformMemoryArrayMappedAddressFunction.c Type24/PlatformHardwareSecurityData.c Type24/PlatformHardwareSecurityFunction.c Type38/PlatformIpmiDeviceData.c diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h index c425ed4431da..9b4f2c1e325c 100644 --- a/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h @@ -6,6 +6,8 @@ **/ +#include <Guid/PlatformInfoHob.h> + #ifndef AMPERE_CPU_LIB_H_ #define AMPERE_CPU_LIB_H_ @@ -182,6 +184,28 @@ GetScpBuild ( UINT8 **ScpBuild ); +/** + Get information of DIMM List. + + @param[out] DimmList Pointer contains information of DIMM List. +**/ +VOID +EFIAPI +GetDimmList ( + PLATFORM_DIMM_LIST **DimmList + ); + +/** + Get information of DRAM. + + @param[out] DramInfo Pointer contains information of DRAM. +**/ +VOID +EFIAPI +GetDramInfo ( + PLATFORM_DRAM_INFO **DramInfo + ); + /** Set the number of configured CPM per socket. diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxeDataTable.c b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxeDataTable.c index 84a4962d33fc..de5b9b83fb78 100644 --- a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxeDataTable.c +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxeDataTable.c @@ -23,9 +23,21 @@ SMBIOS_PLATFORM_DXE_TABLE_EXTERNS ( PlatformSystemSlot ) SMBIOS_PLATFORM_DXE_TABLE_EXTERNS ( - SMBIOS_TABLE_TYPE9, + SMBIOS_TABLE_TYPE11, PlatformOemString ) +SMBIOS_PLATFORM_DXE_TABLE_EXTERNS ( + SMBIOS_TABLE_TYPE16, + PlatformPhysicalMemoryArray + ) +SMBIOS_PLATFORM_DXE_TABLE_EXTERNS ( + SMBIOS_TABLE_TYPE17, + PlatformMemoryDevice + ) +SMBIOS_PLATFORM_DXE_TABLE_EXTERNS ( + SMBIOS_TABLE_TYPE19, + PlatformMemoryArrayMappedAddress + ) SMBIOS_PLATFORM_DXE_TABLE_EXTERNS ( SMBIOS_TABLE_TYPE24, PlatformHardwareSecurity @@ -52,6 +64,18 @@ SMBIOS_PLATFORM_DXE_DATA_TABLE mSmbiosPlatformDxeDataTable[] = { SMBIOS_PLATFORM_DXE_TABLE_ENTRY_DATA_AND_FUNCTION ( PlatformOemString ), + //Type16 + SMBIOS_PLATFORM_DXE_TABLE_ENTRY_DATA_AND_FUNCTION ( + PlatformPhysicalMemoryArray + ), + //Type17 + SMBIOS_PLATFORM_DXE_TABLE_ENTRY_DATA_AND_FUNCTION ( + PlatformMemoryDevice + ), + //Type19 + SMBIOS_PLATFORM_DXE_TABLE_ENTRY_DATA_AND_FUNCTION ( + PlatformMemoryArrayMappedAddress + ), // Type24 SMBIOS_PLATFORM_DXE_TABLE_ENTRY_DATA_AND_FUNCTION ( PlatformHardwareSecurity diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type16/PlatformPhysicalMemoryArrayData.c b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type16/PlatformPhysicalMemoryArrayData.c new file mode 100644 index 000000000000..3c0e6a2ce9a0 --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type16/PlatformPhysicalMemoryArrayData.c @@ -0,0 +1,48 @@ +/** @file + + Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "SmbiosPlatformDxe.h" + +// +// Define data for SMBIOS Type 16 Table. +// +SMBIOS_PLATFORM_DXE_TABLE_DATA (SMBIOS_TABLE_TYPE16, PlatformPhysicalMemoryArray) = { + { // Table 1 + { // Header + EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, // Type + sizeof (SMBIOS_TABLE_TYPE16), // Length + SMBIOS_HANDLE_PI_RESERVED, // Handle + }, + MemoryArrayLocationSystemBoard, // Location + MemoryArrayUseSystemMemory, // Use + MemoryErrorCorrectionMultiBitEcc, // Memory Error Correction + 0x80000000, // Maximum Capacity + 0xFFFE, // Memory Error Information Handle + 0x10, // Number Of Memory Device + 0x40000000000ULL // Extended Maximum Capacity + }, + { // Null-terminated table + { + NULL_TERMINATED_TYPE, + 0, + 0 + }, + } +}; + +// +// Define string Tokens for additional strings. +// +SMBIOS_PLATFORM_DXE_STRING_TOKEN_DATA (PlatformPhysicalMemoryArray) = { + { // Table 1 + { // Tokens array + NULL_TERMINATED_TOKEN + }, + 0 // Size of Tokens array + } +}; diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type16/PlatformPhysicalMemoryArrayFunction.c b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type16/PlatformPhysicalMemoryArrayFunction.c new file mode 100644 index 000000000000..772fa02cc256 --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type16/PlatformPhysicalMemoryArrayFunction.c @@ -0,0 +1,44 @@ +/** @file + + Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Library/AmpereCpuLib.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> + +#include "SmbiosPlatformDxe.h" + +/** + This function adds SMBIOS Table (Type 16) records. + + @param RecordData Pointer to SMBIOS Table with default values. + @param Smbios SMBIOS protocol. + + @retval EFI_SUCCESS The SMBIOS Table was successfully added. + @retval Other Failed to update the SMBIOS Table. + +**/ +SMBIOS_PLATFORM_DXE_TABLE_FUNCTION (PlatformPhysicalMemoryArray) { + UINT8 Index; + EFI_STATUS Status; + SMBIOS_TABLE_TYPE16 *InputData; + + for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) { + InputData = (SMBIOS_TABLE_TYPE16 *)RecordData; + + while (InputData->Hdr.Type != NULL_TERMINATED_TYPE) { + Status = SmbiosPlatformDxeAddRecord ((UINT8 *)InputData, NULL); + if (EFI_ERROR (Status)) { + return Status; + } + + InputData++; + } + } + + return Status; +} diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type17/PlatformMemoryDeviceData.c b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type17/PlatformMemoryDeviceData.c new file mode 100644 index 000000000000..2b2c2fc3b4df --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type17/PlatformMemoryDeviceData.c @@ -0,0 +1,63 @@ +/** @file + + Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "SmbiosPlatformDxe.h" + +// +// Define data for SMBIOS Type 17 Table. +// +SMBIOS_PLATFORM_DXE_TABLE_DATA (SMBIOS_TABLE_TYPE17, PlatformMemoryDevice) = { + { // Table 1 + { // Hdr + EFI_SMBIOS_TYPE_MEMORY_DEVICE, // Type + sizeof (SMBIOS_TABLE_TYPE17), // Length + SMBIOS_HANDLE_PI_RESERVED // Handle + }, + 0xFFFF, // Memory Array Handle + 0xFFFE, // Memory Error Information Handle + 72, // Total Width + 64, // Data Width + 0, // Size + 0x09, // Form Factor + 1, // Device Set + ADDITIONAL_STR_INDEX_1, // Device Locator + ADDITIONAL_STR_INDEX_2, // Bank Locator + MemoryTypeDdr4, // Memory Type + {}, // Type Detail + 0, // Speed + ADDITIONAL_STR_INDEX_3, // Manufacturer + ADDITIONAL_STR_INDEX_4, // Serial + ADDITIONAL_STR_INDEX_5, // Asset Tag + ADDITIONAL_STR_INDEX_6, // Part Number + 0, // Attributes + }, + { // Null-terminated table + { + NULL_TERMINATED_TYPE, + 0, + 0 + }, + } +}; + +// +// Define string Tokens for additional strings. +// +SMBIOS_PLATFORM_DXE_STRING_TOKEN_DATA (PlatformMemoryDevice) = { + { // Table 1 + { // Tokens array + STRING_TOKEN (STR_PLATFORM_DXE_MEMORY_DEVICE_DEVICE_LOCATOR), + STRING_TOKEN (STR_PLATFORM_DXE_MEMORY_DEVICE_BANK_LOCATOR), + STRING_TOKEN (STR_PLATFORM_DXE_MEMORY_DEVICE_MANUFACTURER), + STRING_TOKEN (STR_PLATFORM_DXE_MEMORY_DEVICE_SERIAL_NUMBER), + STRING_TOKEN (STR_PLATFORM_DXE_MEMORY_DEVICE_ASSET_TAG), + STRING_TOKEN (STR_PLATFORM_DXE_MEMORY_DEVICE_PART_NUMBER) + }, + ADDITIONAL_STR_INDEX_6 // Size of Tokens array + } +}; diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type17/PlatformMemoryDeviceFunction.c b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type17/PlatformMemoryDeviceFunction.c new file mode 100644 index 000000000000..d15e4d40a01c --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type17/PlatformMemoryDeviceFunction.c @@ -0,0 +1,475 @@ +/** @file + + Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Guid/PlatformInfoHob.h> +#include <Library/AmpereCpuLib.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/HiiLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PrintLib.h> + +#include "SmbiosPlatformDxe.h" + +#define NULL_TERMINATED_ID 0xFF + +#define ASCII_SPACE_CHARACTER_CODE 0x20 +#define ASCII_TILDE_CHARACTER_CODE 0x7E + +#define SPD_PARITY_BIT_MASK 0x80 +#define SPD_MEMORY_TYPE_OFFSET 0x02 +#define SPD_CONTINUATION_CHARACTER 0x7F + +#define DDR2_SPD_MANUFACTURER_MEMORY_TYPE 0x08 +#define DDR2_SPD_MANUFACTURER_ID_CODE_LENGTH 8 +#define DDR2_SPD_MANUFACTURER_ID_CODE_OFFSET 64 +#define DDR2_SPD_MANUFACTURER_PART_NUMBER_OFFSET 73 +#define DDR2_SPD_MANUFACTURER_SERIAL_NUMBER_OFFSET 95 + +#define DDR3_SPD_MANUFACTURER_MEMORY_TYPE 0x0B +#define DDR3_SPD_MANUFACTURER_ID_BANK_OFFSET 117 +#define DDR3_SPD_MANUFACTURER_ID_CODE_OFFSET 118 +#define DDR3_SPD_MANUFACTURER_PART_NUMBER_OFFSET 128 +#define DDR3_SPD_MANUFACTURER_SERIAL_NUMBER_OFFSET 122 + +#define DDR4_SPD_MANUFACTURER_MEMORY_TYPE 0x0C +#define DDR4_SPD_MANUFACTURER_ID_BANK_OFFSET 320 +#define DDR4_SPD_MANUFACTURER_ID_CODE_OFFSET 321 +#define DDR4_SPD_MANUFACTURER_PART_NUMBER_OFFSET 329 +#define DDR4_SPD_MANUFACTURER_SERIAL_NUMBER_OFFSET 325 + +#define PRINTABLE_CHARACTER(Character) \ + (Character >= ASCII_SPACE_CHARACTER_CODE) && (Character <= ASCII_TILDE_CHARACTER_CODE) ? \ + Character : ASCII_SPACE_CHARACTER_CODE + +typedef enum { + DEVICE_LOCATOR_TOKEN_INDEX = 0, + BANK_LOCATOR_TOKEN_INDEX, + MANUFACTURER_TOKEN_INDEX, + SERIAL_NUMBER_TOKEN_INDEX, + ASSET_TAG_TOKEN_INDEX, + PART_NUMBER_TOKEN_INDEX +} MEMORY_DEVICE_TOKEN_INDEX; + +#pragma pack(1) +typedef struct { + UINT8 VendorId; + CHAR16 *ManufacturerString; +} JEDEC_MF_ID; +#pragma pack() + +JEDEC_MF_ID Bank0Table[] = { + { 0x01, L"AMD\0" }, + { 0x04, L"Fujitsu\0" }, + { 0x07, L"Hitachi\0" }, + { 0x89, L"Intel\0" }, + { 0x10, L"NEC\0" }, + { 0x97, L"Texas Instrument\0" }, + { 0x98, L"Toshiba\0" }, + { 0x1C, L"Mitsubishi\0" }, + { 0x1F, L"Atmel\0" }, + { 0x20, L"STMicroelectronics\0" }, + { 0xA4, L"IBM\0" }, + { 0x2C, L"Micron Technology\0" }, + { 0xAD, L"SK Hynix\0" }, + { 0xB0, L"Sharp\0" }, + { 0xB3, L"IDT\0" }, + { 0x3E, L"Oracle\0" }, + { 0xBF, L"SST\0" }, + { 0x40, L"ProMos/Mosel\0" }, + { 0xC1, L"Infineon\0" }, + { 0xC2, L"Macronix\0" }, + { 0x45, L"SanDisk\0" }, + { 0xCE, L"Samsung\0" }, + { 0xDA, L"Winbond\0" }, + { 0xE0, L"LG Semi\0" }, + { 0x62, L"Sanyo\0" }, + { NULL_TERMINATED_ID, L"Undefined\0" } +}; + +JEDEC_MF_ID Bank1Table[] = { + { 0x98, L"Kingston\0" }, + { 0xBA, L"PNY\0" }, + { 0x4F, L"Transcend\0" }, + { 0x7A, L"Apacer\0" }, + { NULL_TERMINATED_ID, L"Undefined\0" } +}; + +JEDEC_MF_ID Bank2Table[] = { + { 0x9E, L"Corsair\0" }, + { 0xFE, L"Elpida\0" }, + { NULL_TERMINATED_ID, L"Undefined\0" } +}; + +JEDEC_MF_ID Bank3Table[] = { + { 0x0B, L"Nanya\0" }, + { 0x94, L"Mushkin\0" }, + { 0x25, L"Kingmax\0" }, + { NULL_TERMINATED_ID, L"Undefined\0" } +}; + +JEDEC_MF_ID Bank4Table[] = { + { 0xB0, L"OCZ\0" }, + { 0xCB, L"A-DATA\0" }, + { 0xCD, L"G Skill\0" }, + { 0xEF, L"Team\0" }, + { NULL_TERMINATED_ID, L"Undefined\0" } +}; + +JEDEC_MF_ID Bank5Table[] = { + { 0x02, L"Patriot\0" }, + { 0x9B, L"Crucial\0" }, + { 0x51, L"Qimonda\0" }, + { 0x57, L"AENEON\0" }, + { 0xF7, L"Avant\0" }, + { NULL_TERMINATED_ID, L"Undefined\0" } +}; + +JEDEC_MF_ID Bank6Table[] = { + { 0x34, L"Super Talent\0" }, + { 0xD3, L"Silicon Power\0" }, + { NULL_TERMINATED_ID, L"Undefined\0" } +}; + +JEDEC_MF_ID Bank7Table[] = { + { NULL_TERMINATED_ID, L"Undefined\0" } +}; + +JEDEC_MF_ID *ManufacturerJedecIdBankTable[] = { + Bank0Table, + Bank1Table, + Bank2Table, + Bank3Table, + Bank4Table, + Bank5Table, + Bank6Table, + Bank7Table +}; + +VOID +UpdateManufacturer ( + IN UINT8 *SpdData, + IN UINT16 ManufacturerToken + ) +{ + UINTN Index; + UINT8 VendorId; + UINT8 MemType; + UINT8 NumberOfJedecIdBankTables; + JEDEC_MF_ID *IdTblPtr = NULL; + + MemType = SpdData[SPD_MEMORY_TYPE_OFFSET]; + switch (MemType) { + case DDR2_SPD_MANUFACTURER_MEMORY_TYPE: + for (Index = 0; Index < DDR2_SPD_MANUFACTURER_ID_CODE_LENGTH; Index++) { + VendorId = SpdData[DDR2_SPD_MANUFACTURER_ID_CODE_OFFSET + Index]; + if (VendorId != SPD_CONTINUATION_CHARACTER) { + break; + } + } + break; + + case DDR3_SPD_MANUFACTURER_MEMORY_TYPE: + Index = SpdData[DDR3_SPD_MANUFACTURER_ID_BANK_OFFSET] & (~SPD_PARITY_BIT_MASK); // Remove parity bit + VendorId = SpdData[DDR4_SPD_MANUFACTURER_ID_CODE_OFFSET]; + break; + + case DDR4_SPD_MANUFACTURER_MEMORY_TYPE: + Index = SpdData[DDR4_SPD_MANUFACTURER_ID_BANK_OFFSET] & (~SPD_PARITY_BIT_MASK); // Remove parity bit + VendorId = SpdData[DDR4_SPD_MANUFACTURER_ID_CODE_OFFSET]; + break; + + default: // Not supported + return; + } + + NumberOfJedecIdBankTables = ARRAY_SIZE (ManufacturerJedecIdBankTable) - 1; // Exclude NULL-terminated table + if (Index > NumberOfJedecIdBankTables) { + Index = NumberOfJedecIdBankTables; + } + IdTblPtr = ManufacturerJedecIdBankTable[Index]; + + // Search in Manufacturer table and update vendor name accordingly in HII Database + while (IdTblPtr->VendorId != NULL_TERMINATED_ID) { + if (IdTblPtr->VendorId == VendorId) { + HiiSetString (mSmbiosPlatformDxeHiiHandle, ManufacturerToken, IdTblPtr->ManufacturerString, NULL); + break; + } + IdTblPtr++; + } +} + +VOID +UpdateSerialNumber ( + IN UINT8 *SpdData, + IN UINT16 SerialNumberToken + ) +{ + UINT8 MemType; + UINTN Offset; + CHAR16 SerialNumberStr[SMBIOS_UNICODE_STRING_MAX_LENGTH]; + + MemType = SpdData[SPD_MEMORY_TYPE_OFFSET]; + switch (MemType) { + case DDR2_SPD_MANUFACTURER_MEMORY_TYPE: + Offset = DDR2_SPD_MANUFACTURER_SERIAL_NUMBER_OFFSET; + break; + + case DDR3_SPD_MANUFACTURER_MEMORY_TYPE: + Offset = DDR3_SPD_MANUFACTURER_SERIAL_NUMBER_OFFSET; + break; + + case DDR4_SPD_MANUFACTURER_MEMORY_TYPE: + Offset = DDR4_SPD_MANUFACTURER_SERIAL_NUMBER_OFFSET; + break; + + default: // Not supported + return; + } + + UnicodeSPrint ( + SerialNumberStr, + sizeof (SerialNumberStr), + L"%02X%02X%02X%02X", + SpdData[Offset], + SpdData[Offset + 1], + SpdData[Offset + 2], + SpdData[Offset + 3] + ); + HiiSetString (mSmbiosPlatformDxeHiiHandle, SerialNumberToken, SerialNumberStr, NULL); +} + +VOID +UpdatePartNumber ( + IN UINT8 *SpdData, + IN UINT16 PartNumberToken + ) +{ + UINT8 MemType; + UINTN Offset; + CHAR16 PartNumberStr[SMBIOS_UNICODE_STRING_MAX_LENGTH]; + + MemType = SpdData[SPD_MEMORY_TYPE_OFFSET]; + switch (MemType) { + case DDR2_SPD_MANUFACTURER_MEMORY_TYPE: + Offset = DDR2_SPD_MANUFACTURER_PART_NUMBER_OFFSET; + break; + + case DDR3_SPD_MANUFACTURER_MEMORY_TYPE: + Offset = DDR3_SPD_MANUFACTURER_PART_NUMBER_OFFSET; + break; + + case DDR4_SPD_MANUFACTURER_MEMORY_TYPE: + Offset = DDR4_SPD_MANUFACTURER_PART_NUMBER_OFFSET; + break; + + default: // Not supported + return; + } + + UnicodeSPrint ( + PartNumberStr, + sizeof (PartNumberStr), + L"%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", + PRINTABLE_CHARACTER (SpdData[Offset]), + PRINTABLE_CHARACTER (SpdData[Offset + 1]), + PRINTABLE_CHARACTER (SpdData[Offset + 2]), + PRINTABLE_CHARACTER (SpdData[Offset + 3]), + PRINTABLE_CHARACTER (SpdData[Offset + 4]), + PRINTABLE_CHARACTER (SpdData[Offset + 5]), + PRINTABLE_CHARACTER (SpdData[Offset + 6]), + PRINTABLE_CHARACTER (SpdData[Offset + 7]), + PRINTABLE_CHARACTER (SpdData[Offset + 8]), + PRINTABLE_CHARACTER (SpdData[Offset + 9]), + PRINTABLE_CHARACTER (SpdData[Offset + 10]), + PRINTABLE_CHARACTER (SpdData[Offset + 11]), + PRINTABLE_CHARACTER (SpdData[Offset + 12]), + PRINTABLE_CHARACTER (SpdData[Offset + 13]), + PRINTABLE_CHARACTER (SpdData[Offset + 14]), + PRINTABLE_CHARACTER (SpdData[Offset + 15]), + PRINTABLE_CHARACTER (SpdData[Offset + 16]), + PRINTABLE_CHARACTER (SpdData[Offset + 17]) + ); + HiiSetString (mSmbiosPlatformDxeHiiHandle, PartNumberToken, PartNumberStr, NULL); +} + +/** + This function adds SMBIOS Table (Type 17) records. + + @param RecordData Pointer to SMBIOS Table with default values. + @param Smbios SMBIOS protocol. + + @retval EFI_SUCCESS The SMBIOS Table was successfully added. + @retval Other Failed to update the SMBIOS Table. + +**/ +SMBIOS_PLATFORM_DXE_TABLE_FUNCTION (PlatformMemoryDevice) { + UINT8 Index; + UINT8 SlotIndex; + UINTN HandleCount; + UINTN MemorySize; + UINT16 *HandleArray; + CHAR16 UnicodeStr[SMBIOS_UNICODE_STRING_MAX_LENGTH]; + EFI_STATUS Status; + SMBIOS_HANDLE MemoryArrayHandle; + PLATFORM_DIMM *Dimm; + STR_TOKEN_INFO *InputStrToken; + PLATFORM_DIMM_LIST *DimmList; + PLATFORM_DRAM_INFO *DramInfo; + SMBIOS_TABLE_TYPE17 *InputData; + SMBIOS_TABLE_TYPE17 *Type17Record; + + HandleCount = 0; + HandleArray = NULL; + + GetDimmList (&DimmList); + if (DimmList == NULL) { + DEBUG (( + DEBUG_ERROR, + "[%a]:[%dL] Failed to get Dimm List\n", + __func__, + __LINE__ + )); + return EFI_NOT_FOUND; + } + + GetDramInfo (&DramInfo); + if (DramInfo == NULL) { + DEBUG (( + DEBUG_ERROR, + "[%a]:[%dL] Failed to get DRAM Information\n", + __func__, + __LINE__ + )); + return EFI_NOT_FOUND; + } + + SmbiosPlatformDxeGetLinkTypeHandle ( + EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, + &HandleArray, + &HandleCount + ); + if (HandleArray == NULL) { + return EFI_OUT_OF_RESOURCES; + } + if (HandleCount != GetNumberOfSupportedSockets ()) { + DEBUG (( + DEBUG_ERROR, + "[%a]:[%dL] Failed to get Memory Array Handle\n", + __func__, + __LINE__ + )); + FreePool (HandleArray); + return EFI_NOT_FOUND; + } + + for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) { + InputData = (SMBIOS_TABLE_TYPE17 *)RecordData; + InputStrToken = (STR_TOKEN_INFO *)StrToken; + MemoryArrayHandle = HandleArray[Index]; + + while (InputData->Hdr.Type != NULL_TERMINATED_TYPE) { + for (SlotIndex = 0; SlotIndex < DimmList->BoardDimmSlots; SlotIndex++) { + // + // Prepare additional strings for SMBIOS Table. + // + Dimm = &DimmList->Dimm[SlotIndex]; + if (Dimm->NodeId != Index) { + continue; + } + + Status = SmbiosPlatformDxeSaveHiiDefaultString (InputStrToken); + if (EFI_ERROR (Status)) { + FreePool (HandleArray); + return Status; + } + if (Dimm->Info.DimmStatus == DIMM_INSTALLED_OPERATIONAL) { + UpdateManufacturer (Dimm->SpdData.Data, InputStrToken->TokenArray[MANUFACTURER_TOKEN_INDEX]); + UpdateSerialNumber (Dimm->SpdData.Data, InputStrToken->TokenArray[SERIAL_NUMBER_TOKEN_INDEX]); + UpdatePartNumber (Dimm->SpdData.Data, InputStrToken->TokenArray[PART_NUMBER_TOKEN_INDEX]); + } + UnicodeSPrint (UnicodeStr, sizeof (UnicodeStr), L"Socket %d DIMM %d", Index, SlotIndex); + HiiSetString (mSmbiosPlatformDxeHiiHandle, InputStrToken->TokenArray[DEVICE_LOCATOR_TOKEN_INDEX], UnicodeStr, NULL); + UnicodeSPrint (UnicodeStr, sizeof (UnicodeStr), L"Bank %d", SlotIndex); + HiiSetString (mSmbiosPlatformDxeHiiHandle, InputStrToken->TokenArray[BANK_LOCATOR_TOKEN_INDEX], UnicodeStr, NULL); + UnicodeSPrint (UnicodeStr, sizeof (UnicodeStr), L"Array %d Asset Tag %d", Index, SlotIndex); + HiiSetString (mSmbiosPlatformDxeHiiHandle, InputStrToken->TokenArray[ASSET_TAG_TOKEN_INDEX], UnicodeStr, NULL); + + // + // Create Table and fill up information. + // + SmbiosPlatformDxeCreateTable ( + (VOID *)&Type17Record, + (VOID *)&InputData, + sizeof (SMBIOS_TABLE_TYPE17), + InputStrToken + ); + if (Type17Record == NULL) { + FreePool (HandleArray); + return EFI_OUT_OF_RESOURCES; + } + + if (Dimm->Info.DimmStatus == DIMM_INSTALLED_OPERATIONAL) { + MemorySize = Dimm->Info.DimmSize * 1024; + if (MemorySize >= 0x7FFF) { + Type17Record->Size = 0x7FFF; + Type17Record->ExtendedSize = MemorySize; + } else { + Type17Record->Size = (UINT16)MemorySize; + Type17Record->ExtendedSize = 0; + } + + Type17Record->MemoryType = 0x1A; // DDR4 + Type17Record->Speed = (UINT16)DramInfo->MaxSpeed; + Type17Record->ConfiguredMemoryClockSpeed = (UINT16)DramInfo->MaxSpeed; + Type17Record->Attributes = Dimm->Info.DimmNrRank & 0x0F; + Type17Record->ConfiguredVoltage = 1200; + Type17Record->MinimumVoltage = 1140; + Type17Record->MaximumVoltage = 1260; + Type17Record->DeviceSet = 0; // None + + if (Dimm->Info.DimmType == UDIMM || Dimm->Info.DimmType == SODIMM) { + Type17Record->TypeDetail.Unbuffered = 1; // BIT 14: unregistered + } else if (Dimm->Info.DimmType == RDIMM + || Dimm->Info.DimmType == LRDIMM + || Dimm->Info.DimmType == RSODIMM) + { + Type17Record->TypeDetail.Registered = 1; // BIT 13: registered + } + /* FIXME: Determine if need to set technology to NVDIMM-* when supported */ + Type17Record->MemoryTechnology = 0x3; // DRAM + } + // Update Type 16 handle + Type17Record->MemoryArrayHandle = MemoryArrayHandle; + + // + // Add Table record and free pool. + // + Status = SmbiosPlatformDxeAddRecord ((UINT8 *)Type17Record, NULL); + if (EFI_ERROR (Status)) { + FreePool (HandleArray); + FreePool (Type17Record); + return Status; + } + + FreePool (Type17Record); + Status = SmbiosPlatformDxeRestoreHiiDefaultString (InputStrToken); + if (EFI_ERROR (Status)) { + FreePool (HandleArray); + return Status; + } + } + + InputData++; + InputStrToken++; + } + } + FreePool (HandleArray); + + return Status; +} diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type19/PlatformMemoryArrayMappedAddressData.c b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type19/PlatformMemoryArrayMappedAddressData.c new file mode 100644 index 000000000000..d14099ae8852 --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type19/PlatformMemoryArrayMappedAddressData.c @@ -0,0 +1,47 @@ +/** @file + + Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "SmbiosPlatformDxe.h" + +// +// Define data for SMBIOS Type 19 Table. +// +SMBIOS_PLATFORM_DXE_TABLE_DATA (SMBIOS_TABLE_TYPE19, PlatformMemoryArrayMappedAddress) = { + { // Table 1 + { // Header + EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS, // Type + sizeof (SMBIOS_TABLE_TYPE19), // Length + SMBIOS_HANDLE_PI_RESERVED // Handle + }, + 0xFFFFFFFF, // Starting Address + 0xFFFFFFFF, // Ending Address + 0xFFFF, // Memory Array Handle + 1, // Partition Width + 0x0, // Extended Starting Address + 0x0 // Extended Ending Address + }, + { // Null-terminated table + { + NULL_TERMINATED_TYPE, + 0, + 0 + }, + } +}; + +// +// Define string Tokens for additional strings. +// +SMBIOS_PLATFORM_DXE_STRING_TOKEN_DATA (PlatformMemoryArrayMappedAddress) = { + { // Table 1 + { // Tokens array + NULL_TERMINATED_TOKEN + }, + 0 // Size of Tokens array + } +}; diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type19/PlatformMemoryArrayMappedAddressFunction.c b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type19/PlatformMemoryArrayMappedAddressFunction.c new file mode 100644 index 000000000000..c57eaef26bf5 --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type19/PlatformMemoryArrayMappedAddressFunction.c @@ -0,0 +1,150 @@ +/** @file + + Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Guid/PlatformInfoHob.h> +#include <Library/AmpereCpuLib.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> + +#include "SmbiosPlatformDxe.h" + +/** + This function adds SMBIOS Table (Type 19) records. + + @param RecordData Pointer to SMBIOS Table with default values. + @param Smbios SMBIOS protocol. + + @retval EFI_SUCCESS The SMBIOS Table was successfully added. + @retval Other Failed to update the SMBIOS Table. + +**/ +SMBIOS_PLATFORM_DXE_TABLE_FUNCTION (PlatformMemoryArrayMappedAddress) { + UINT8 Index; + UINT8 SlotIndex; + UINT8 MemRegionIndex; + UINTN HandleCount; + UINTN MemorySize; + UINT16 *HandleArray; + EFI_STATUS Status; + PLATFORM_DIMM *Dimm; + STR_TOKEN_INFO *InputStrToken; + PLATFORM_DIMM_LIST *DimmList; + PLATFORM_DRAM_INFO *DramInfo; + SMBIOS_TABLE_TYPE19 *InputData; + SMBIOS_TABLE_TYPE19 *Type19Record; + + HandleCount = 0; + HandleArray = NULL; + + GetDimmList (&DimmList); + if (DimmList == NULL) { + DEBUG (( + DEBUG_ERROR, + "[%a]:[%dL] Failed to get Dimm List\n", + __func__, + __LINE__ + )); + return EFI_NOT_FOUND; + } + + GetDramInfo (&DramInfo); + if (DramInfo == NULL) { + DEBUG (( + DEBUG_ERROR, + "[%a]:[%dL] Failed to get DRAM Information\n", + __func__, + __LINE__ + )); + return EFI_NOT_FOUND; + } + + SmbiosPlatformDxeGetLinkTypeHandle ( + EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, + &HandleArray, + &HandleCount + ); + if (HandleArray == NULL) { + return EFI_OUT_OF_RESOURCES; + } + if (HandleCount != GetNumberOfSupportedSockets ()) { + DEBUG (( + DEBUG_ERROR, + "[%a]:[%dL] Failed to get Memory Array Handle\n", + __func__, + __LINE__ + )); + FreePool (HandleArray); + return EFI_NOT_FOUND; + } + + for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) { + InputData = (SMBIOS_TABLE_TYPE19 *)RecordData; + InputStrToken = (STR_TOKEN_INFO *)StrToken; + while (InputData->Hdr.Type != NULL_TERMINATED_TYPE) { + // + // Calculate memory size + // + for (SlotIndex = 0; SlotIndex < DimmList->BoardDimmSlots; SlotIndex++) { + Dimm = &DimmList->Dimm[SlotIndex]; + if (Dimm->NodeId != Index) { + continue; + } + + if (Dimm->Info.DimmStatus == DIMM_INSTALLED_OPERATIONAL) { + MemorySize = Dimm->Info.DimmSize * 1024; + } + } + + // + // Create Table and fill up information + // + for (MemRegionIndex = 0; MemRegionIndex < DramInfo->NumRegion; MemRegionIndex++) { + SmbiosPlatformDxeCreateTable ( + (VOID *)&Type19Record, + (VOID *)&InputData, + sizeof (SMBIOS_TABLE_TYPE19), + InputStrToken + ); + if (Type19Record == NULL) { + FreePool (HandleArray); + return EFI_OUT_OF_RESOURCES; + } + + if (DramInfo->NvdRegion[MemRegionIndex] > 0 + || DramInfo->Socket[MemRegionIndex] != Index) + { + continue; + } + + Type19Record->ExtendedStartingAddress = DramInfo->Base[MemRegionIndex]; + Type19Record->ExtendedEndingAddress = DramInfo->Base[MemRegionIndex] + + DramInfo->Size[MemRegionIndex] -1; + if (MemorySize != 0) { + Type19Record->PartitionWidth = (DramInfo->Size[MemRegionIndex] - 1) / MemorySize + 1; + } + Type19Record->MemoryArrayHandle = HandleArray[Index]; + + Status = SmbiosPlatformDxeAddRecord ((UINT8 *)Type19Record, NULL); + if (EFI_ERROR (Status)) { + FreePool (HandleArray); + FreePool (Type19Record); + return Status; + } + + FreePool (Type19Record); + } + + InputData++; + InputStrToken++; + } + } + FreePool (HandleArray); + + return Status; +} diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLibCommon.c b/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLibCommon.c index 853ab5543f11..0d72853e3d5f 100644 --- a/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLibCommon.c +++ b/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLibCommon.c @@ -555,6 +555,48 @@ GetScpBuild ( } } +/** + Get information of DIMM List. + + @param[out] DimmList Pointer contains information of DIMM List. +**/ +VOID +EFIAPI +GetDimmList ( + PLATFORM_DIMM_LIST **DimmList + ) +{ + PLATFORM_INFO_HOB *PlatformHob; + + PlatformHob = GetPlatformHob (); + if (PlatformHob != NULL) { + *DimmList = &PlatformHob->DimmList; + } else { + *DimmList = NULL; + } +} + +/** + Get information of DRAM. + + @param[out] DramInfo Pointer contains information of DRAM. +**/ +VOID +EFIAPI +GetDramInfo ( + PLATFORM_DRAM_INFO **DramInfo + ) +{ + PLATFORM_INFO_HOB *PlatformHob; + + PlatformHob = GetPlatformHob (); + if (PlatformHob != NULL) { + *DramInfo = &PlatformHob->DramInfo; + } else { + *DramInfo = NULL; + } +} + /** Set the number of configured CPM per socket. diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxeStrings.uni b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxeStrings.uni index c8176e31ab45..83a76202d614 100644 --- a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxeStrings.uni +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxeStrings.uni @@ -18,4 +18,5 @@ #include "Type08/PlatformPortConnector.uni" #include "Type09/PlatformSystemSlot.uni" #include "Type11/PlatformOemString.uni" +#include "Type17/PlatformMemoryDevice.uni" #include "Type41/PlatformOnboardDevicesExtended.uni" diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type17/PlatformMemoryDevice.uni b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type17/PlatformMemoryDevice.uni new file mode 100644 index 000000000000..012bc241f78a --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/Type17/PlatformMemoryDevice.uni @@ -0,0 +1,16 @@ +/** @file + + Copyright (c) 2023, Ampere Computing LLC. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +/=# + +#string STR_PLATFORM_DXE_MEMORY_DEVICE_DEVICE_LOCATOR #language en-US "Not set" +#string STR_PLATFORM_DXE_MEMORY_DEVICE_BANK_LOCATOR #language en-US "Not set" +#string STR_PLATFORM_DXE_MEMORY_DEVICE_MANUFACTURER #language en-US "Not set" +#string STR_PLATFORM_DXE_MEMORY_DEVICE_SERIAL_NUMBER #language en-US "Not set" +#string STR_PLATFORM_DXE_MEMORY_DEVICE_ASSET_TAG #language en-US "Not set" +#string STR_PLATFORM_DXE_MEMORY_DEVICE_PART_NUMBER #language en-US "Not set" -- 2.39.0 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#105269): https://edk2.groups.io/g/devel/message/105269 Mute This Topic: https://groups.io/mt/99111900/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-