[edk2-devel] [edk2-platforms][PATCH 06/14] ManageabilityPkg: Add PldmSmbiosTransferDxe driver

Chang, Abner via groups.io abner.chang=amd.com at groups.io
Mon Apr 3 15:04:51 UTC 2023


From: abnchang <abnchang at amd.com>

Add edk2 driver that supports PLDM SMBIOS Transfer
Specification.
https://www.dmtf.org/sites/default/files/standards/documents/DSP0246_1.0.1.pdf

We currently only support "Push" mode of PLDM SMBIOS
transfer. That says only BIOS to BMC direction is
supported.
The functionality is verified by checking the binary
debug output of payload.

Signed-off-by: Abner Chang <abner.chang at amd.com>
Cc: Isaac Oram <isaac.w.oram at intel.com>
Cc: Abdul Lateef Attar <abdattar at amd.com>
Cc: Nickle Wang <nicklew at nvidia.com>
Cc: Igor Kulchytskyy <igork at ami.com>
---
 .../ManageabilityPkg/ManageabilityPkg.dec     |   1 +
 .../Include/Dsc/Manageability.dsc             |   1 +
 .../PldmSmbiosTransferDxe.inf                 |  47 ++
 .../Protocol/PldmSmbiosTransferProtocol.h     | 184 +++++++
 .../PldmSmbiosTransferDxe.c                   | 518 ++++++++++++++++++
 5 files changed, 751 insertions(+)
 create mode 100644 Features/ManageabilityPkg/Universal/PldmSmbiosTransferDxe/PldmSmbiosTransferDxe.inf
 create mode 100644 Features/ManageabilityPkg/Include/Protocol/PldmSmbiosTransferProtocol.h
 create mode 100644 Features/ManageabilityPkg/Universal/PldmSmbiosTransferDxe/PldmSmbiosTransferDxe.c

diff --git a/Features/ManageabilityPkg/ManageabilityPkg.dec b/Features/ManageabilityPkg/ManageabilityPkg.dec
index 1e9245c8dc..309faa8c98 100644
--- a/Features/ManageabilityPkg/ManageabilityPkg.dec
+++ b/Features/ManageabilityPkg/ManageabilityPkg.dec
@@ -51,3 +51,4 @@
 
 [Protocols]
   gEdkiiPldmProtocolGuid                = { 0x60997616, 0xDB70, 0x4B5F, { 0x86, 0xA4, 0x09, 0x58, 0xA3, 0x71, 0x47, 0xB4 } }
+  gEdkiiPldmSmbiosTransferProtocolGuid  = { 0xFA431C3C, 0x816B, 0x4B32, { 0xA3, 0xE0, 0xAD, 0x9B, 0x7F, 0x64, 0x27, 0x2E } }
diff --git a/Features/ManageabilityPkg/Include/Dsc/Manageability.dsc b/Features/ManageabilityPkg/Include/Dsc/Manageability.dsc
index 59549eb39a..a5a4fd6615 100644
--- a/Features/ManageabilityPkg/Include/Dsc/Manageability.dsc
+++ b/Features/ManageabilityPkg/Include/Dsc/Manageability.dsc
@@ -25,4 +25,5 @@
 [Components.X64]
   ManageabilityPkg/Universal/IpmiProtocol/Dxe/IpmiProtocolDxe.inf
   ManageabilityPkg/Universal/IpmiProtocol/Smm/IpmiProtocolSmm.inf
+  ManageabilityPkg/Universal/PldmSmbiosTransferDxe/PldmSmbiosTransferDxe.inf
 
diff --git a/Features/ManageabilityPkg/Universal/PldmSmbiosTransferDxe/PldmSmbiosTransferDxe.inf b/Features/ManageabilityPkg/Universal/PldmSmbiosTransferDxe/PldmSmbiosTransferDxe.inf
new file mode 100644
index 0000000000..da49057982
--- /dev/null
+++ b/Features/ManageabilityPkg/Universal/PldmSmbiosTransferDxe/PldmSmbiosTransferDxe.inf
@@ -0,0 +1,47 @@
+## @file
+# PLDM SMBIOS Transfer DXE Driver.
+#
+# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001d
+  BASE_NAME                      = PldmSmbiosTransferDxe
+  FILE_GUID                      = 71BF5CF0-CE09-4C7C-912B-944BF4E4CBC0
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = DxePldmSmbiosTransferEntry
+  UNLOAD_IMAGE                   = PldmSmbiosTransferUnloadImage
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+  PldmSmbiosTransferDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ManageabilityPkg/ManageabilityPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  ManageabilityTransportLib
+  ManageabilityTransportHelperLib
+  PldmProtocolLib
+  UefiLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+
+[Guids]
+  gEfiSmbios3TableGuid
+
+[Protocols]
+  gEfiSmbiosProtocolGuid
+  gEdkiiPldmSmbiosTransferProtocolGuid
+
+[Depex]
+  gEdkiiPldmProtocolGuid  ## ALWAYS_CONSUMES
diff --git a/Features/ManageabilityPkg/Include/Protocol/PldmSmbiosTransferProtocol.h b/Features/ManageabilityPkg/Include/Protocol/PldmSmbiosTransferProtocol.h
new file mode 100644
index 0000000000..7903e12726
--- /dev/null
+++ b/Features/ManageabilityPkg/Include/Protocol/PldmSmbiosTransferProtocol.h
@@ -0,0 +1,184 @@
+/** @file
+  Protocol of EDKII PLDM SMBIOS Transfer Protocol.
+
+  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_H_
+#define EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_H_
+
+#include <IndustryStandard/Pldm.h>
+
+typedef struct  _EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL;
+
+#define EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_GUID \
+  { \
+    0xFA431C3C, 0x816B, 0x4B32, 0xA3, 0xE0, 0xAD, 0x9B, 0x7F, 0x64, 0x27, 0x2E \
+  }
+
+#define EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_VERSION_MAJOR  1
+#define EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_VERSION_MINOR  0
+#define EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_VERSION        ((EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_VERSION_MAJOR << 8) |\
+                                                       EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_VERSION_MINOR)
+
+/**
+  This function gets SMBIOS table metadata.
+
+  @param [in]   This         EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL instance.
+  @param [out]  Buffer       Buffer to receive the SMBIOS table metadata.
+
+  @retval       EFI_SUCCESS            Get SMBIOS table metadata Successfully.
+  @retval       EFI_UNSUPPORTED        The function is unsupported by this
+                                       driver instance.
+  @retval       Other values           Fail to get SMBIOS table metadata.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PLDM_GET_SMBIOS_STRUCTURE_TABLE_METADATA)(
+  IN  EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL   *This,
+  OUT PLDM_SMBIOS_STRUCTURE_TABLE_METADATA  *Buffer
+  );
+
+/**
+  This function sets SMBIOS table metadata.
+
+  @param [in]   This         EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL instance.
+  @param [in]   Buffer       Pointer to SMBIOS table metadata.
+
+  @retval       EFI_SUCCESS            Set SMBIOS table metadata Successfully.
+  @retval       EFI_UNSUPPORTED        The function is unsupported by this
+                                       driver instance.
+  @retval       Other values           Fail to set SMBIOS table metadata.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PLDM_SET_SMBIOS_STRUCTURE_TABLE_METADATA)(
+  IN  EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL   *This,
+  IN  PLDM_SMBIOS_STRUCTURE_TABLE_METADATA  *Buffer
+  );
+
+/**
+  This function gets SMBIOS structure table.
+
+  @param [in]   This        EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL instance.
+  @param [out]  Buffer      Pointer to the returned SMBIOS structure table.
+                            Caller has to free this memory block when it
+                            is no longer needed.
+  @param [out]  BufferSize  Size of the returned message payload in buffer.
+
+  @retval       EFI_SUCCESS            Gets SMBIOS structure table successfully.
+  @retval       EFI_UNSUPPORTED        The function is unsupported by this
+                                       driver instance.
+  @retval       Other values           Fail to get SMBIOS structure table.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PLDM_GET_SMBIOS_STRUCTURE_TABLE)(
+  IN   EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL   *This,
+  OUT  UINT8                                 **Buffer,
+  OUT  UINT32                                *BufferSize
+  );
+
+/**
+  This function sets SMBIOS structure table.
+
+  @param [in]   This        EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL instance.
+
+  @retval      EFI_SUCCESS            Successful
+  @retval      EFI_UNSUPPORTED        The function is unsupported by this
+                                      driver instance.
+  @retval      Other values           Fail to set SMBIOS structure table.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PLDM_SET_SMBIOS_STRUCTURE_TABLE)(
+  IN   EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL  *This
+  );
+
+/**
+  This function gets particular type of SMBIOS structure.
+
+  @param [in]   This                 EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL instance.
+  @param [in]   TypeId               The type of SMBIOS structure.
+  @param [in]   StructureInstanceId  The instance ID of particular type of SMBIOS structure.
+  @param [out]  Buffer               Pointer to the returned SMBIOS structure.
+                                     Caller has to free this memory block when it
+                                     is no longer needed.
+  @param [out]  BufferSize           Size of the returned message payload in buffer.
+
+  @retval      EFI_SUCCESS           Gets particular type of SMBIOS structure successfully.
+  @retval      EFI_UNSUPPORTED       The function is unsupported by this
+                                     driver instance.
+  @retval      Other values          Fail to set SMBIOS structure table.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PLDM_GET_SMBIOS_STRUCTURE_BY_TYPE)(
+  IN   EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL  *This,
+  IN   UINT8                                TypeId,
+  IN   UINT16                               StructureInstanceId,
+  OUT  UINT8                                **Buffer,
+  OUT  UINT32                               *BufferSize
+  );
+
+/**
+  This function gets particular handle of SMBIOS structure.
+
+  @param [in]   This                 EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL instance.
+  @param [in]   Handle               The handle of SMBIOS structure.
+  @param [out]  Buffer               Pointer to the returned SMBIOS structure.
+                                     Caller has to free this memory block when it
+                                     is no longer needed.
+  @param [out]  BufferSize           Size of the returned message payload in buffer.
+
+  @retval      EFI_SUCCESS           Gets particular handle of SMBIOS structure successfully.
+  @retval      EFI_UNSUPPORTED       The function is unsupported by this
+                                     driver instance.
+  @retval      Other values          Fail to set SMBIOS structure table.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PLDM_GET_SMBIOS_STRUCTURE_BY_HANDLE)(
+  IN   EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL  *This,
+  IN   UINT16                               Handle,
+  OUT  UINT8                                **Buffer,
+  OUT  UINT32                               *BufferSize
+  );
+
+//
+// EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL
+//
+typedef struct {
+  PLDM_GET_SMBIOS_STRUCTURE_TABLE_METADATA    GetSmbiosStructureTableMetaData;
+  PLDM_SET_SMBIOS_STRUCTURE_TABLE_METADATA    SetSmbiosStructureTableMetaData;
+  PLDM_GET_SMBIOS_STRUCTURE_TABLE             GetSmbiosStructureTable;
+  PLDM_SET_SMBIOS_STRUCTURE_TABLE             SetSmbiosStructureTable;
+  PLDM_GET_SMBIOS_STRUCTURE_BY_TYPE           GetSmbiosStructureByType;
+  PLDM_GET_SMBIOS_STRUCTURE_BY_HANDLE         GetSmbiosStructureByHandle;
+} EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_V1_0;
+
+///
+/// Definitions of EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL.
+/// This is a union that can accommodate the new functionalities defined
+/// in PLDM SMBIOS Transfer specification in the future.
+/// The new added function must has its own EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL
+/// structure with the incremental version number.
+///   e.g., EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_V1_1.
+///
+/// The new function must be added base on the last version of
+/// EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL to keep the backward compatibility.
+///
+typedef union {
+  EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_V1_0    *Version1_0;
+} EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_FUNCTION;
+
+struct _EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL {
+  UINT16                                          ProtocolVersion;
+  EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_FUNCTION    Functions;
+};
+
+extern EFI_GUID  gEdkiiPldmSmbiosTransferProtocolGuid;
+
+#endif // EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_H_
diff --git a/Features/ManageabilityPkg/Universal/PldmSmbiosTransferDxe/PldmSmbiosTransferDxe.c b/Features/ManageabilityPkg/Universal/PldmSmbiosTransferDxe/PldmSmbiosTransferDxe.c
new file mode 100644
index 0000000000..5f1b1028f3
--- /dev/null
+++ b/Features/ManageabilityPkg/Universal/PldmSmbiosTransferDxe/PldmSmbiosTransferDxe.c
@@ -0,0 +1,518 @@
+/** @file
+  This file provides edk2 PLDM SMBIOS Transfer Protocol implementation.
+
+  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Revision Reference:
+   Platform Level Data Model (PLDM) for SMBIOS Data Transfer Specification
+   Version 1.0.1
+   https://www.dmtf.org/sites/default/files/standards/documents/DSP0246_1.0.1.pdf
+**/
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BasePldmProtocolLib.h>
+#include <Library/ManageabilityTransportHelperLib.h>
+#include <IndustryStandard/PldmSmbiosTransfer.h>
+#include <IndustryStandard/SmBios.h>
+#include <Protocol/PldmSmbiosTransferProtocol.h>
+#include <Protocol/Smbios.h>
+
+UINT32  SetSmbiosStructureTableHandle;
+
+/**
+  Get the full size of SMBIOS structure including optional strings that follow the formatted structure.
+
+  @param Head                   Pointer to the beginning of SMBIOS structure.
+  @param NumberOfStrings        The returned number of optional strings that follow the formatted structure.
+
+  @return Size                  The returned size.
+**/
+UINTN
+GetSmbiosStructureSize (
+  IN   EFI_SMBIOS_TABLE_HEADER  *Head,
+  OUT  UINTN                    *NumberOfStrings
+  )
+{
+  UINTN  Size;
+  UINTN  StrLen;
+  CHAR8  *CharInStr;
+  UINTN  StringsNumber;
+
+  CharInStr     = (CHAR8 *)Head + Head->Length;
+  Size          = Head->Length;
+  StringsNumber = 0;
+  StrLen        = 0;
+  //
+  // look for the two consecutive zeros, check the string limit by the way.
+  //
+  while (*CharInStr != 0 || *(CharInStr+1) != 0) {
+    if (*CharInStr == 0) {
+      Size += 1;
+      CharInStr++;
+    }
+
+    for (StrLen = 0; StrLen < SMBIOS_STRING_MAX_LENGTH; StrLen++) {
+      if (*(CharInStr+StrLen) == 0) {
+        break;
+      }
+    }
+
+    if (StrLen == SMBIOS_STRING_MAX_LENGTH) {
+      return 0;
+    }
+
+    //
+    // forward the pointer
+    //
+    CharInStr     += StrLen;
+    Size          += StrLen;
+    StringsNumber += 1;
+  }
+
+  //
+  // count ending two zeros.
+  //
+  Size += 2;
+
+  if (NumberOfStrings != NULL) {
+    *NumberOfStrings = StringsNumber;
+  }
+
+  return Size;
+}
+
+/**
+
+  This function returns full SMBIOS table length.
+
+  @param  TableAddress      SMBIOS table based address
+  @param  TableMaximumSize  Maximum size of SMBIOS table
+
+  @return SMBIOS table length
+
+**/
+UINTN
+GetSmbiosTableLength (
+  IN VOID   *TableAddress,
+  IN UINTN  TableMaximumSize
+  )
+{
+  VOID   *TableEntry;
+  VOID   *TableAddressEnd;
+  UINTN  TableEntryLength;
+
+  TableAddressEnd = (VOID *)((UINTN)TableAddress + TableMaximumSize);
+  TableEntry      = TableAddress;
+  while (TableEntry < TableAddressEnd) {
+    TableEntryLength = GetSmbiosStructureSize (TableEntry, NULL);
+    if (TableEntryLength == 0) {
+      break;
+    }
+
+    if (((SMBIOS_STRUCTURE *)TableEntry)->Type == 127) {
+      TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);
+      break;
+    }
+
+    TableEntry = (VOID *)((UINTN)TableEntry + TableEntryLength);
+  }
+
+  return ((UINTN)TableEntry - (UINTN)TableAddress);
+}
+
+/**
+  This function gets SMBIOS table metadata.
+
+  @param [in]   This         EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL instance.
+  @param [out]  Buffer       Buffer to receive the SMBIOS table metadata.
+
+  @retval       EFI_SUCCESS            Get SMBIOS table metadata Successfully.
+  @retval       EFI_UNSUPPORTED        The function is unsupported by this
+                                       driver instance.
+  @retval       Other values           Fail to get SMBIOS table metadata.
+**/
+EFI_STATUS
+EFIAPI
+GetSmbiosStructureTableMetaData (
+  IN  EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL   *This,
+  OUT PLDM_SMBIOS_STRUCTURE_TABLE_METADATA  *Buffer
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      ResponseSize;
+
+  DEBUG((DEBUG_INFO, "%a: Set SMBIOS structure table metafile.\n", __FUNCTION__));
+
+  ResponseSize = sizeof (PLDM_SMBIOS_STRUCTURE_TABLE_METADATA);
+  Status       = PldmSubmitCommand (
+                   PLDM_TYPE_SMBIOS,
+                   PLDM_GET_SMBIOS_STRUCTURE_TABLE_METADATA_COMMAND_CODE,
+                   NULL,
+                   0,
+                   (UINT8 *)Buffer,
+                   &ResponseSize
+                   );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Fails to get SMBIOS structure table metafile.\n", __FUNCTION__));
+  }
+  if (ResponseSize != 0) {
+    HelperManageabilityDebugPrint(
+     (VOID *)Buffer,
+     ResponseSize,
+     "SMBIOS structure table metafile got from BMC.\n"
+     );
+  }
+  return Status;
+}
+
+/**
+  This function sets SMBIOS table metadata.
+
+  @param [in]   This         EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL instance.
+
+  @retval       EFI_SUCCESS            Set SMBIOS table metadata Successfully.
+  @retval       EFI_UNSUPPORTED        The function is unsupported by this
+                                       driver instance.
+  @retval       Other values           Fail to set SMBIOS table metadata.
+**/
+EFI_STATUS
+EFIAPI
+SetSmbiosStructureTableMetaData (
+  IN  EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL   *This,
+  IN  PLDM_SMBIOS_STRUCTURE_TABLE_METADATA  *Buffer
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      ResponseSize;
+  UINT32      RequestSize;
+
+  DEBUG((DEBUG_INFO, "%a: Get SMBIOS structure table metafile.\n", __FUNCTION__));
+
+  RequestSize   = sizeof(PLDM_SMBIOS_STRUCTURE_TABLE_METADATA);
+  ResponseSize  = 0;
+
+  Status = PldmSubmitCommand (
+             PLDM_TYPE_SMBIOS,
+             PLDM_SET_SMBIOS_STRUCTURE_TABLE_METADATA_COMMAND_CODE,
+             (UINT8 *)Buffer,
+             RequestSize,
+             (UINT8 *)NULL,
+             &ResponseSize
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Fails to set SMBIOS structure table metafile.\n", __FUNCTION__));
+  }
+
+  return Status;
+}
+
+/**
+  This function gets SMBIOS structure table.
+
+  @param [in]   This        EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL instance.
+  @param [out]  Buffer      Pointer to the returned SMBIOS structure table.
+                            Caller has to free this memory block when it
+                            is no longer needed.
+  @param [out]  BufferSize  Size of the returned message payload in buffer.
+
+  @retval       EFI_SUCCESS            Gets SMBIOS structure table successfully.
+  @retval       EFI_UNSUPPORTED        The function is unsupported by this
+                                       driver instance.
+  @retval       Other values           Fail to get SMBIOS structure table.
+**/
+EFI_STATUS
+EFIAPI
+GetSmbiosStructureTable (
+  IN   EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL  *This,
+  OUT  UINT8                                **Buffer,
+  OUT  UINT32                               *BufferSize
+  )
+{
+  DEBUG ((DEBUG_INFO, "%a: Unsupported.\n", __FUNCTION__));
+  // Only support PLDM SMBIOS Transfer push mode.
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  This function sets SMBIOS structure table.
+
+  @param [in]   This        EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL instance.
+
+  @retval      EFI_SUCCESS            Successful
+  @retval      EFI_NOT_FOUND          No SMBIOS record found on system.
+  @retval      EFI_UNSUPPORTED        The function is unsupported by this
+                                      driver instance.
+  @retval      Other values           Fail to set SMBIOS structure table.
+**/
+EFI_STATUS
+EFIAPI
+SetSmbiosStructureTable (
+  IN  EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL  *This
+  )
+{
+  EFI_STATUS                               Status;
+  SMBIOS_TABLE_3_0_ENTRY_POINT             *SmbiosEntry;
+  EFI_SMBIOS_HANDLE                        SmbiosHandle;
+  EFI_SMBIOS_PROTOCOL                      *Smbios;
+  UINT32                                   PaddingSize;
+  UINT32                                   ResponseSize;
+  UINT32                                   RequestSize;
+  UINT8                                    *RequestBuffer;
+  UINT8                                    *DataPointer;
+  UINT32                                   Crc32;
+  UINT16                                   TableLength;
+  EFI_SMBIOS_TABLE_HEADER                  *Record;
+  PLDM_SET_SMBIOS_STRUCTURE_TABLE_REQUEST  *PldmSetSmbiosStructureTable;
+
+  DEBUG((DEBUG_INFO, "%a: Set SMBIOS structure table.\n", __FUNCTION__));
+
+  Status = gBS->LocateProtocol (
+                  &gEfiSmbiosProtocolGuid,
+                  NULL,
+                  (VOID **)&Smbios
+                  );
+  if (EFI_ERROR(Status)) {
+    DEBUG((DEBUG_ERROR, "%a: No Efi SMBIOS Protocol installed.\n"));
+    return EFI_UNSUPPORTED;
+  }
+  if (Smbios->MajorVersion < 3) {
+    DEBUG((DEBUG_ERROR, "%a: We don't support SMBIOS spec version earlier than v3.0.\n"));
+    return EFI_UNSUPPORTED;
+  }
+  Status = EfiGetSystemConfigurationTable (
+             &gEfiSmbios3TableGuid,
+             (VOID **)&SmbiosEntry
+             );
+  if (Status != EFI_SUCCESS) {
+    DEBUG ((DEBUG_ERROR, "%a: Failed to get system configuration table.\n"));
+    return Status;
+  }
+
+  //
+  // Print out SMBIOS table information.
+  DEBUG ((DEBUG_INFO, "PldmSetSmbiosStructureTable SmbiosTable:\n"));
+  DEBUG ((
+    DEBUG_INFO,
+    "AnchorString                ------ '%c%c%c%c%c'\n",
+    SmbiosEntry->AnchorString[0],
+    SmbiosEntry->AnchorString[1],
+    SmbiosEntry->AnchorString[2],
+    SmbiosEntry->AnchorString[3],
+    SmbiosEntry->AnchorString[4]
+    ));
+
+  DEBUG((DEBUG_INFO, "EntryPointStructureChecksum ------ 0x%02x\n", SmbiosEntry->EntryPointStructureChecksum));
+  DEBUG((DEBUG_INFO, "EntryPointLength            ------ 0x%02x\n", SmbiosEntry->EntryPointLength));
+  DEBUG((DEBUG_INFO, "MajorVersion                ------ 0x%02x\n", SmbiosEntry->MajorVersion));
+  DEBUG((DEBUG_INFO, "MinorVersion                ------ 0x%02x\n", SmbiosEntry->MinorVersion));
+  DEBUG((DEBUG_INFO, "DocRev                      ------ 0x%02x\n", SmbiosEntry->DocRev));
+  DEBUG((DEBUG_INFO, "MaxStructureSize            ------ 0x%08x\n", SmbiosEntry->TableMaximumSize));
+  DEBUG((DEBUG_INFO, "EntryPointRevision               - 0x%02x\n", SmbiosEntry->EntryPointRevision));
+  DEBUG((DEBUG_INFO, "TableMaximumSize                 - 0x%08x\n", SmbiosEntry->TableMaximumSize));
+  DEBUG((DEBUG_INFO, "TableAddress                     - 0x%016lx\n", SmbiosEntry->TableAddress));
+
+  SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  do {
+    Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
+    if (EFI_ERROR(Status)) {
+      break;
+    }
+    DEBUG((DEBUG_INFO, "  SMBIOS type %d to BMC\n", Record->Type));
+  } while(Status == EFI_SUCCESS);
+
+  TableLength = GetSmbiosTableLength ((VOID *)(UINTN)SmbiosEntry->TableAddress, SmbiosEntry->TableMaximumSize);
+
+  // Padding requirement (0 ~ 3 bytes)
+  PaddingSize = (4 - (TableLength % 4)) % 4;
+
+  // Total request buffer size = PLDM_SET_SMBIOS_STRUCTURE_TABLE_REQUEST + SMBIOS tables + padding + checksum
+  RequestSize = (UINT32)(sizeof(PLDM_SET_SMBIOS_STRUCTURE_TABLE_REQUEST) + TableLength + PaddingSize + sizeof(Crc32));
+  RequestBuffer = (UINT8 *)AllocatePool (RequestSize);
+  if (RequestBuffer == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: No memory resource for sending SetSmbiosStructureTable.\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  // Fill in smbios tables
+  CopyMem (
+    (VOID *)((UINT8 *)RequestBuffer + sizeof(PLDM_SET_SMBIOS_STRUCTURE_TABLE_REQUEST)),
+    (VOID *)(UINTN) SmbiosEntry->TableAddress,
+    TableLength
+    );
+
+  // Fill in padding
+  DataPointer = RequestBuffer + sizeof(PLDM_SET_SMBIOS_STRUCTURE_TABLE_REQUEST) + TableLength;
+  ZeroMem ((VOID *)DataPointer, PaddingSize);
+
+  // Fill in checksum
+  gBS->CalculateCrc32 (
+         (VOID *)(RequestBuffer + sizeof(PLDM_SET_SMBIOS_STRUCTURE_TABLE_REQUEST)),
+         TableLength + PaddingSize,
+         &Crc32
+         );
+  DataPointer += PaddingSize;
+  CopyMem ((VOID *)DataPointer, (VOID *)&Crc32, 4);
+
+  PldmSetSmbiosStructureTable                     = (PLDM_SET_SMBIOS_STRUCTURE_TABLE_REQUEST *)RequestBuffer;
+  PldmSetSmbiosStructureTable->DataTransferHandle = SetSmbiosStructureTableHandle;
+  PldmSetSmbiosStructureTable->TransferFlag       = PLDM_TRANSFER_FLAG_START_AND_END;
+  ResponseSize                                    = sizeof (SetSmbiosStructureTableHandle);
+
+  Status = PldmSubmitCommand (
+             PLDM_TYPE_SMBIOS,
+             PLDM_SET_SMBIOS_STRUCTURE_TABLE_COMMAND_CODE,
+             RequestBuffer,
+             RequestSize,
+             (UINT8 *)&SetSmbiosStructureTableHandle,
+             &ResponseSize
+             );
+  if (RequestBuffer != NULL) {
+    FreePool (RequestBuffer);
+  }
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Set SMBIOS structure table.\n", __FUNCTION__));
+  }
+  if (ResponseSize != 0 && ResponseSize <= sizeof(SetSmbiosStructureTableHandle)) {
+    HelperManageabilityDebugPrint(
+     (VOID *)&SetSmbiosStructureTableHandle,
+     ResponseSize,
+     "Set SMBIOS structure table response got from BMC.\n"
+     );
+  }
+  return Status;
+}
+
+/**
+  This function gets particular type of SMBIOS structure.
+
+  @param [in]   This                 EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL instance.
+  @param [in]   TypeId               The type of SMBIOS structure.
+  @param [in]   StructureInstanceId  The instance ID of particular type of SMBIOS structure.
+  @param [out]  Buffer               Pointer to the returned SMBIOS structure.
+                                     Caller has to free this memory block when it
+                                     is no longer needed.
+  @param [out]  BufferSize           Size of the returned message payload in buffer.
+
+  @retval      EFI_SUCCESS           Gets particular type of SMBIOS structure successfully.
+  @retval      EFI_UNSUPPORTED       The function is unsupported by this
+                                     driver instance.
+  @retval      Other values          Fail to set SMBIOS structure table.
+**/
+EFI_STATUS
+EFIAPI
+GetSmbiosStructureByType (
+  IN   EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL  *This,
+  IN   UINT8                                TypeId,
+  IN   UINT16                               StructureInstanceId,
+  OUT  UINT8                                **Buffer,
+  OUT  UINT32                               *BufferSize
+  )
+{
+  DEBUG ((DEBUG_INFO, "%a: Unsupported.\n", __FUNCTION__));
+  // Only support PLDM SMBIOS Transfer push mode.
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  This function gets particular handle of SMBIOS structure.
+
+  @param [in]   This                 EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL instance.
+  @param [in]   Handle               The handle of SMBIOS structure.
+  @param [out]  Buffer               Pointer to the returned SMBIOS structure.
+                                     Caller has to free this memory block when it
+                                     is no longer needed.
+  @param [out]  BufferSize           Size of the returned message payload in buffer.
+
+  @retval      EFI_SUCCESS           Gets particular handle of SMBIOS structure successfully.
+  @retval      EFI_UNSUPPORTED       The function is unsupported by this
+                                     driver instance.
+  @retval      Other values          Fail to set SMBIOS structure table.
+**/
+EFI_STATUS
+EFIAPI
+GetSmbiosStructureByHandle (
+  IN   EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL  *This,
+  IN   UINT16                               Handle,
+  OUT  UINT8                                **Buffer,
+  OUT  UINT32                               *BufferSize
+  )
+{
+  DEBUG ((DEBUG_INFO, "%a: Unsupported.\n", __FUNCTION__));
+  // Only support PLDM SMBIOS Transfer push mode.
+  return EFI_UNSUPPORTED;
+}
+
+EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_V1_0  mPldmSmbiosTransferProtocolV10 = {
+  GetSmbiosStructureTableMetaData,
+  SetSmbiosStructureTableMetaData,
+  GetSmbiosStructureTable,
+  SetSmbiosStructureTable,
+  GetSmbiosStructureByType,
+  GetSmbiosStructureByHandle
+};
+
+EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL  mPldmSmbiosTransferProtocol;
+
+/**
+  The entry point of the PLDM SMBIOS Transfer DXE driver.
+
+  @param[in] ImageHandle - Handle of this driver image
+  @param[in] SystemTable - Table containing standard EFI services
+
+  @retval EFI_SUCCESS    - IPMI Protocol is installed successfully.
+  @retval Otherwise      - Other errors.
+**/
+EFI_STATUS
+EFIAPI
+DxePldmSmbiosTransferEntry (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_HANDLE  Handle;
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "%a: Entry.\n", __FUNCTION__));
+
+  SetSmbiosStructureTableHandle = 0;
+
+  Handle                                           = NULL;
+  mPldmSmbiosTransferProtocol.ProtocolVersion      = EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL_VERSION;
+  mPldmSmbiosTransferProtocol.Functions.Version1_0 = &mPldmSmbiosTransferProtocolV10;
+  Status                                           = gBS->InstallProtocolInterface (
+                                                            &Handle,
+                                                            &gEdkiiPldmSmbiosTransferProtocolGuid,
+                                                            EFI_NATIVE_INTERFACE,
+                                                            (VOID **)&mPldmSmbiosTransferProtocol
+                                                            );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Fail to install EDKII_PLDM_SMBIOS_TRANSFER_PROTOCOL.\n", __FUNCTION__));
+  }
+
+  return Status;
+}
+
+/**
+  This is the unload handler of PLDM SMBIOS Transfer DXE driver.
+
+  @param[in] ImageHandle           The driver's image handle.
+
+  @retval    EFI_SUCCESS           The image is unloaded.
+  @retval    Others                Failed to unload the image.
+
+**/
+EFI_STATUS
+EFIAPI
+PldmSmbiosTransferUnloadImage (
+  IN EFI_HANDLE  ImageHandle
+  )
+{
+  return EFI_SUCCESS;
+}
-- 
2.37.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#102421): https://edk2.groups.io/g/devel/message/102421
Mute This Topic: https://groups.io/mt/98037374/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