[edk2-devel] [edk2-platforms][PATCH V4 09/11] Platform/Sgi: Add SMBIOS Type17 Table

Pranav Madhu pranav.madhu at arm.com
Mon May 24 14:28:14 UTC 2021


Add the SMBIOS type 17 table (Memory Device) that includes the
specification of each installed memory device such as size of each
device, bank locator, memory device type, and other related information.

Signed-off-by: Pranav Madhu <pranav.madhu at arm.com>
Reviewed-by: Sami Mujawar <sami.mujawar at arm.com>
---
 Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf |   1 +
 Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.h   |  26 ++
 Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c   |   1 +
 Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/Type17MemoryDevice.c  | 409 ++++++++++++++++++++
 4 files changed, 437 insertions(+)

diff --git a/Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
index ebd19c1882bb..9061c491d461 100644
--- a/Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+++ b/Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
@@ -21,6 +21,7 @@
   Type4ProcessorInformation.c
   Type7CacheInformation.c
   Type16PhysicalMemoryArray.c
+  Type17MemoryDevice.c
 
 [Packages]
   ArmPkg/ArmPkg.dec
diff --git a/Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.h b/Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.h
index 95bb2c4bfc70..4e663033d515 100644
--- a/Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.h
+++ b/Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.h
@@ -122,6 +122,24 @@ InstallType16PhysicalMemoryArray (
   IN     EFI_SMBIOS_PROTOCOL    *Smbios
   );
 
+
+/**
+  Install SMBIOS memory device table.
+
+  Install the SMBIOS memory device (type 17) table for RD platforms.
+
+  @param[in] Smbios   SMBIOS protocol.
+
+  @retval EFI_SUCCESS           Record was added.
+  @retval EFI_OUT_OF_RESOURCES  Record was not added.
+  @retval EFI_ALREADY_STARTED   The SmbiosHandle passed is already in use.
+**/
+EFI_STATUS
+EFIAPI
+InstallType17MemoryDevice (
+  IN     EFI_SMBIOS_PROTOCOL    *Smbios
+  );
+
 typedef enum {
   SMBIOS_HANDLE_ENCLOSURE = 0x1000,
   SMBIOS_HANDLE_CLUSTER1,
@@ -131,6 +149,14 @@ typedef enum {
   SMBIOS_HANDLE_L3_CACHE,
   SMBIOS_HANDLE_L4_CACHE,
   SMBIOS_HANDLE_PHYSICAL_MEMORY,
+  SMBIOS_HANDLE_MEMORY_DEVICE0000,  // Chip 0 Bank 0
+  SMBIOS_HANDLE_MEMORY_DEVICE0001,  // Chip 0 Bank 1
+  SMBIOS_HANDLE_MEMORY_DEVICE0100,  // Chip 1 Bank 0
+  SMBIOS_HANDLE_MEMORY_DEVICE0101,  // Chip 1 Bank 1
+  SMBIOS_HANDLE_MEMORY_DEVICE0200,  // Chip 2 Bank 0
+  SMBIOS_HANDLE_MEMORY_DEVICE0201,  // Chip 2 Bank 1
+  SMBIOS_HANDLE_MEMORY_DEVICE0300,  // Chip 3 Bank 0
+  SMBIOS_HANDLE_MEMORY_DEVICE0301,  // Chip 3 Bank 1
 } SMBIOS_REFRENCE_HANDLES;
 
 #endif // SMBIOS_PLATFORM_DXE_H_
diff --git a/Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c b/Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c
index 4f14be165c94..4e6a6b250813 100644
--- a/Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c
+++ b/Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c
@@ -32,6 +32,7 @@ ARM_RD_SMBIOS_TABLE_INSTALL_FPTR mSmbiosTableList[] = {
   &InstallType4ProcessorInformation,
   &InstallType7CacheInformation,
   &InstallType16PhysicalMemoryArray,
+  &InstallType17MemoryDevice,
 };
 
 /**
diff --git a/Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/Type17MemoryDevice.c b/Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/Type17MemoryDevice.c
new file mode 100644
index 000000000000..b51e2b3fa1a6
--- /dev/null
+++ b/Platform/ARM/SgiPkg/Drivers/SmbiosPlatformDxe/Type17MemoryDevice.c
@@ -0,0 +1,409 @@
+/** @file
+  SMBIOS Type 17 (Memory Device) table for ARM RD platforms.
+
+  This file installs SMBIOS Type 17 (Memory Device) table for Arm's Reference
+  Design platforms. It includes the specification of each installed memory
+  device such as size of each device, bank locator, memory device type, and
+  other related information.
+
+  Copyright (c) 2021, ARM Limited. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Specification Reference:
+    - SMBIOS Reference Specification 3.4.0, Chapter 7.18
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/Smbios.h>
+
+#include "SmbiosPlatformDxe.h"
+
+#define TYPE17_STRINGS                                  \
+  "Chip 0 Bank 0\0"                                     \
+  "Chip 1 Bank 0\0"                                     \
+  "Chip 2 Bank 0\0"                                     \
+  "Chip 3 Bank 0\0"                                     \
+  "Chip 0 Bank 1\0"                                     \
+  "Chip 1 Bank 1\0"                                     \
+  "Chip 2 Bank 1\0"                                     \
+  "Chip 3 Bank 1\0"
+
+typedef enum {
+  Chip0Bank0 = 1,
+  Chip1Bank0,
+  Chip2Bank0,
+  Chip3Bank0,
+  Chip0Bank1,
+  Chip1Bank1,
+  Chip2Bank1,
+  Chip3Bank1
+} TYPE17_STRING_ELEMENTS;
+
+/* SMBIOS Type17 structure */
+#pragma pack(1)
+typedef struct {
+  SMBIOS_TABLE_TYPE17 Base;
+  CHAR8               Strings[sizeof (TYPE17_STRINGS)];
+} ARM_RD_SMBIOS_TYPE17;
+#pragma pack()
+
+/* Memory Device */
+STATIC ARM_RD_SMBIOS_TYPE17 mArmRdSmbiosType17[] = {
+  {
+    {
+      {
+        // SMBIOS header
+        EFI_SMBIOS_TYPE_MEMORY_DEVICE,  // Type 17
+        sizeof (SMBIOS_TABLE_TYPE17),   // Length
+        SMBIOS_HANDLE_MEMORY_DEVICE0000
+      },
+      SMBIOS_HANDLE_PHYSICAL_MEMORY,    // Physical memory array handle
+      0xFFFE,                           // Memory error info handle
+      0xFFFF,                           // Total width unknown
+      0xFFFF,                           // Data width unknown
+      0,                                // Size, Update dynamically
+      MemoryFormFactorOther,            // Form Factor
+      0,                                // Device set, not part of a set
+      0,                                // Device locator
+      Chip0Bank0,                       // Chip 0 Bank 0
+      MemoryTypeDram,                   // Memory type
+      {0, 1},                           // Type details others
+    },
+    // Text strings (unformatted area)
+    TYPE17_STRINGS
+  },
+  {
+    {
+      {
+        // SMBIOS header
+        EFI_SMBIOS_TYPE_MEMORY_DEVICE,  // Type 17
+        sizeof (SMBIOS_TABLE_TYPE17),   // Length
+        SMBIOS_HANDLE_MEMORY_DEVICE0001
+      },
+      SMBIOS_HANDLE_PHYSICAL_MEMORY,    // Physical memory array handle
+      0xFFFE,                           // Memory error info handle
+      0xFFFF,                           // Total width unknown
+      0xFFFF,                           // Data width unknown
+      0,                                // Size, Update dynamically
+      MemoryFormFactorOther,            // Form Factor
+      0,                                // Device set, not part of a set
+      0,                                // Device locator
+      Chip0Bank1,                       // Chip 0 Bank 1
+      MemoryTypeDram,                   // Memory type
+      {0, 1},                           // Type details others
+    },
+    // Text strings (unformatted area)
+    TYPE17_STRINGS
+  },
+  {
+    {
+      {
+        // SMBIOS header
+        EFI_SMBIOS_TYPE_MEMORY_DEVICE,  // Type 17
+        sizeof (SMBIOS_TABLE_TYPE17),   // Length
+        SMBIOS_HANDLE_MEMORY_DEVICE0100
+      },
+      SMBIOS_HANDLE_PHYSICAL_MEMORY,    // Physical memory array handle
+      0xFFFE,                           // Memory error info handle
+      0xFFFF,                           // Total width unknown
+      0xFFFF,                           // Data width unknown
+      0,                                // Size, Update dynamically
+      MemoryFormFactorOther,            // Form Factor
+      0,                                // Device set, not part of a set
+      0,                                // Device locator
+      Chip1Bank0,                       // Chip 1 Bank 0
+      MemoryTypeDram,                   // Memory type
+      {0, 1},                           // Type details others
+    },
+    // Text strings (unformatted area)
+    TYPE17_STRINGS
+  },
+  {
+    {
+      {
+        // SMBIOS header
+        EFI_SMBIOS_TYPE_MEMORY_DEVICE,  // Type 17
+        sizeof (SMBIOS_TABLE_TYPE17),   // Length
+        SMBIOS_HANDLE_MEMORY_DEVICE0101
+      },
+      SMBIOS_HANDLE_PHYSICAL_MEMORY,    // Physical memory array handle
+      0xFFFE,                           // Memory error info handle
+      0xFFFF,                           // Total width unknown
+      0xFFFF,                           // Data width unknown
+      0,                                // Size, Update dynamically
+      MemoryFormFactorOther,            // Form Factor
+      0,                                // Device set, not part of a set
+      0,                                // Device locator
+      Chip1Bank1,                       // Chip 1 Bank 1
+      MemoryTypeDram,                   // Memory type
+      {0, 1},                           // Type details others
+    },
+    // Text strings (unformatted area)
+    TYPE17_STRINGS
+  },
+  {
+    {
+      {
+        // SMBIOS header
+        EFI_SMBIOS_TYPE_MEMORY_DEVICE,  // Type 17
+        sizeof (SMBIOS_TABLE_TYPE17),   // Length
+        SMBIOS_HANDLE_MEMORY_DEVICE0200
+      },
+      SMBIOS_HANDLE_PHYSICAL_MEMORY,    // Physical memory array handle
+      0xFFFE,                           // Memory error info handle
+      0xFFFF,                           // Total width unknown
+      0xFFFF,                           // Data width unknown
+      0,                                // Size, Update dynamically
+      MemoryFormFactorOther,            // Form Factor
+      0,                                // Device set, not part of a set
+      0,                                // Device locator
+      Chip2Bank0,                       // Chip 2 Bank 0
+      MemoryTypeDram,                   // Memory type
+      {0, 1},                           // Type details others
+    },
+    // Text strings (unformatted area)
+    TYPE17_STRINGS
+  },
+  {
+    {
+      {
+        // SMBIOS header
+        EFI_SMBIOS_TYPE_MEMORY_DEVICE,  // Type 17
+        sizeof (SMBIOS_TABLE_TYPE17),   // Length
+        SMBIOS_HANDLE_MEMORY_DEVICE0201
+      },
+      SMBIOS_HANDLE_PHYSICAL_MEMORY,    // Physical memory array handle
+      0xFFFE,                           // Memory error info handle
+      0xFFFF,                           // Total width unknown
+      0xFFFF,                           // Data width unknown
+      0,                                // Size, Update dynamically
+      MemoryFormFactorOther,            // Form Factor
+      0,                                // Device set, not part of a set
+      0,                                // Device locator
+      Chip2Bank1,                       // Chip 2 Bank 1
+      MemoryTypeDram,                   // Memory type
+      {0, 1},                           // Type details others
+    },
+    // Text strings (unformatted area)
+    TYPE17_STRINGS
+  },
+  {
+    {
+      {
+        // SMBIOS header
+        EFI_SMBIOS_TYPE_MEMORY_DEVICE,  // Type 17
+        sizeof (SMBIOS_TABLE_TYPE17),   // Length
+        SMBIOS_HANDLE_MEMORY_DEVICE0300
+      },
+      SMBIOS_HANDLE_PHYSICAL_MEMORY,    // Physical memory array handle
+      0xFFFE,                           // Memory error info handle
+      0xFFFF,                           // Total width unknown
+      0xFFFF,                           // Data width unknown
+      0,                                // Size, Update dynamically
+      MemoryFormFactorOther,            // Form Factor
+      0,                                // Device set, not part of a set
+      0,                                // Device locator
+      Chip3Bank0,                       // Chip 3 Bank 0
+      MemoryTypeDram,                   // Memory type
+      {0, 1},                           // Type details others
+    },
+    // Text strings (unformatted area)
+    TYPE17_STRINGS
+  },
+  {
+    {
+      {
+        // SMBIOS header
+        EFI_SMBIOS_TYPE_MEMORY_DEVICE,  // Type 17
+        sizeof (SMBIOS_TABLE_TYPE17),   // Length
+        SMBIOS_HANDLE_MEMORY_DEVICE0301
+      },
+      SMBIOS_HANDLE_PHYSICAL_MEMORY,    // Physical memory array handle
+      0xFFFE,                           // Memory error info handle
+      0xFFFF,                           // Total width unknown
+      0xFFFF,                           // Data width unknown
+      0,                                // Size, Update dynamically
+      MemoryFormFactorOther,            // Form Factor
+      0,                                // Device set, not part of a set
+      0,                                // Device locator
+      Chip3Bank1,                       // Chip 3 Bank 1
+      MemoryTypeDram,                   // Memory type
+      {0, 1},                           // Type details others
+    },
+    // Text strings (unformatted area)
+    TYPE17_STRINGS
+  },
+};
+
+/** Update the memory size fields in SMBIOS Memory Device (Type 17) table.
+
+  @param  [in]  Type17Table  Pointer to the Type 17 table.
+  @param  [in]  MemorySize   Memory size available on the platform.
+                             - If no memory device is installed, this value
+                               is 0.
+                             - If size is unknown, this value is MAX_UINT64.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER Invalid Type 17 Table pointer.
+**/
+STATIC
+UINTN
+UpdateMemorySize (
+  IN  SMBIOS_TABLE_TYPE17   *Type17Table,
+  IN  UINT64                MemorySize
+  )
+{
+  if (Type17Table == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  /* Ref: SMBIOS Specifiation, Version 3.4.0, Document Identifier: DSP0134,
+     Table 75 – Memory Device (Type 17) structure, description for Size field.
+     If the value is 0, no memory device is installed in the socket; if
+     the size is unknown, the field value is FFFFh.
+  */
+  if (MemorySize == 0) {
+    Type17Table->Size = 0;
+    Type17Table->ExtendedSize = 0;
+    return EFI_SUCCESS;
+  }
+
+  if (MemorySize == MAX_UINT64) {
+    Type17Table->Size = MAX_UINT16;
+    Type17Table->ExtendedSize = 0;
+    return EFI_SUCCESS;
+  }
+
+  /* Ref: SMBIOS Specifiation, Version 3.4.0, Document Identifier: DSP0134,
+     Table 75 – Memory Device (Type 17) structure, description for Size field.
+     If the size is 32 GB-1 MB or greater, the field value is 7FFFh and the
+     actual size is stored in the Extended Size field.
+  */
+  if (MemorySize < (SIZE_32GB - SIZE_1MB)) {
+    /* Ref: SMBIOS Specifiation, Version 3.4.0, Document Identifier: DSP0134,
+       section 7.18.5 Memory Device — Extended Size
+       For compatibility with older SMBIOS parsers, memory devices
+       smaller than (32 GB - 1 MB) should be represented using their
+       size in the Size field, leaving the Extended Size field set to 0.
+    */
+    Type17Table->ExtendedSize = 0;
+
+    /* Ref: SMBIOS Specifiation, Version 3.4.0, Document Identifier: DSP0134,
+       Table 75 – Memory Device (Type 17) structure, description for Size field.
+       The granularity in which the value is specified depends on the setting
+       of the most-significant bit (bit 15). If the bit is 0, the value is
+       specified in megabyte units; if the bit is 1, the value is specified
+       in kilobyte units.
+       For example, the value 8100h identifies a 256 KB memory device
+       and 0100h identifies a 256 MB memory device.
+    */
+    if (MemorySize < SIZE_1MB) {
+      Type17Table->Size = MemorySize >> 10;
+      Type17Table->Size |= BIT15;
+    } else {
+      Type17Table->Size = MemorySize >> 20;
+    }
+    return EFI_SUCCESS;
+  }
+
+  /* Ref: SMBIOS Specifiation, Version 3.4.0, Document Identifier: DSP0134,
+      section 7.18.5 Memory Device — Extended Size
+      The Extended Size field is intended to represent memory devices
+      larger than 32,767 MB (32 GB - 1 MB), which cannot be described
+      using the Size field. This field is only meaningful if the value
+      in the Size field is 7FFFh.
+  */
+  Type17Table->Size = 0x7FFF;
+
+  /* Ref: SMBIOS Specifiation, Version 3.4.0, Document Identifier: DSP0134,
+     section 7.18.5 Memory Device — Extended Size
+     Bit 31 is reserved for future use and must be set to 0.
+     Bits 30:0 represent the size of the memory device in megabytes.
+     EXAMPLE: 0000_8000h indicates a 32 GB memory device (32,768 MB),
+              0002_0000h represents a 128 GB memory device (131,072 MB), and
+              0000_7FFFh represents a 32,767 MB (32 GB – 1 MB) device.
+  */
+  Type17Table->ExtendedSize = (MemorySize >> 20) & (~BIT31);
+  return EFI_SUCCESS;
+}
+
+/**
+  Install SMBIOS memory device Table.
+
+  Install the SMBIOS memory device (type 17) table for RD platforms.
+
+  @param[in] Smbios   SMBIOS protocol.
+
+  @retval EFI_SUCCESS           Record was added.
+  @retval EFI_OUT_OF_RESOURCES  Record was not added.
+  @retval EFI_ALREADY_STARTED   The SmbiosHandle passed is already in use.
+**/
+EFI_STATUS
+InstallType17MemoryDevice (
+  IN     EFI_SMBIOS_PROTOCOL    *Smbios
+  )
+{
+  EFI_STATUS Status;
+  EFI_SMBIOS_HANDLE SmbiosHandle;
+  UINT8  Idx;
+
+  /* Get system memory information */
+  for (Idx = 0; Idx < (FixedPcdGet32 (PcdChipCount) * 2); Idx += 2) {
+    Status = UpdateMemorySize (
+               &mArmRdSmbiosType17[Idx].Base,
+               PcdGet64 (PcdSystemMemorySize) + SIZE_16MB
+             );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "SMBIOS: Failed to update DRAM size for chip%d.\n",
+        Idx / 2
+      ));
+    } else {
+      mArmRdSmbiosType17[Idx].Base.MemoryTechnology = MemoryTechnologyDram;
+      mArmRdSmbiosType17[Idx].Base.MemoryOperatingModeCapability.Bits.
+        VolatileMemory = 1;
+    }
+
+    if (PcdGet64 (PcdDramBlock2Size) != 0) {
+      Status = UpdateMemorySize (
+                 &mArmRdSmbiosType17[Idx + 1].Base,
+                 PcdGet64 (PcdDramBlock2Size)
+               );
+      if (EFI_ERROR (Status)) {
+        DEBUG ((
+          DEBUG_ERROR,
+          "SMBIOS: Failed to update DRAM block 2 size for chip%d.\n",
+          Idx / 2
+        ));
+      } else {
+        mArmRdSmbiosType17[Idx + 1].Base.MemoryTechnology =
+          MemoryTechnologyDram;
+        mArmRdSmbiosType17[Idx + 1].Base.MemoryOperatingModeCapability.Bits.
+          VolatileMemory = 1;
+      }
+    }
+  }
+
+  /* Install valid entries */
+  for (Idx = 0; Idx < (FixedPcdGet32 (PcdChipCount) * 2); Idx++) {
+    SmbiosHandle =
+      ((EFI_SMBIOS_TABLE_HEADER *)&mArmRdSmbiosType17[Idx])->Handle;
+    Status = Smbios->Add (
+                       Smbios,
+                       NULL,
+                       &SmbiosHandle,
+                       (EFI_SMBIOS_TABLE_HEADER *)&mArmRdSmbiosType17[Idx]
+                       );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "SMBIOS: Failed to install Type17 SMBIOS table.\n"
+        ));
+      break;
+    }
+  }
+
+  return Status;
+}
-- 
2.17.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#75531): https://edk2.groups.io/g/devel/message/75531
Mute This Topic: https://groups.io/mt/83052329/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-






More information about the edk2-devel-archive mailing list