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 <minhnguyen1@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/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2024 Red Hat, Inc.