public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel] [edk2-platforms] AmdPlatformPkg: Adds SmbiosCommonDxe driver
@ 2024-05-20 10:23 Abdul Lateef Attar via groups.io
  2024-05-20 11:00 ` Chang, Abner via groups.io
  0 siblings, 1 reply; 2+ messages in thread
From: Abdul Lateef Attar via groups.io @ 2024-05-20 10:23 UTC (permalink / raw)
  To: devel; +Cc: Abdul Lateef Attar, Abner Chang, Paul Grimes

Adds SMBIOS common driver which generates various
tables for AMD platforms.

Cc: Abner Chang <abner.chang@amd.com>
Cc: Paul Grimes <paul.grimes@amd.com>
Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
---
 .../AMD/AmdPlatformPkg/AmdPlatformPkg.dec     |  63 ++++-
 .../AMD/AmdPlatformPkg/AmdPlatformPkg.dsc     |   3 +-
 .../SmbiosCommonDxe/DefaultLomDevicePath.c    | 130 ++++++++++
 .../Universal/SmbiosCommonDxe/SmbiosCommon.h  | 210 ++++++++++++++++
 .../SmbiosCommonDxe/SmbiosCommonDxe.inf       |  76 ++++++
 .../SmbiosCommonDxe/SmbiosCommonEntryPoint.c  | 148 +++++++++++
 .../Type11OemStringsFunction.c                |  91 +++++++
 .../Type12SystemCfgOptionsFunction.c          |  90 +++++++
 .../Type13BiosLanguageInfoFunction.c          | 146 +++++++++++
 .../Type38IpmiDeviceInformation.c             |  70 ++++++
 .../Type41OnboardDevExtInfoFunction.c         | 237 ++++++++++++++++++
 .../Type8PortConnectorInfoFunction.c          | 133 ++++++++++
 .../Type9SystemSlotInfoFunction.c             |  94 +++++++
 13 files changed, 1489 insertions(+), 2 deletions(-)
 create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/DefaultLomDevicePath.c
 create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCommon.h
 create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCommonDxe.inf
 create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCommonEntryPoint.c
 create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type11OemStringsFunction.c
 create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type12SystemCfgOptionsFunction.c
 create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type13BiosLanguageInfoFunction.c
 create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type38IpmiDeviceInformation.c
 create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type41OnboardDevExtInfoFunction.c
 create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type8PortConnectorInfoFunction.c
 create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type9SystemSlotInfoFunction.c

diff --git a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dec b/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dec
index 83f57f6d0a..787dac4cca 100644
--- a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dec
+++ b/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dec
@@ -8,7 +8,7 @@
 #
 ##
 
-[Defines]
+[Defines] 
   DEC_SPECIFICATION = 1.27
   PACKAGE_NAME      = AmdPlatformPkg
   PACKAGE_GUID      = 2CB1238B-18E2-4837-B714-9DAB2B30A3C2
@@ -42,3 +42,64 @@
   # 3 - BT
   # 4 - SSIF
   gAmdPlatformPkgTokenSpaceGuid.PcdIpmiInterfaceType|0|UINT8|0x00020001
+
+  #
+  # This PCD is mapped to AMD SMBIOS type 8 record structure
+  #
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType8Number|0|UINT8|0x00020002
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType8|{0x0}|SMBIOS_PORT_CONNECTOR_RECORD_ARRAY|0x00020003 {
+  <HeaderFiles>
+    Pcd/SmbiosPcd.h
+  <Packages>
+    AmdPlatformPkg/AmdPlatformPkg.dec
+    MdePkg/MdePkg.dec
+    MdeModulePkg/MdeModulePkg.dec
+  }
+
+  #
+  # This PCD is mapped to AMD SMBIOS type 41 record structure
+  #
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType41Number|0|UINT8|0x00020004
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType41|{0x0}|SMBIOS_ONBOARD_DEV_EXT_INFO_ARRAY|0x00020005 {
+  <HeaderFiles>
+    Pcd/SmbiosPcd.h
+  <Packages>
+    AmdPlatformPkg/AmdPlatformPkg.dec
+    MdePkg/MdePkg.dec
+    MdeModulePkg/MdeModulePkg.dec
+  }
+
+  #
+  # These PCDs are mapped to AMD SMBIOS type 9 record structure
+  #
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1|{0x0}|MISC_SLOT_CHARACTERISTICS1|0x00020009 {
+  <HeaderFiles>
+    IndustryStandard/SmBios.h
+  }
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.CharacteristicsUnknown|0
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.Provides50Volts|0
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.Provides33Volts|1
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.SharedSlot|0
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.PcCard16Supported|0
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.CardBusSupported|0
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.ZoomVideoSupported|0
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.ModemRingResumeSupported|0
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2|{0x0}|MISC_SLOT_CHARACTERISTICS2|0x0002000A {
+  <HeaderFiles>
+    IndustryStandard/SmBios.h
+  }
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.PmeSignalSupported|0
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.HotPlugDevicesSupported|0
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.SmbusSignalSupported|0
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.BifurcationSupported|1
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.AsyncSurpriseRemoval|0
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.FlexbusSlotCxl10Capable|0
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.FlexbusSlotCxl20Capable|0
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.Reserved|0
+
+[PcdsDynamic, PcdsDynamicEx]
+  # SMBIOS
+  gAmdPlatformPkgTokenSpaceGuid.PcdType11OemStringsCount|0|UINT8|0x00030001
+  gAmdPlatformPkgTokenSpaceGuid.PcdType11OemStrings|NULL|VOID*|0x00030002
+  gAmdPlatformPkgTokenSpaceGuid.PcdType12SystemCfgOptionsCount|0|UINT8|0x00030003
+  gAmdPlatformPkgTokenSpaceGuid.PcdType12SystemCfgOptions|NULL|VOID*|0x00030004
diff --git a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc b/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc
index 99dd5b341f..d11d3594e3 100644
--- a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc
+++ b/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc
@@ -71,4 +71,5 @@
   AmdPlatformPkg/Universal/HiiConfigRouting/AmdConfigRouting.inf
   AmdPlatformPkg/Universal/LogoDxe/JpegLogoDxe.inf                                           # Server platform JPEG logo driver
   AmdPlatformPkg/Universal/LogoDxe/LogoDxe.inf                                               # Server platfrom Bitmap logo driver
-  AmdPlatformPkg/Universal/LogoDxe/S3LogoDxe.inf
\ No newline at end of file
+  AmdPlatformPkg/Universal/LogoDxe/S3LogoDxe.inf
+  AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCommonDxe.inf
diff --git a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/DefaultLomDevicePath.c b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/DefaultLomDevicePath.c
new file mode 100644
index 0000000000..92c7aa5e07
--- /dev/null
+++ b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/DefaultLomDevicePath.c
@@ -0,0 +1,130 @@
+/** @file
+  This file contains the implementation of the DefaultLomDevicePath protocol.
+  The DefaultLomDevicePath protocol is used to identify the default LOM device
+  path for the system. The protocol is installed by the SmbiosCommonDxe driver
+  and is used by the BDS to identify the default LOM device path for the system.
+
+  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Protocol/PciEnumerationComplete.h>
+#include <IndustryStandard/Ipmi.h>
+#include <Bus/Pci/PciBusDxe/PciBus.h>
+#include <Pcd/SmbiosPcd.h>
+#include <Library/PciSegmentLib.h>
+#include <Pcd/SmbiosPcd.h>
+#include "SmbiosCommon.h"
+#include <IndustryStandard/Ipmi.h>
+#include <Library/BoardBdsHookLib.h>
+
+EFI_HANDLE                                mBoardBdsHandle = NULL;
+BOARD_BDS_BOOT_FROM_DEVICE_PATH_PROTOCOL  mBootDevicePathProtocol;
+
+/**
+  Find the Lan-On-Motherboard device path. Installs BOARD_BDS_BOOT_FROM_DEVICE_PATH_PROTOCOL
+  with the LOM device path protocol
+
+  @retval EFI NOT_FOUND         LOM device path is not found
+  @retval EFI_SUCCESS           LOM device path found
+**/
+EFI_STATUS
+EFIAPI
+InstallLomDevicePath (
+  )
+{
+  SMBIOS_ONBOARD_DEV_EXT_INFO_RECORD  *DevExtInfoRecord;
+  EFI_STATUS                          Status;
+  EFI_HANDLE                          *PciHandles;
+  UINTN                               PciHandlesSize;
+  UINTN                               Index;
+  EFI_PCI_IO_PROTOCOL                 *PciProtocol;
+  PCI_IO_DEVICE                       *PciIoDevice;
+  UINT8                               NumberOfDevices;
+  UINT8                               DevIdx;
+  UINTN                               SegmentNumber;
+  UINTN                               BusNumber;
+  UINTN                               DeviceNumber;
+  UINTN                               FunctionNumber;
+
+  NumberOfDevices  = PcdGet8 (PcdAmdSmbiosType41Number);
+  DevExtInfoRecord = (SMBIOS_ONBOARD_DEV_EXT_INFO_RECORD *)PcdGetPtr (PcdAmdSmbiosType41);
+
+  // No device entries found
+  if (NumberOfDevices == 0) {
+    DEBUG ((DEBUG_INFO, "No onboard devices found.\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  // search through present on board devices, look for onboard ethernet
+  for (DevIdx = 0; DevIdx < NumberOfDevices; DevIdx++) {
+    if (AsciiStrCmp (DevExtInfoRecord->RefDesignationStr, "Onboard Ethernet") == 0) {
+      break;
+    }
+
+    DevExtInfoRecord++;
+  }
+
+  // edge case, no Onboard Ethernet designator
+  if (AsciiStrCmp (DevExtInfoRecord->RefDesignationStr, "Onboard Ethernet") != 0) {
+    DEBUG ((DEBUG_INFO, "No Onboard ethernet SMBIOS designator found!\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiPciIoProtocolGuid,
+                  NULL,
+                  &PciHandlesSize,
+                  &PciHandles
+                  );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "Can't locate gEfiPciIoProtocolGuid Protocol: Status = %r\n\n", Status));
+    return Status;
+  }
+
+  for (Index = 0; Index < PciHandlesSize; Index++) {
+    Status = gBS->HandleProtocol (
+                    PciHandles[Index],
+                    &gEfiPciIoProtocolGuid,
+                    (VOID **)&PciProtocol
+                    );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_INFO, "ERROR - Status = %r when locating PciIoProtocol\n", Status));
+      continue;
+    }
+
+    PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciProtocol);
+    Status      = PciIoDevice->PciIo.GetLocation (&PciIoDevice->PciIo, &SegmentNumber, &BusNumber, &DeviceNumber, &FunctionNumber);
+
+    if ((PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SegmentNumber, BusNumber, DeviceNumber, FunctionNumber, 2)) == DevExtInfoRecord->DeviceId) &&
+        (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SegmentNumber, BusNumber, DeviceNumber, FunctionNumber, 0)) == DevExtInfoRecord->VendorId))
+    {
+      // Making Lan0 default for systems with two LANs
+      if (FunctionNumber == 0) {
+        DEBUG ((DEBUG_INFO, "Found Onboard Device with DeviceID=0x%X, VendorID=0x%X\n", DevExtInfoRecord->DeviceId, DevExtInfoRecord->VendorId));
+        Status = EFI_SUCCESS;
+        // install device path protocol here
+        mBootDevicePathProtocol.Device                     = PciIoDevice->DevicePath;
+        mBootDevicePathProtocol.IpmiBootDeviceSelectorType = IPMI_BOOT_DEVICE_SELECTOR_PXE;
+        Status                                             = gBS->InstallProtocolInterface (
+                                                                    &mBoardBdsHandle,
+                                                                    &gBoardBdsBootFromDevicePathProtocolGuid,
+                                                                    EFI_NATIVE_INTERFACE,
+                                                                    &mBootDevicePathProtocol
+                                                                    );
+        if (!EFI_ERROR (Status)) {
+          DEBUG ((DEBUG_INFO, "BoardBdsBootFromDevicePathProtocol installed successfully\n"));
+        }
+
+        break;
+      }
+    }
+  }
+
+  return Status;
+}
diff --git a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCommon.h b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCommon.h
new file mode 100644
index 0000000000..770053e42b
--- /dev/null
+++ b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCommon.h
@@ -0,0 +1,210 @@
+/** @file
+  AMD Smbios common header file.
+
+  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef SMBIOS_COMMON_DRIVER_H_
+#define SMBIOS_COMMON_DRIVER_H_
+
+#include <PiDxe.h>
+#include <Protocol/Smbios.h>
+#include <IndustryStandard/SmBios.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PciSegmentLib.h>
+
+/**
+  Add an SMBIOS record.
+
+  @param[in]  Smbios                The EFI_SMBIOS_PROTOCOL instance.
+  @param[out] SmbiosHandle          A unique handle will be assigned to the SMBIOS record.
+  @param[in]  Record                The data for the fixed portion of the SMBIOS record. The format of the record is
+                                determined by EFI_SMBIOS_TABLE_HEADER.Type. The size of the formatted area is defined
+                                by EFI_SMBIOS_TABLE_HEADER.Length and either followed by a double-null (0x0000) or
+                                a set of null terminated strings and a null.
+
+  @retval EFI_SUCCESS           Record was added.
+  @retval EFI_OUT_OF_RESOURCES  Record was not added due to lack of system resources.
+
+**/
+EFI_STATUS
+AddCommonSmbiosRecord (
+  IN EFI_SMBIOS_PROTOCOL      *Smbios,
+  OUT EFI_SMBIOS_HANDLE       *SmbiosHandle,
+  IN EFI_SMBIOS_TABLE_HEADER  *Record
+  );
+
+/**
+  This function gets the Bus, Device and Segment number of a PCI device when Vendor ID, Device ID and instance
+  are provided.
+
+  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
+  @param[in]  VendorId                   Vendor ID of the PCI device to be provided.
+  @param[in]  DeviceId                   Device ID of the PCI device to be provided
+  @param[out]  Instance                   Instance of the PCI device. If more than one devices with same vendor
+                                     and device ID is present, instance number is used.
+  @param[out]  Segment                    Segment number of the PCI device is assigned.
+  @param[out]  Bus                        Bus number of the PCI device is assigned.
+  @param[out]  Device                     Device number of the PCI device is assigned.
+  @param[out]  Functions                  Bits 0-7 of the Functions variable correspond to respective function numbers.
+  @param[out]  DeviceFound                Set to 1 if the device is found.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+**/
+EFI_STATUS
+EFIAPI
+GetBusDeviceInfo (
+  IN  UINT16  *VendorId,
+  IN  UINT16  *DeviceId,
+  IN  UINT8   *Instance,
+  OUT UINT16  *Segment,
+  OUT UINT8   *Bus,
+  OUT UINT8   *Device,
+  OUT UINT8   *Functions,
+  OUT UINT8   *DeviceFound
+  );
+
+/**
+  PciEnumerationComplete Protocol notification event handler.
+
+  @param[in] Event    Event whose notification function is being invoked.
+  @param[in] Context  Pointer to the notification function's context.
+**/
+VOID
+EFIAPI
+OnPciEnumerationComplete (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  );
+
+/**
+  This function updates IPMI Device information changes to the contents of the
+  Table Type 38.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+**/
+EFI_STATUS
+EFIAPI
+IpmiDeviceInformation (
+  IN  EFI_SMBIOS_PROTOCOL  *Smbios
+  );
+
+/**
+  This function checks for system slot info and adds smbios record (Type 9).
+
+  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_OUT_OF_RESOURCES       Resource not available.
+
+**/
+EFI_STATUS
+EFIAPI
+SystemSlotInfoFunction (
+  IN  EFI_SMBIOS_PROTOCOL  *Smbios
+  );
+
+/**
+  This function adds port connector information smbios record (Type 8).
+
+  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_OUT_OF_RESOURCES       Resource not available.
+**/
+EFI_STATUS
+EFIAPI
+PortConnectorInfoFunction (
+  IN  EFI_SMBIOS_PROTOCOL  *Smbios
+  );
+
+/**
+  This function adds OEM strings smbios record (Type 11).
+
+  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_OUT_OF_RESOURCES       Resource not available.
+**/
+EFI_STATUS
+EFIAPI
+OemStringsFunction (
+  IN EFI_SMBIOS_PROTOCOL  *Smbios
+  );
+
+/**
+  This function adds System Configuration Options record (Type 12).
+
+  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_OUT_OF_RESOURCES       Resource not available.
+**/
+EFI_STATUS
+EFIAPI
+SystemCfgOptionsFunction (
+  IN EFI_SMBIOS_PROTOCOL  *Smbios
+  );
+
+/**
+  This function adds bios language information smbios record (Type 13).
+
+  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_OUT_OF_RESOURCES       Resource not available.
+  @retval EFI_NOT_FOUND              Not able to locate PlatformLanguage.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosLanguageInfoFunction (
+  IN  EFI_SMBIOS_PROTOCOL  *Smbios
+  );
+
+/**
+  This function adds onboard devices extended information smbios record (Type 41).
+
+  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_OUT_OF_RESOURCES       Resource not available.
+**/
+EFI_STATUS
+EFIAPI
+OnboardDevExtInfoFunction (
+  IN EFI_SMBIOS_PROTOCOL  *Smbios
+  );
+
+/**
+  Find the Lan-On-Motherboard device path. Installs BOARD_BDS_BOOT_FROM_DEVICE_PATH_PROTOCOL
+  with the LOM device path protocol
+
+  @retval EFI NOT_FOUND         LOM device path is not found
+  @retval EFI_SUCCESS           LOM device path found
+**/
+EFI_STATUS
+EFIAPI
+InstallLomDevicePath (
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI EFI_COMMON_SMBIOS_DATA_FUNCTION)(
+  IN  EFI_SMBIOS_PROTOCOL  *Smbios
+  );
+
+typedef struct {
+  EFI_COMMON_SMBIOS_DATA_FUNCTION    *Function;
+} EFI_COMMON_SMBIOS_DATA;
+#endif // SMBIOS_COMMON_DRIVER_H_
diff --git a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCommonDxe.inf b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCommonDxe.inf
new file mode 100644
index 0000000000..e3d296192c
--- /dev/null
+++ b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCommonDxe.inf
@@ -0,0 +1,76 @@
+## @file
+#  AMD common SMBIOS DXE library Description File
+#
+#  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SmbiosCommonDxe
+  FILE_GUID                      = 2546E2B4-8629-47C3-A294-91E244936CBE
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmbiosCommonEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  SmbiosCommon.h
+  SmbiosCommonEntryPoint.c
+  Type38IpmiDeviceInformation.c
+  Type9SystemSlotInfoFunction.c
+  Type8PortConnectorInfoFunction.c
+  Type11OemStringsFunction.c
+  Type12SystemCfgOptionsFunction.c
+  Type13BiosLanguageInfoFunction.c
+  Type41OnboardDevExtInfoFunction.c
+  DefaultLomDevicePath.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  AmdPlatformPkg/AmdPlatformPkg.dec
+  BoardModulePkg/BoardModulePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  HobLib
+  MemoryAllocationLib
+  PcdLib
+  UefiDriverEntryPoint
+  UefiLib
+  PlatformSocLib
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                       ## PROTOCOL ALWAYS_CONSUMED
+  gEfiPciEnumerationCompleteProtocolGuid       ## CONSUMES
+  gEfiPciIoProtocolGuid                        ## CONSUMES
+  gBoardBdsBootFromDevicePathProtocolGuid      ## PRODUCES
+
+[Pcd]
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType8                       ## CONSUMES
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType8Number                 ## CONSUMES
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1   ## CONSUMES
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2   ## CONSUMES
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType41                      ## CONSUMES
+  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType41Number                ## CONSUMES
+  gAmdPlatformPkgTokenSpaceGuid.PcdIpmiInterfaceType                    ## CONSUMES
+  gAmdPlatformPkgTokenSpaceGuid.PcdType11OemStringsCount                ## CONSUMES
+  gAmdPlatformPkgTokenSpaceGuid.PcdType11OemStrings                     ## CONSUMES
+  gAmdPlatformPkgTokenSpaceGuid.PcdType12SystemCfgOptionsCount          ## CONSUMES
+  gAmdPlatformPkgTokenSpaceGuid.PcdType12SystemCfgOptions               ## CONSUMES
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLangCodes      ## CONSUMES
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang           ## CONSUMES
+  gEfiMdePkgTokenSpaceGuid.PcdIpmiKcsIoBaseAddress                      ## CONSUMES
+
+[Depex]
+  gEfiSmbiosProtocolGuid
diff --git a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCommonEntryPoint.c b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCommonEntryPoint.c
new file mode 100644
index 0000000000..eaa66be454
--- /dev/null
+++ b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCommonEntryPoint.c
@@ -0,0 +1,148 @@
+/** @file
+  AMD Smbios Common DXE entry point.
+
+  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "SmbiosCommon.h"
+
+EFI_COMMON_SMBIOS_DATA  mSmbiosCommonDataFuncTable[] = {
+  { &IpmiDeviceInformation     },
+  { &SystemSlotInfoFunction    },
+  { &PortConnectorInfoFunction },
+  { &OemStringsFunction        },
+  { &SystemCfgOptionsFunction  },
+  { &BiosLanguageInfoFunction  }
+};
+
+/**
+  Add an SMBIOS record.
+
+  @param  Smbios                The EFI_SMBIOS_PROTOCOL instance.
+  @param  SmbiosHandle          A unique handle will be assigned to the SMBIOS record.
+  @param  Record                The data for the fixed portion of the SMBIOS record. The format of the record is
+                                determined by EFI_SMBIOS_TABLE_HEADER.Type. The size of the formatted area is defined
+                                by EFI_SMBIOS_TABLE_HEADER.Length and either followed by a double-null (0x0000) or
+                                a set of null terminated strings and a null.
+
+  @retval EFI_SUCCESS           Record was added.
+  @retval EFI_OUT_OF_RESOURCES  Record was not added due to lack of system resources.
+
+**/
+EFI_STATUS
+AddCommonSmbiosRecord (
+  IN EFI_SMBIOS_PROTOCOL      *Smbios,
+  OUT EFI_SMBIOS_HANDLE       *SmbiosHandle,
+  IN EFI_SMBIOS_TABLE_HEADER  *Record
+  )
+{
+  *SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+  return Smbios->Add (
+                   Smbios,
+                   NULL,
+                   SmbiosHandle,
+                   Record
+                   );
+}
+
+/**
+  PciEnumerationComplete Protocol notification event handler.
+
+  @param[in] Event    Event whose notification function is being invoked.
+  @param[in] Context  Pointer to the notification function's context.
+**/
+VOID
+EFIAPI
+OnPciEnumerationComplete (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  EFI_STATUS           EfiStatus;
+  EFI_SMBIOS_PROTOCOL  *Smbios;
+
+  EfiStatus = gBS->LocateProtocol (
+                     &gEfiSmbiosProtocolGuid,
+                     NULL,
+                     (VOID **)&Smbios
+                     );
+  if (EFI_ERROR (EfiStatus)) {
+    DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol.  %r\n", EfiStatus));
+  }
+
+  // Install Type 41 when PCI enumeration is complete
+  EfiStatus = OnboardDevExtInfoFunction (Smbios);
+  if (EFI_ERROR (EfiStatus)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "Skip installing SMBIOS Table 41, ReturnStatus=%r\n",
+      EfiStatus
+      ));
+  }
+
+  EfiStatus = InstallLomDevicePath ();
+}
+
+/**
+  EFI driver entry point. This driver parses mSmbiosCommonDataFuncTable
+  structure and generates common platform smbios records.
+
+  @param  ImageHandle     Handle for the image of this driver
+  @param  SystemTable     Pointer to the EFI System Table
+
+  @retval  EFI_SUCCESS    The data was successfully stored.
+
+**/
+EFI_STATUS
+EFIAPI
+SmbiosCommonEntryPoint (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  UINTN                Index;
+  EFI_STATUS           EfiStatus;
+  EFI_SMBIOS_PROTOCOL  *Smbios;
+  EFI_EVENT            ProtocolNotifyEvent;
+  VOID                 *Registration;
+
+  DEBUG ((DEBUG_INFO, "%a: Entry.\n", __func__));
+
+  EfiStatus = gBS->LocateProtocol (
+                     &gEfiSmbiosProtocolGuid,
+                     NULL,
+                     (VOID **)&Smbios
+                     );
+  if (EFI_ERROR (EfiStatus)) {
+    DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol.  %r\n", EfiStatus));
+    return EfiStatus;
+  }
+
+  ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent (
+                          &gEfiPciEnumerationCompleteProtocolGuid,
+                          TPL_CALLBACK,
+                          OnPciEnumerationComplete,
+                          NULL,
+                          &Registration
+                          );
+  if (ProtocolNotifyEvent == NULL) {
+    DEBUG ((DEBUG_ERROR, "Could not create PCI enumeration complete event\n"));
+  }
+
+  for (Index = 0; Index < sizeof (mSmbiosCommonDataFuncTable)/sizeof (mSmbiosCommonDataFuncTable[0]); ++Index) {
+    EfiStatus = (*mSmbiosCommonDataFuncTable[Index].Function)(Smbios);
+    if (EFI_ERROR (EfiStatus)) {
+      // Continue installing remaining tables if one table fails.
+      DEBUG ((
+        DEBUG_ERROR,
+        "Skip installing SMBIOS Table Index=%d, ReturnStatus=%r\n",
+        Index,
+        EfiStatus
+        ));
+      continue;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type11OemStringsFunction.c b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type11OemStringsFunction.c
new file mode 100644
index 0000000000..53e7a57355
--- /dev/null
+++ b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type11OemStringsFunction.c
@@ -0,0 +1,91 @@
+/** @file
+  AMD SMBIOS Type 11 Record
+
+  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "SmbiosCommon.h"
+
+/**
+  This function adds OEM strings smbios record (Type 11).
+
+  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_OUT_OF_RESOURCES       Resource not available.
+**/
+EFI_STATUS
+EFIAPI
+OemStringsFunction (
+  IN EFI_SMBIOS_PROTOCOL  *Smbios
+  )
+{
+  EFI_STATUS           Status;
+  EFI_SMBIOS_HANDLE    SmbiosHandle;
+  SMBIOS_TABLE_TYPE11  *SmbiosRecord;
+  UINT8                OemStrCount;
+  UINTN                OemStrLen;
+  UINTN                OemStrListSize;
+  CHAR8                *OemStrPtr;
+  UINT8                Idx;
+  UINTN                StringOffset;
+
+  Status         = EFI_SUCCESS;
+  SmbiosRecord   = NULL;
+  OemStrListSize = 0;
+
+  if (Smbios == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Get number of OEM strings
+  OemStrCount = PcdGet8 (PcdType11OemStringsCount);
+
+  // Calculate size of all OEM Strings
+  OemStrPtr = (CHAR8 *)PcdGetPtr (PcdType11OemStrings);
+  for (Idx = 0; Idx < OemStrCount; Idx++) {
+    OemStrLen       = AsciiStrSize (OemStrPtr);
+    OemStrPtr      += OemStrLen;
+    OemStrListSize += OemStrLen;
+  }
+
+  // Allocate memory for Type11 record
+  SmbiosRecord = AllocateZeroPool (
+                   sizeof (SMBIOS_TABLE_TYPE11) + OemStrListSize + 1
+                   );
+
+  if (SmbiosRecord == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  SmbiosRecord->Hdr.Type    = SMBIOS_TYPE_OEM_STRINGS;
+  SmbiosRecord->Hdr.Length  = sizeof (SMBIOS_TABLE_TYPE11);
+  SmbiosRecord->Hdr.Handle  = 0;
+  SmbiosRecord->StringCount = OemStrCount;
+
+  StringOffset = SmbiosRecord->Hdr.Length;
+
+  // Append strings at the end
+  OemStrPtr = (CHAR8 *)PcdGetPtr (PcdType11OemStrings);
+  for (Idx = 0; Idx < OemStrCount; Idx++) {
+    OemStrLen = AsciiStrSize (OemStrPtr);
+    CopyMem (
+      (UINT8 *)SmbiosRecord + StringOffset,
+      OemStrPtr,
+      OemStrLen
+      );
+    OemStrPtr    += OemStrLen;
+    StringOffset += OemStrLen;
+  }
+
+  Status = AddCommonSmbiosRecord (
+             Smbios,
+             &SmbiosHandle,
+             (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord
+             );
+
+  FreePool (SmbiosRecord);
+
+  return Status;
+}
diff --git a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type12SystemCfgOptionsFunction.c b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type12SystemCfgOptionsFunction.c
new file mode 100644
index 0000000000..befb122372
--- /dev/null
+++ b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type12SystemCfgOptionsFunction.c
@@ -0,0 +1,90 @@
+/** @file
+  AMD SMBIOS Type 12 Record
+
+  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "SmbiosCommon.h"
+
+/**
+  This function adds System Configuration Options record (Type 12).
+
+  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_OUT_OF_RESOURCES       Resource not available.
+**/
+EFI_STATUS
+EFIAPI
+SystemCfgOptionsFunction (
+  IN EFI_SMBIOS_PROTOCOL  *Smbios
+  )
+{
+  EFI_STATUS           Status;
+  EFI_SMBIOS_HANDLE    SmbiosHandle;
+  SMBIOS_TABLE_TYPE12  *SmbiosRecord;
+  UINT8                SystemCfgOptionsCount;
+  UINTN                SystemCfgOptionsLen;
+  UINTN                SystemCfgOptionsListSize;
+  CHAR8                *SystemCfgOptionsPtr;
+  UINT8                Idx;
+  UINTN                StringOffset;
+
+  Status                   = EFI_SUCCESS;
+  SmbiosRecord             = NULL;
+  SystemCfgOptionsListSize = 0;
+
+  if (Smbios == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Get number of System Configuration Options
+  SystemCfgOptionsCount = PcdGet8 (PcdType12SystemCfgOptionsCount);
+
+  // Calculate size of all Strings
+  SystemCfgOptionsPtr = (CHAR8 *)PcdGetPtr (PcdType12SystemCfgOptions);
+  for (Idx = 0; Idx < SystemCfgOptionsCount; Idx++) {
+    SystemCfgOptionsLen       = AsciiStrSize (SystemCfgOptionsPtr);
+    SystemCfgOptionsPtr      += SystemCfgOptionsLen;
+    SystemCfgOptionsListSize += SystemCfgOptionsLen;
+  }
+
+  // Allocate memory for Type12 record
+  SmbiosRecord = AllocateZeroPool (
+                   sizeof (SMBIOS_TABLE_TYPE12) + SystemCfgOptionsListSize + 1
+                   );
+
+  if (SmbiosRecord == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  SmbiosRecord->Hdr.Type    = SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS;
+  SmbiosRecord->Hdr.Length  = sizeof (SMBIOS_TABLE_TYPE12);
+  SmbiosRecord->Hdr.Handle  = 0;
+  SmbiosRecord->StringCount = SystemCfgOptionsCount;
+
+  StringOffset = SmbiosRecord->Hdr.Length;
+
+  // Append strings at the end
+  SystemCfgOptionsPtr = (CHAR8 *)PcdGetPtr (PcdType12SystemCfgOptions);
+  for (Idx = 0; Idx < SystemCfgOptionsCount; Idx++) {
+    SystemCfgOptionsLen = AsciiStrSize (SystemCfgOptionsPtr);
+    CopyMem (
+      (UINT8 *)SmbiosRecord + StringOffset,
+      SystemCfgOptionsPtr,
+      SystemCfgOptionsLen
+      );
+    SystemCfgOptionsPtr += SystemCfgOptionsLen;
+    StringOffset        += SystemCfgOptionsLen;
+  }
+
+  Status = AddCommonSmbiosRecord (
+             Smbios,
+             &SmbiosHandle,
+             (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord
+             );
+  FreePool (SmbiosRecord);
+
+  return Status;
+}
diff --git a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type13BiosLanguageInfoFunction.c b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type13BiosLanguageInfoFunction.c
new file mode 100644
index 0000000000..7d3ada2769
--- /dev/null
+++ b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type13BiosLanguageInfoFunction.c
@@ -0,0 +1,146 @@
+/** @file
+  AMD SMBIOS Type 13 Record
+
+  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "SmbiosCommon.h"
+
+/**
+  This function adds bios language information smbios record (Type 13).
+
+  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_OUT_OF_RESOURCES       Resource not available.
+  @retval EFI_NOT_FOUND              Not able to locate PlatformLanguage.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosLanguageInfoFunction (
+  IN  EFI_SMBIOS_PROTOCOL  *Smbios
+  )
+{
+  EFI_STATUS           Status;
+  EFI_SMBIOS_HANDLE    SmbiosHandle;
+  SMBIOS_TABLE_TYPE13  *SmbiosRecord;
+  UINTN                TotalSize;
+  UINTN                StringOffset;
+  UINTN                VarSize;
+  UINTN                Idx;
+  UINT8                NumSupportedLang;
+  UINT8                CurrLangIdx;
+  CHAR8                *CurrLang;
+  CHAR8                *SupportedLang;
+  CHAR8                *LangStr;
+
+  if (Smbios == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  CurrLang      = NULL;
+  SupportedLang = NULL;
+
+  // Get the current language.
+  Status = GetEfiGlobalVariable2 (
+             L"PlatformLang",
+             (void **)&CurrLang,
+             &VarSize
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to get PlatformLang: %r\n", Status));
+
+    VarSize = AsciiStrSize (
+                (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang)
+                );
+    CurrLang = AllocateCopyPool (
+                 VarSize,
+                 (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang)
+                 );
+    ASSERT (CurrLang != NULL);
+  }
+
+  // Get the list of supported languages.
+  Status = GetEfiGlobalVariable2 (
+             L"PlatformLangCodes",
+             (void **)&SupportedLang,
+             &VarSize
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to get PlatformLangCodes: %r\n", Status));
+
+    VarSize = AsciiStrSize (
+                (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)
+                );
+    SupportedLang = AllocateCopyPool (
+                      VarSize,
+                      (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)
+                      );
+    ASSERT (SupportedLang != NULL);
+  }
+
+  // Calculate number of supported languages and index of current language in list.
+  CurrLangIdx      = 0;
+  NumSupportedLang = 0;
+  LangStr          = SupportedLang;
+
+  for (Idx = 0; Idx < VarSize; Idx++) {
+    if ((SupportedLang[Idx] == ';') || (SupportedLang[Idx] == '\0')) {
+      // Found a language string, increment the language count.
+      NumSupportedLang++;
+
+      // Replace string separator with null termination.
+      SupportedLang[Idx] = '\0';
+      if (!AsciiStrCmp (LangStr, CurrLang)) {
+        CurrLangIdx = NumSupportedLang;
+      }
+
+      // Point LangStr to next string in list.
+      LangStr = &SupportedLang[Idx + 1];
+    }
+  }
+
+  if (CurrLangIdx == 0) {
+    DEBUG ((DEBUG_ERROR, "Failed to locate PlatformLang in PlatformLangCode.\n"));
+    Status = EFI_NOT_FOUND;
+  } else {
+    // Calculate record size and allocate memory for smbios record.
+    TotalSize = sizeof (SMBIOS_TABLE_TYPE13) + VarSize + 1;
+
+    SmbiosRecord = AllocateZeroPool (TotalSize);
+    if (SmbiosRecord == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+    } else {
+      // Fill record data and strings.
+      SmbiosRecord->Hdr.Type             = SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION;
+      SmbiosRecord->Hdr.Length           = sizeof (SMBIOS_TABLE_TYPE13);
+      SmbiosRecord->Hdr.Handle           = 0;
+      SmbiosRecord->InstallableLanguages = NumSupportedLang;
+      SmbiosRecord->Flags                = 1; // Abbreviated Format.
+      SmbiosRecord->CurrentLanguages     = CurrLangIdx;
+
+      // Add strings to bottom of data block
+      StringOffset = SmbiosRecord->Hdr.Length;
+      CopyMem ((UINT8 *)SmbiosRecord + StringOffset, SupportedLang, VarSize);
+
+      Status = AddCommonSmbiosRecord (
+                 Smbios,
+                 &SmbiosHandle,
+                 (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord
+                 );
+      FreePool (SmbiosRecord);
+    }
+  }
+
+  if (CurrLang != NULL) {
+    FreePool (CurrLang);
+  }
+
+  if (SupportedLang != NULL) {
+    FreePool (SupportedLang);
+  }
+
+  return Status;
+}
diff --git a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type38IpmiDeviceInformation.c b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type38IpmiDeviceInformation.c
new file mode 100644
index 0000000000..e2ad2ddb3d
--- /dev/null
+++ b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type38IpmiDeviceInformation.c
@@ -0,0 +1,70 @@
+/** @file
+  AMD SMBIOS Type 38 Record
+
+  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include "SmbiosCommon.h"
+
+/**
+  This function updates IPMI Device information changes to the contents of the
+  Table Type 38.
+
+  @param[in]  Smbios  The EFI_SMBIOS_PROTOCOL protocol instance.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
+**/
+EFI_STATUS
+EFIAPI
+IpmiDeviceInformation (
+  IN  EFI_SMBIOS_PROTOCOL  *Smbios
+  )
+{
+  EFI_STATUS           Status;
+  EFI_SMBIOS_HANDLE    SmbiosHandle;
+  SMBIOS_TABLE_TYPE38  *SmbiosRecord;
+
+  //
+  // Two zeros following the last string.
+  //
+  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE38) + 1 + 1);
+  if (SmbiosRecord == NULL) {
+    ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  SmbiosRecord->Hdr.Type   = EFI_SMBIOS_TYPE_IPMI_DEVICE_INFORMATION;
+  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE38);
+  SmbiosRecord->Hdr.Handle = 0;
+
+  switch (FixedPcdGet8 (PcdIpmiInterfaceType)) {
+    case IPMIDeviceInfoInterfaceTypeKCS:
+      SmbiosRecord->InterfaceType             = IPMIDeviceInfoInterfaceTypeKCS;
+      SmbiosRecord->IPMISpecificationRevision = 0x20; // IPMI v2.0
+      SmbiosRecord->I2CSlaveAddress           = 0x00; // not used in KCS interface
+      SmbiosRecord->NVStorageDeviceAddress    = 0xFF;
+      // KCS port number base and set LSB bit 1 to mark IO ADDRESS space
+      SmbiosRecord->BaseAddress                       = FixedPcdGet16 (PcdIpmiKcsIoBaseAddress) | 0x1;
+      SmbiosRecord->BaseAddressModifier_InterruptInfo = 0x00;
+      SmbiosRecord->InterruptNumber                   = 0x00;
+      //
+      // Now we have got the full smbios record,
+      // call smbios protocol to add this record.
+      //
+      Status = AddCommonSmbiosRecord (
+                 Smbios,
+                 &SmbiosHandle,
+                 (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord
+                 );
+      break;
+    default:
+      // Do not add table
+      Status = EFI_UNSUPPORTED;
+      break;
+  }
+
+  FreePool (SmbiosRecord);
+  return Status;
+}
diff --git a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type41OnboardDevExtInfoFunction.c b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type41OnboardDevExtInfoFunction.c
new file mode 100644
index 0000000000..cbd4c75eaf
--- /dev/null
+++ b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type41OnboardDevExtInfoFunction.c
@@ -0,0 +1,237 @@
+/** @file
+  AMD SMBIOS Type 41 Record
+
+  Copyright (C) 2023 - 2024  Advanced Micro Devices, Inc. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Pcd/SmbiosPcd.h>
+#include "SmbiosCommon.h"
+
+#define MSR_MMIO_CFG_BASE  0xC0010058ul             // MMIO Configuration Base Address Register
+
+/**
+  This function adds onboard devices extended information smbios record (Type 41).
+
+  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_OUT_OF_RESOURCES       Resource not available.
+**/
+EFI_STATUS
+EFIAPI
+OnboardDevExtInfoFunction (
+  IN EFI_SMBIOS_PROTOCOL  *Smbios
+  )
+{
+  EFI_STATUS                          Status;
+  EFI_SMBIOS_HANDLE                   SmbiosHandle;
+  SMBIOS_TABLE_TYPE41                 *SmbiosRecord;
+  SMBIOS_ONBOARD_DEV_EXT_INFO_RECORD  *DevExtInfoRecord;
+  UINT8                               DevIdx;
+  UINT8                               Idx;
+  UINT8                               NumberOfDevices;
+  UINTN                               StringOffset;
+  CHAR8                               *RefDesStr;
+  UINTN                               RefDesStrLen;
+  UINT16                              SegmentNum;
+  UINT8                               BusNum;
+  UINT8                               DevNum;
+  UINT8                               Functions;
+  UINT8                               DeviceFound;
+
+  if (Smbios == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Get the total number of onboard devices.
+  NumberOfDevices = PcdGet8 (PcdAmdSmbiosType41Number);
+  DEBUG ((DEBUG_INFO, "%a: Total number of AMD SMBIOS type41 PCD structure %d.\n", __func__, NumberOfDevices));
+  DevExtInfoRecord = (SMBIOS_ONBOARD_DEV_EXT_INFO_RECORD *)PcdGetPtr (PcdAmdSmbiosType41);
+
+  // No device entries found
+  if (NumberOfDevices == 0) {
+    DEBUG ((DEBUG_INFO, "No onboard devices found.\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  // Generate type41 smbios record for each device and add it to Smbios table.
+  for (DevIdx = 0; DevIdx < NumberOfDevices; DevIdx++) {
+    DEBUG ((DEBUG_MANAGEABILITY, "Device number %d:\n", DevIdx));
+    // Check whether reference designation strings are present.
+    if (DevExtInfoRecord->ReferenceDesignation != 0) {
+      RefDesStr    = DevExtInfoRecord->RefDesignationStr;
+      RefDesStrLen = AsciiStrLen (RefDesStr) + 1;
+    } else {
+      RefDesStr    = NULL;
+      RefDesStrLen = 1;
+    }
+
+    DEBUG ((DEBUG_MANAGEABILITY, " - ReferenceDesignation = %d\n", DevExtInfoRecord->ReferenceDesignation));
+    DEBUG ((DEBUG_MANAGEABILITY, " - DeviceType = %d\n", DevExtInfoRecord->DeviceType));
+    DEBUG ((DEBUG_MANAGEABILITY, " - DeviceEnabled = %d\n", DevExtInfoRecord->DeviceEnabled));
+    DEBUG ((DEBUG_MANAGEABILITY, " - DeviceTypeInstance = %d\n", DevExtInfoRecord->DeviceTypeInstance));
+    DEBUG ((DEBUG_MANAGEABILITY, " - VendorId = %x\n", DevExtInfoRecord->VendorId));
+    DEBUG ((DEBUG_MANAGEABILITY, " - DeviceId = %x\n", DevExtInfoRecord->DeviceId));
+    DEBUG ((DEBUG_MANAGEABILITY, " - RefDesignationStr = %a\n", DevExtInfoRecord->RefDesignationStr));
+
+    Status = GetBusDeviceInfo (
+               &DevExtInfoRecord->VendorId,
+               &DevExtInfoRecord->DeviceId,
+               &DevExtInfoRecord->DeviceTypeInstance,
+               &SegmentNum,
+               &BusNum,
+               &DevNum,
+               &Functions,
+               &DeviceFound
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Could not get SBDF details for idx %d\n", DevIdx));
+      continue;
+    }
+
+    // Device not present
+    if (DeviceFound == 0) {
+      Status = EFI_NOT_FOUND;
+      DEBUG ((
+        DEBUG_ERROR,
+        "No onboard device found matching VendorId: %x DeviceId: %x\n",
+        DevExtInfoRecord->VendorId,
+        DevExtInfoRecord->DeviceId
+        ));
+      continue;
+    }
+
+    // Create one record for each function in a multi-function device
+    for (Idx = 0; Idx <= 7; Idx++) {
+      if ((Functions >> Idx) & 0x1) {
+        SmbiosRecord = NULL;
+        SmbiosRecord = AllocateZeroPool (
+                         sizeof (SMBIOS_TABLE_TYPE41) + RefDesStrLen + 1
+                         );
+        if (SmbiosRecord == NULL) {
+          Status = EFI_OUT_OF_RESOURCES;
+          return Status;
+        } else {
+          SmbiosRecord->Hdr.Type             = SMBIOS_TYPE_ONBOARD_DEVICES_EXTENDED_INFORMATION;
+          SmbiosRecord->Hdr.Length           = sizeof (SMBIOS_TABLE_TYPE41);
+          SmbiosRecord->Hdr.Handle           = 0;
+          SmbiosRecord->ReferenceDesignation = DevExtInfoRecord->ReferenceDesignation;
+          SmbiosRecord->DeviceType           = (DevExtInfoRecord->DeviceEnabled << 7) | DevExtInfoRecord->DeviceType;
+          SmbiosRecord->DeviceTypeInstance   = DevExtInfoRecord->DeviceTypeInstance;
+          SmbiosRecord->SegmentGroupNum      = SegmentNum;
+          SmbiosRecord->BusNum               = BusNum;
+          SmbiosRecord->DevFuncNum           = (DevNum << 3) + Idx;
+
+          // Add strings to bottom of data block
+          StringOffset = SmbiosRecord->Hdr.Length;
+          CopyMem (
+            (UINT8 *)SmbiosRecord + StringOffset,
+            RefDesStr,
+            RefDesStrLen
+            );
+          StringOffset += RefDesStrLen;
+
+          Status = AddCommonSmbiosRecord (
+                     Smbios,
+                     &SmbiosHandle,
+                     (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord
+                     );
+          FreePool (SmbiosRecord);
+        }
+      }
+    }
+
+    DevExtInfoRecord++;
+  }
+
+  return Status;
+}
+
+/**
+  This function gets the Bus, Device and Segment number of a PCI device when Vendor ID, Device ID and instance
+  are provided.
+
+  @param[in]  VendorId        Vendor ID of the PCI device to be provided.
+  @param[in]  DeviceId        Device ID of the PCI device to be provided
+  @param[in]  Instance        Instance of the PCI device. If more than one devices with same vendor
+                              and device ID is present, instance number is used.
+  @param[out]  Segment        Segment number of the PCI device is assigned.
+  @param[out]  Bus            Bus number of the PCI device is assigned.
+  @param[out]  Device         Device number of the PCI device is assigned.
+  @param[out]  Functions      Bits 0-7 of the Functions variable correspond to respective function numbers.
+  @param[out]  DeviceFound    Set to 1 if the device is found.
+
+  @retval EFI_SUCCESS         All parameters were valid.
+**/
+EFI_STATUS
+EFIAPI
+GetBusDeviceInfo (
+  IN  UINT16  *VendorId,
+  IN  UINT16  *DeviceId,
+  IN  UINT8   *Instance,
+  OUT UINT16  *Segment,
+  OUT UINT8   *Bus,
+  OUT UINT8   *Device,
+  OUT UINT8   *Functions,
+  OUT UINT8   *DeviceFound
+  )
+{
+  UINT16  SegIdx;
+  UINT8   BusIdx;
+  UINT16  BusIdx16;
+  UINT8   DevIdx;
+  UINT8   FuncIdx;
+  UINT8   InstanceCount;
+  UINT16  MaxSegments;
+  UINT8   BusRangeIdentifier;
+
+  InstanceCount = *Instance;
+  *DeviceFound  = 0;
+
+  BusRangeIdentifier = (AsmReadMsr64 (MSR_MMIO_CFG_BASE) >> 2) & 0xF;
+  if ( BusRangeIdentifier <= 0x8 ) {
+    MaxSegments = 1;
+  } else if ((BusRangeIdentifier >= 0x9) && (BusRangeIdentifier <= 0xF)) {
+    MaxSegments = 1 << (BusRangeIdentifier - 0x8);
+  }
+
+  for (SegIdx = 0; SegIdx < MaxSegments; SegIdx++ ) {
+    for (BusIdx16 = 0; BusIdx16 <= 255; BusIdx16++) {
+      BusIdx = (UINT8)BusIdx16;
+      for (DevIdx = 0; DevIdx < 32; DevIdx++) {
+        if ((PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SegIdx, BusIdx, DevIdx, 0, 2)) == *DeviceId) &&
+            (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SegIdx, BusIdx, DevIdx, 0, 0)) == *VendorId))
+        {
+          *DeviceFound = 1;
+          *Functions   = 0;
+          if (InstanceCount > 1) {
+            *DeviceFound = 0;
+            InstanceCount--;
+            continue;
+          } else {
+            *Bus        = BusIdx;
+            *Device     = DevIdx;
+            *Segment    = SegIdx;
+            *Functions |= 1;
+            for (FuncIdx = 1; FuncIdx < 8; FuncIdx++) {
+              if ((PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SegIdx, BusIdx, DevIdx, FuncIdx, 2)) == *DeviceId) &&
+                  (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SegIdx, BusIdx, DevIdx, FuncIdx, 0)) == *VendorId))
+              {
+                *Functions |= (1 << FuncIdx);
+              }
+            }
+
+            return EFI_SUCCESS;
+          }
+        }
+      }
+
+      if (BusIdx == 255) {
+        break;
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type8PortConnectorInfoFunction.c b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type8PortConnectorInfoFunction.c
new file mode 100644
index 0000000000..844529d1f0
--- /dev/null
+++ b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type8PortConnectorInfoFunction.c
@@ -0,0 +1,133 @@
+/** @file
+  AMD SMBIOS Type 8 Record
+
+  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Pcd/SmbiosPcd.h>
+#include "SmbiosCommon.h"
+
+/**
+  This function adds port connector information smbios record (Type 8).
+
+  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_OUT_OF_RESOURCES       Resource not available.
+**/
+EFI_STATUS
+EFIAPI
+PortConnectorInfoFunction (
+  IN EFI_SMBIOS_PROTOCOL  *Smbios
+  )
+{
+  EFI_STATUS                    Status;
+  EFI_SMBIOS_HANDLE             SmbiosHandle;
+  SMBIOS_TABLE_TYPE8            *SmbiosRecord;
+  SMBIOS_PORT_CONNECTOR_RECORD  *PortConnRecord;
+  UINT8                         PortIdx;
+  UINT8                         NumberOfPortConnector;
+  UINTN                         StringOffset;
+  CHAR8                         *IntPortConDesStr;
+  UINTN                         IntPortConDesStrLen;
+  CHAR8                         *ExtPortConDesStr;
+  UINTN                         ExtPortConDesStrLen;
+
+  if (Smbios == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Get the total number of port connectors.
+  NumberOfPortConnector = PcdGet8 (PcdAmdSmbiosType8Number);
+  DEBUG ((DEBUG_INFO, "%a: Total number of AMD SMBIOS type8 PCD structure %d.\n", __func__, NumberOfPortConnector));
+  PortConnRecord = (SMBIOS_PORT_CONNECTOR_RECORD *)PcdGetPtr (PcdAmdSmbiosType8);
+
+  if (NumberOfPortConnector == 0) {
+    DEBUG ((DEBUG_INFO, "No port connectors found.\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  // Generate type8 smbios record for each connector and add it to Smbios table.
+  for (PortIdx = 0; PortIdx < NumberOfPortConnector; PortIdx++) {
+    DEBUG ((DEBUG_MANAGEABILITY, "Port %d:\n", PortIdx));
+    // Check whether Port connector designator strings are present or not.
+    if (PortConnRecord->Type8Data.InternalReferenceDesignator != 0) {
+      IntPortConDesStr    = PortConnRecord->DesinatorStr.IntDesignatorStr;
+      IntPortConDesStrLen = AsciiStrLen (IntPortConDesStr) + 1;
+      DEBUG ((DEBUG_MANAGEABILITY, "-- DesinatorStr.IntDesignatorStr = %a\n", IntPortConDesStr));
+    } else {
+      IntPortConDesStr    = NULL;
+      IntPortConDesStrLen = 0;
+    }
+
+    if (PortConnRecord->Type8Data.ExternalReferenceDesignator != 0) {
+      ExtPortConDesStr    = PortConnRecord->DesinatorStr.ExtDesignatorStr;
+      ExtPortConDesStrLen = AsciiStrLen (ExtPortConDesStr) + 1;
+      DEBUG ((DEBUG_MANAGEABILITY, "-- DesinatorStr.ExtDesignatorStr = %a\n", ExtPortConDesStr));
+    } else {
+      ExtPortConDesStr    = NULL;
+      ExtPortConDesStrLen = 0;
+    }
+
+    SmbiosRecord = NULL;
+    SmbiosRecord = AllocateZeroPool (
+                     sizeof (SMBIOS_TABLE_TYPE8) + IntPortConDesStrLen + ExtPortConDesStrLen + 1
+                     );
+
+    if (SmbiosRecord == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      return Status;
+    } else {
+      SmbiosRecord->Hdr.Type   = SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION;
+      SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE8);
+      SmbiosRecord->Hdr.Handle = 0;
+
+      SmbiosRecord->InternalReferenceDesignator =
+        PortConnRecord->Type8Data.InternalReferenceDesignator;
+      SmbiosRecord->InternalConnectorType =
+        PortConnRecord->Type8Data.InternalConnectorType;
+      SmbiosRecord->ExternalReferenceDesignator =
+        PortConnRecord->Type8Data.ExternalReferenceDesignator;
+      SmbiosRecord->ExternalConnectorType =
+        PortConnRecord->Type8Data.ExternalConnectorType;
+      SmbiosRecord->PortType =
+        PortConnRecord->Type8Data.PortType;
+      DEBUG ((DEBUG_MANAGEABILITY, " - InternalReferenceDesignator = %d\n", SmbiosRecord->InternalReferenceDesignator));
+      DEBUG ((DEBUG_MANAGEABILITY, " - InternalConnectorType = %d\n", SmbiosRecord->InternalConnectorType));
+      DEBUG ((DEBUG_MANAGEABILITY, " - ExternalReferenceDesignator = %d\n", SmbiosRecord->ExternalReferenceDesignator));
+      DEBUG ((DEBUG_MANAGEABILITY, " - ExternalConnectorType = %d\n", SmbiosRecord->ExternalConnectorType));
+      DEBUG ((DEBUG_MANAGEABILITY, " - PortType = %d\n", SmbiosRecord->PortType));
+
+      // Add strings to bottom of data block
+      StringOffset = SmbiosRecord->Hdr.Length;
+      if (IntPortConDesStr != NULL) {
+        CopyMem (
+          (UINT8 *)SmbiosRecord + StringOffset,
+          IntPortConDesStr,
+          IntPortConDesStrLen
+          );
+        StringOffset += IntPortConDesStrLen;
+      }
+
+      if (ExtPortConDesStr != NULL) {
+        CopyMem (
+          (UINT8 *)SmbiosRecord + StringOffset,
+          ExtPortConDesStr,
+          ExtPortConDesStrLen
+          );
+      }
+
+      Status = AddCommonSmbiosRecord (
+                 Smbios,
+                 &SmbiosHandle,
+                 (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord
+                 );
+      FreePool (SmbiosRecord);
+    }
+
+    PortConnRecord++;
+  }
+
+  return Status;
+}
diff --git a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type9SystemSlotInfoFunction.c b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type9SystemSlotInfoFunction.c
new file mode 100644
index 0000000000..568f44b427
--- /dev/null
+++ b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type9SystemSlotInfoFunction.c
@@ -0,0 +1,94 @@
+/** @file
+  AMD SMBIOS Type 9 Record
+
+  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#include <Library/PrintLib.h>
+#include "SmbiosCommon.h"
+#include <Library/AmdPlatformSocLib.h>
+
+/**
+  This function checks for system slot info and adds smbios record (Type 9).
+
+  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
+
+  @retval EFI_SUCCESS                All parameters were valid.
+  @retval EFI_OUT_OF_RESOURCES       Resource not available.
+
+**/
+EFI_STATUS
+EFIAPI
+SystemSlotInfoFunction (
+  IN  EFI_SMBIOS_PROTOCOL  *Smbios
+  )
+{
+  EFI_STATUS                   Status;
+  EFI_SMBIOS_HANDLE            SmbiosHandle;
+  SMBIOS_TABLE_TYPE9           *SmbiosRecord;
+  UINTN                        SystemSlotCount;
+  SMBIOS_TABLE_TYPE9           *SystemSlotInfo;
+  UINTN                        Index;
+  CHAR8                        SlotDesignationStr[SMBIOS_STRING_MAX_LENGTH];
+  SMBIOS_TABLE_TYPE9_EXTENDED  SmbiosRecordExtended;
+  UINTN                        SlotDesStrLen;
+  UINTN                        TotalSize;
+
+  if (Smbios == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  SystemSlotInfo  = NULL;
+  SystemSlotCount = 0;
+  // Invoke GetSystemSlotInfo function to get the number of system slots.
+  Status = GetSystemSlotInfo (&SystemSlotInfo, &SystemSlotCount);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  for (Index = 0; Index < SystemSlotCount; Index++) {
+    SlotDesStrLen = AsciiSPrint (
+                      SlotDesignationStr,
+                      SMBIOS_STRING_MAX_LENGTH,
+                      "PCIE-%d",
+                      SystemSlotInfo[Index].SlotID
+                      );
+    // Two zeros following the last string.
+    TotalSize    = sizeof (SMBIOS_TABLE_TYPE9) + sizeof (SMBIOS_TABLE_TYPE9_EXTENDED) + SlotDesStrLen + 2;
+    SmbiosRecord = NULL;
+    SmbiosRecord = AllocateZeroPool (TotalSize);
+    if (SmbiosRecord == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+    } else {
+      CopyMem (SmbiosRecord, &SystemSlotInfo[Index], sizeof (SMBIOS_TABLE_TYPE9));
+      SmbiosRecord->Hdr.Type                 = SMBIOS_TYPE_SYSTEM_SLOTS;
+      SmbiosRecord->Hdr.Length               = sizeof (SMBIOS_TABLE_TYPE9) + sizeof (SMBIOS_TABLE_TYPE9_EXTENDED);
+      SmbiosRecord->Hdr.Handle               = 0;
+      SmbiosRecord->SlotDesignation          = 1;
+      SmbiosRecordExtended.SlotHeight        = SlotHeightUnknown;
+      SmbiosRecordExtended.SlotPitch         = 0;
+      SmbiosRecordExtended.SlotPhysicalWidth = SmbiosRecord->SlotDataBusWidth;
+      CopyMem (&SmbiosRecord->SlotCharacteristics1, PcdGetPtr (PcdAmdSmbiosType9SlotCharacteristics1), sizeof (MISC_SLOT_CHARACTERISTICS1));
+      CopyMem (&SmbiosRecord->SlotCharacteristics2, PcdGetPtr (PcdAmdSmbiosType9SlotCharacteristics2), sizeof (MISC_SLOT_CHARACTERISTICS2));
+      CopyMem ((UINT8 *)SmbiosRecord->PeerGroups + SmbiosRecord->PeerGroupingCount * sizeof (SmbiosRecord->PeerGroups), (UINT8 *)&SmbiosRecordExtended, sizeof (SMBIOS_TABLE_TYPE9_EXTENDED));
+      CopyMem ((UINT8 *)SmbiosRecord + SmbiosRecord->Hdr.Length, SlotDesignationStr, SlotDesStrLen);
+      Status = AddCommonSmbiosRecord (
+                 Smbios,
+                 &SmbiosHandle,
+                 (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord
+                 );
+      if (EFI_ERROR (Status)) {
+        FreePool (SmbiosRecord);
+        break;
+      }
+
+      if (SmbiosRecord != NULL) {
+        FreePool (SmbiosRecord);
+      }
+    }
+  }
+
+  FreePool (SystemSlotInfo);
+  return EFI_SUCCESS;
+}
-- 
2.34.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119080): https://edk2.groups.io/g/devel/message/119080
Mute This Topic: https://groups.io/mt/106200547/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [edk2-devel] [edk2-platforms] AmdPlatformPkg: Adds SmbiosCommonDxe driver
  2024-05-20 10:23 [edk2-devel] [edk2-platforms] AmdPlatformPkg: Adds SmbiosCommonDxe driver Abdul Lateef Attar via groups.io
@ 2024-05-20 11:00 ` Chang, Abner via groups.io
  0 siblings, 0 replies; 2+ messages in thread
From: Chang, Abner via groups.io @ 2024-05-20 11:00 UTC (permalink / raw)
  To: Attar, AbdulLateef (Abdul Lateef), devel@edk2.groups.io
  Cc: Attar, AbdulLateef (Abdul Lateef), Grimes, Paul

[AMD Official Use Only - AMD Internal Distribution Only]

Already reviewed internally.
Reviewed-by: Abner Chang <abner.chang@amd.com>

> -----Original Message-----
> From: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
> Sent: Monday, May 20, 2024 6:24 PM
> To: devel@edk2.groups.io
> Cc: Attar, AbdulLateef (Abdul Lateef) <AbdulLateef.Attar@amd.com>; Chang,
> Abner <Abner.Chang@amd.com>; Grimes, Paul <Paul.Grimes@amd.com>
> Subject: [edk2-platforms] AmdPlatformPkg: Adds SmbiosCommonDxe driver
>
> Adds SMBIOS common driver which generates various
> tables for AMD platforms.
>
> Cc: Abner Chang <abner.chang@amd.com>
> Cc: Paul Grimes <paul.grimes@amd.com>
> Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
> ---
>  .../AMD/AmdPlatformPkg/AmdPlatformPkg.dec     |  63 ++++-
>  .../AMD/AmdPlatformPkg/AmdPlatformPkg.dsc     |   3 +-
>  .../SmbiosCommonDxe/DefaultLomDevicePath.c    | 130 ++++++++++
>  .../Universal/SmbiosCommonDxe/SmbiosCommon.h  | 210
> ++++++++++++++++
>  .../SmbiosCommonDxe/SmbiosCommonDxe.inf       |  76 ++++++
>  .../SmbiosCommonDxe/SmbiosCommonEntryPoint.c  | 148 +++++++++++
>  .../Type11OemStringsFunction.c                |  91 +++++++
>  .../Type12SystemCfgOptionsFunction.c          |  90 +++++++
>  .../Type13BiosLanguageInfoFunction.c          | 146 +++++++++++
>  .../Type38IpmiDeviceInformation.c             |  70 ++++++
>  .../Type41OnboardDevExtInfoFunction.c         | 237 ++++++++++++++++++
>  .../Type8PortConnectorInfoFunction.c          | 133 ++++++++++
>  .../Type9SystemSlotInfoFunction.c             |  94 +++++++
>  13 files changed, 1489 insertions(+), 2 deletions(-)
>  create mode 100644
> Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/DefaultLom
> DevicePath.c
>  create mode 100644
> Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCom
> mon.h
>  create mode 100644
> Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCom
> monDxe.inf
>  create mode 100644
> Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCom
> monEntryPoint.c
>  create mode 100644
> Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type11Oem
> StringsFunction.c
>  create mode 100644
> Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type12Syste
> mCfgOptionsFunction.c
>  create mode 100644
> Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type13BiosL
> anguageInfoFunction.c
>  create mode 100644
> Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type38Ipmi
> DeviceInformation.c
>  create mode 100644
> Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type41Onb
> oardDevExtInfoFunction.c
>  create mode 100644
> Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type8PortC
> onnectorInfoFunction.c
>  create mode 100644
> Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type9Syste
> mSlotInfoFunction.c
>
> diff --git a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dec
> b/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dec
> index 83f57f6d0a..787dac4cca 100644
> --- a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dec
> +++ b/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dec
> @@ -8,7 +8,7 @@
>  #
>  ##
>
> -[Defines]
> +[Defines]
>    DEC_SPECIFICATION = 1.27
>    PACKAGE_NAME      = AmdPlatformPkg
>    PACKAGE_GUID      = 2CB1238B-18E2-4837-B714-9DAB2B30A3C2
> @@ -42,3 +42,64 @@
>    # 3 - BT
>    # 4 - SSIF
>
> gAmdPlatformPkgTokenSpaceGuid.PcdIpmiInterfaceType|0|UINT8|0x00020
> 001
> +
> +  #
> +  # This PCD is mapped to AMD SMBIOS type 8 record structure
> +  #
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType8Number|0|UINT8|0
> x00020002
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType8|{0x0}|SMBIOS_PO
> RT_CONNECTOR_RECORD_ARRAY|0x00020003 {
> +  <HeaderFiles>
> +    Pcd/SmbiosPcd.h
> +  <Packages>
> +    AmdPlatformPkg/AmdPlatformPkg.dec
> +    MdePkg/MdePkg.dec
> +    MdeModulePkg/MdeModulePkg.dec
> +  }
> +
> +  #
> +  # This PCD is mapped to AMD SMBIOS type 41 record structure
> +  #
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType41Number|0|UINT8|
> 0x00020004
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType41|{0x0}|SMBIOS_O
> NBOARD_DEV_EXT_INFO_ARRAY|0x00020005 {
> +  <HeaderFiles>
> +    Pcd/SmbiosPcd.h
> +  <Packages>
> +    AmdPlatformPkg/AmdPlatformPkg.dec
> +    MdePkg/MdePkg.dec
> +    MdeModulePkg/MdeModulePkg.dec
> +  }
> +
> +  #
> +  # These PCDs are mapped to AMD SMBIOS type 9 record structure
> +  #
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1|
> {0x0}|MISC_SLOT_CHARACTERISTICS1|0x00020009 {
> +  <HeaderFiles>
> +    IndustryStandard/SmBios.h
> +  }
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.
> CharacteristicsUnknown|0
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.
> Provides50Volts|0
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.
> Provides33Volts|1
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.
> SharedSlot|0
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.
> PcCard16Supported|0
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.
> CardBusSupported|0
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.
> ZoomVideoSupported|0
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1.
> ModemRingResumeSupported|0
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2|
> {0x0}|MISC_SLOT_CHARACTERISTICS2|0x0002000A {
> +  <HeaderFiles>
> +    IndustryStandard/SmBios.h
> +  }
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.
> PmeSignalSupported|0
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.
> HotPlugDevicesSupported|0
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.
> SmbusSignalSupported|0
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.
> BifurcationSupported|1
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.
> AsyncSurpriseRemoval|0
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.
> FlexbusSlotCxl10Capable|0
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.
> FlexbusSlotCxl20Capable|0
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2.
> Reserved|0
> +
> +[PcdsDynamic, PcdsDynamicEx]
> +  # SMBIOS
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdType11OemStringsCount|0|UINT8|0x
> 00030001
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdType11OemStrings|NULL|VOID*|0x00
> 030002
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdType12SystemCfgOptionsCount|0|UI
> NT8|0x00030003
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdType12SystemCfgOptions|NULL|VOID
> *|0x00030004
> diff --git a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc
> b/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc
> index 99dd5b341f..d11d3594e3 100644
> --- a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc
> +++ b/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc
> @@ -71,4 +71,5 @@
>    AmdPlatformPkg/Universal/HiiConfigRouting/AmdConfigRouting.inf
>    AmdPlatformPkg/Universal/LogoDxe/JpegLogoDxe.inf
> # Server platform JPEG logo driver
>    AmdPlatformPkg/Universal/LogoDxe/LogoDxe.inf                                               #
> Server platfrom Bitmap logo driver
> -  AmdPlatformPkg/Universal/LogoDxe/S3LogoDxe.inf
> \ No newline at end of file
> +  AmdPlatformPkg/Universal/LogoDxe/S3LogoDxe.inf
> +  AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCommonDxe.inf
> diff --git
> a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/DefaultLo
> mDevicePath.c
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/DefaultLo
> mDevicePath.c
> new file mode 100644
> index 0000000000..92c7aa5e07
> --- /dev/null
> +++
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/DefaultLo
> mDevicePath.c
> @@ -0,0 +1,130 @@
> +/** @file
> +  This file contains the implementation of the DefaultLomDevicePath protocol.
> +  The DefaultLomDevicePath protocol is used to identify the default LOM
> device
> +  path for the system. The protocol is installed by the SmbiosCommonDxe
> driver
> +  and is used by the BDS to identify the default LOM device path for the
> system.
> +
> +  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Library/IoLib.h>
> +#include <Library/PciLib.h>
> +#include <Protocol/PciEnumerationComplete.h>
> +#include <IndustryStandard/Ipmi.h>
> +#include <Bus/Pci/PciBusDxe/PciBus.h>
> +#include <Pcd/SmbiosPcd.h>
> +#include <Library/PciSegmentLib.h>
> +#include <Pcd/SmbiosPcd.h>
> +#include "SmbiosCommon.h"
> +#include <IndustryStandard/Ipmi.h>
> +#include <Library/BoardBdsHookLib.h>
> +
> +EFI_HANDLE                                mBoardBdsHandle = NULL;
> +BOARD_BDS_BOOT_FROM_DEVICE_PATH_PROTOCOL
> mBootDevicePathProtocol;
> +
> +/**
> +  Find the Lan-On-Motherboard device path. Installs
> BOARD_BDS_BOOT_FROM_DEVICE_PATH_PROTOCOL
> +  with the LOM device path protocol
> +
> +  @retval EFI NOT_FOUND         LOM device path is not found
> +  @retval EFI_SUCCESS           LOM device path found
> +**/
> +EFI_STATUS
> +EFIAPI
> +InstallLomDevicePath (
> +  )
> +{
> +  SMBIOS_ONBOARD_DEV_EXT_INFO_RECORD  *DevExtInfoRecord;
> +  EFI_STATUS                          Status;
> +  EFI_HANDLE                          *PciHandles;
> +  UINTN                               PciHandlesSize;
> +  UINTN                               Index;
> +  EFI_PCI_IO_PROTOCOL                 *PciProtocol;
> +  PCI_IO_DEVICE                       *PciIoDevice;
> +  UINT8                               NumberOfDevices;
> +  UINT8                               DevIdx;
> +  UINTN                               SegmentNumber;
> +  UINTN                               BusNumber;
> +  UINTN                               DeviceNumber;
> +  UINTN                               FunctionNumber;
> +
> +  NumberOfDevices  = PcdGet8 (PcdAmdSmbiosType41Number);
> +  DevExtInfoRecord = (SMBIOS_ONBOARD_DEV_EXT_INFO_RECORD
> *)PcdGetPtr (PcdAmdSmbiosType41);
> +
> +  // No device entries found
> +  if (NumberOfDevices == 0) {
> +    DEBUG ((DEBUG_INFO, "No onboard devices found.\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  // search through present on board devices, look for onboard ethernet
> +  for (DevIdx = 0; DevIdx < NumberOfDevices; DevIdx++) {
> +    if (AsciiStrCmp (DevExtInfoRecord->RefDesignationStr, "Onboard
> Ethernet") == 0) {
> +      break;
> +    }
> +
> +    DevExtInfoRecord++;
> +  }
> +
> +  // edge case, no Onboard Ethernet designator
> +  if (AsciiStrCmp (DevExtInfoRecord->RefDesignationStr, "Onboard
> Ethernet") != 0) {
> +    DEBUG ((DEBUG_INFO, "No Onboard ethernet SMBIOS designator
> found!\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiPciIoProtocolGuid,
> +                  NULL,
> +                  &PciHandlesSize,
> +                  &PciHandles
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "Can't locate gEfiPciIoProtocolGuid Protocol: Status
> = %r\n\n", Status));
> +    return Status;
> +  }
> +
> +  for (Index = 0; Index < PciHandlesSize; Index++) {
> +    Status = gBS->HandleProtocol (
> +                    PciHandles[Index],
> +                    &gEfiPciIoProtocolGuid,
> +                    (VOID **)&PciProtocol
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_INFO, "ERROR - Status = %r when locating
> PciIoProtocol\n", Status));
> +      continue;
> +    }
> +
> +    PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciProtocol);
> +    Status      = PciIoDevice->PciIo.GetLocation (&PciIoDevice->PciIo,
> &SegmentNumber, &BusNumber, &DeviceNumber, &FunctionNumber);
> +
> +    if ((PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SegmentNumber,
> BusNumber, DeviceNumber, FunctionNumber, 2)) == DevExtInfoRecord-
> >DeviceId) &&
> +        (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SegmentNumber,
> BusNumber, DeviceNumber, FunctionNumber, 0)) == DevExtInfoRecord-
> >VendorId))
> +    {
> +      // Making Lan0 default for systems with two LANs
> +      if (FunctionNumber == 0) {
> +        DEBUG ((DEBUG_INFO, "Found Onboard Device with DeviceID=0x%X,
> VendorID=0x%X\n", DevExtInfoRecord->DeviceId, DevExtInfoRecord-
> >VendorId));
> +        Status = EFI_SUCCESS;
> +        // install device path protocol here
> +        mBootDevicePathProtocol.Device                     = PciIoDevice->DevicePath;
> +        mBootDevicePathProtocol.IpmiBootDeviceSelectorType =
> IPMI_BOOT_DEVICE_SELECTOR_PXE;
> +        Status                                             = gBS->InstallProtocolInterface (
> +                                                                    &mBoardBdsHandle,
> +
> &gBoardBdsBootFromDevicePathProtocolGuid,
> +                                                                    EFI_NATIVE_INTERFACE,
> +                                                                    &mBootDevicePathProtocol
> +                                                                    );
> +        if (!EFI_ERROR (Status)) {
> +          DEBUG ((DEBUG_INFO, "BoardBdsBootFromDevicePathProtocol
> installed successfully\n"));
> +        }
> +
> +        break;
> +      }
> +    }
> +  }
> +
> +  return Status;
> +}
> diff --git
> a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCo
> mmon.h
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCo
> mmon.h
> new file mode 100644
> index 0000000000..770053e42b
> --- /dev/null
> +++
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCo
> mmon.h
> @@ -0,0 +1,210 @@
> +/** @file
> +  AMD Smbios common header file.
> +
> +  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef SMBIOS_COMMON_DRIVER_H_
> +#define SMBIOS_COMMON_DRIVER_H_
> +
> +#include <PiDxe.h>
> +#include <Protocol/Smbios.h>
> +#include <IndustryStandard/SmBios.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/PciSegmentLib.h>
> +
> +/**
> +  Add an SMBIOS record.
> +
> +  @param[in]  Smbios                The EFI_SMBIOS_PROTOCOL instance.
> +  @param[out] SmbiosHandle          A unique handle will be assigned to the
> SMBIOS record.
> +  @param[in]  Record                The data for the fixed portion of the SMBIOS
> record. The format of the record is
> +                                determined by EFI_SMBIOS_TABLE_HEADER.Type. The size of
> the formatted area is defined
> +                                by EFI_SMBIOS_TABLE_HEADER.Length and either followed
> by a double-null (0x0000) or
> +                                a set of null terminated strings and a null.
> +
> +  @retval EFI_SUCCESS           Record was added.
> +  @retval EFI_OUT_OF_RESOURCES  Record was not added due to lack of
> system resources.
> +
> +**/
> +EFI_STATUS
> +AddCommonSmbiosRecord (
> +  IN EFI_SMBIOS_PROTOCOL      *Smbios,
> +  OUT EFI_SMBIOS_HANDLE       *SmbiosHandle,
> +  IN EFI_SMBIOS_TABLE_HEADER  *Record
> +  );
> +
> +/**
> +  This function gets the Bus, Device and Segment number of a PCI device
> when Vendor ID, Device ID and instance
> +  are provided.
> +
> +  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
> +  @param[in]  VendorId                   Vendor ID of the PCI device to be provided.
> +  @param[in]  DeviceId                   Device ID of the PCI device to be provided
> +  @param[out]  Instance                   Instance of the PCI device. If more than
> one devices with same vendor
> +                                     and device ID is present, instance number is used.
> +  @param[out]  Segment                    Segment number of the PCI device is
> assigned.
> +  @param[out]  Bus                        Bus number of the PCI device is assigned.
> +  @param[out]  Device                     Device number of the PCI device is assigned.
> +  @param[out]  Functions                  Bits 0-7 of the Functions variable
> correspond to respective function numbers.
> +  @param[out]  DeviceFound                Set to 1 if the device is found.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetBusDeviceInfo (
> +  IN  UINT16  *VendorId,
> +  IN  UINT16  *DeviceId,
> +  IN  UINT8   *Instance,
> +  OUT UINT16  *Segment,
> +  OUT UINT8   *Bus,
> +  OUT UINT8   *Device,
> +  OUT UINT8   *Functions,
> +  OUT UINT8   *DeviceFound
> +  );
> +
> +/**
> +  PciEnumerationComplete Protocol notification event handler.
> +
> +  @param[in] Event    Event whose notification function is being invoked.
> +  @param[in] Context  Pointer to the notification function's context.
> +**/
> +VOID
> +EFIAPI
> +OnPciEnumerationComplete (
> +  IN EFI_EVENT  Event,
> +  IN VOID       *Context
> +  );
> +
> +/**
> +  This function updates IPMI Device information changes to the contents of
> the
> +  Table Type 38.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +**/
> +EFI_STATUS
> +EFIAPI
> +IpmiDeviceInformation (
> +  IN  EFI_SMBIOS_PROTOCOL  *Smbios
> +  );
> +
> +/**
> +  This function checks for system slot info and adds smbios record (Type 9).
> +
> +  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_OUT_OF_RESOURCES       Resource not available.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SystemSlotInfoFunction (
> +  IN  EFI_SMBIOS_PROTOCOL  *Smbios
> +  );
> +
> +/**
> +  This function adds port connector information smbios record (Type 8).
> +
> +  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_OUT_OF_RESOURCES       Resource not available.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PortConnectorInfoFunction (
> +  IN  EFI_SMBIOS_PROTOCOL  *Smbios
> +  );
> +
> +/**
> +  This function adds OEM strings smbios record (Type 11).
> +
> +  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_OUT_OF_RESOURCES       Resource not available.
> +**/
> +EFI_STATUS
> +EFIAPI
> +OemStringsFunction (
> +  IN EFI_SMBIOS_PROTOCOL  *Smbios
> +  );
> +
> +/**
> +  This function adds System Configuration Options record (Type 12).
> +
> +  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_OUT_OF_RESOURCES       Resource not available.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SystemCfgOptionsFunction (
> +  IN EFI_SMBIOS_PROTOCOL  *Smbios
> +  );
> +
> +/**
> +  This function adds bios language information smbios record (Type 13).
> +
> +  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_OUT_OF_RESOURCES       Resource not available.
> +  @retval EFI_NOT_FOUND              Not able to locate PlatformLanguage.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BiosLanguageInfoFunction (
> +  IN  EFI_SMBIOS_PROTOCOL  *Smbios
> +  );
> +
> +/**
> +  This function adds onboard devices extended information smbios record
> (Type 41).
> +
> +  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_OUT_OF_RESOURCES       Resource not available.
> +**/
> +EFI_STATUS
> +EFIAPI
> +OnboardDevExtInfoFunction (
> +  IN EFI_SMBIOS_PROTOCOL  *Smbios
> +  );
> +
> +/**
> +  Find the Lan-On-Motherboard device path. Installs
> BOARD_BDS_BOOT_FROM_DEVICE_PATH_PROTOCOL
> +  with the LOM device path protocol
> +
> +  @retval EFI NOT_FOUND         LOM device path is not found
> +  @retval EFI_SUCCESS           LOM device path found
> +**/
> +EFI_STATUS
> +EFIAPI
> +InstallLomDevicePath (
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI EFI_COMMON_SMBIOS_DATA_FUNCTION)(
> +  IN  EFI_SMBIOS_PROTOCOL  *Smbios
> +  );
> +
> +typedef struct {
> +  EFI_COMMON_SMBIOS_DATA_FUNCTION    *Function;
> +} EFI_COMMON_SMBIOS_DATA;
> +#endif // SMBIOS_COMMON_DRIVER_H_
> diff --git
> a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCo
> mmonDxe.inf
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCo
> mmonDxe.inf
> new file mode 100644
> index 0000000000..e3d296192c
> --- /dev/null
> +++
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCo
> mmonDxe.inf
> @@ -0,0 +1,76 @@
> +## @file
> +#  AMD common SMBIOS DXE library Description File
> +#
> +#  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = SmbiosCommonDxe
> +  FILE_GUID                      = 2546E2B4-8629-47C3-A294-91E244936CBE
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = SmbiosCommonEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  SmbiosCommon.h
> +  SmbiosCommonEntryPoint.c
> +  Type38IpmiDeviceInformation.c
> +  Type9SystemSlotInfoFunction.c
> +  Type8PortConnectorInfoFunction.c
> +  Type11OemStringsFunction.c
> +  Type12SystemCfgOptionsFunction.c
> +  Type13BiosLanguageInfoFunction.c
> +  Type41OnboardDevExtInfoFunction.c
> +  DefaultLomDevicePath.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  AmdPlatformPkg/AmdPlatformPkg.dec
> +  BoardModulePkg/BoardModulePkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  DevicePathLib
> +  HobLib
> +  MemoryAllocationLib
> +  PcdLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +  PlatformSocLib
> +
> +[Protocols]
> +  gEfiSmbiosProtocolGuid                       ## PROTOCOL ALWAYS_CONSUMED
> +  gEfiPciEnumerationCompleteProtocolGuid       ## CONSUMES
> +  gEfiPciIoProtocolGuid                        ## CONSUMES
> +  gBoardBdsBootFromDevicePathProtocolGuid      ## PRODUCES
> +
> +[Pcd]
> +  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType8                       ##
> CONSUMES
> +  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType8Number
> ## CONSUMES
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics1
> ## CONSUMES
> +
> gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType9SlotCharacteristics2
> ## CONSUMES
> +  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType41                      ##
> CONSUMES
> +  gAmdPlatformPkgTokenSpaceGuid.PcdAmdSmbiosType41Number
> ## CONSUMES
> +  gAmdPlatformPkgTokenSpaceGuid.PcdIpmiInterfaceType                    ##
> CONSUMES
> +  gAmdPlatformPkgTokenSpaceGuid.PcdType11OemStringsCount                ##
> CONSUMES
> +  gAmdPlatformPkgTokenSpaceGuid.PcdType11OemStrings                     ##
> CONSUMES
> +  gAmdPlatformPkgTokenSpaceGuid.PcdType12SystemCfgOptionsCount
> ## CONSUMES
> +  gAmdPlatformPkgTokenSpaceGuid.PcdType12SystemCfgOptions               ##
> CONSUMES
> +  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLangCodes
> ## CONSUMES
> +  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang           ##
> CONSUMES
> +  gEfiMdePkgTokenSpaceGuid.PcdIpmiKcsIoBaseAddress                      ##
> CONSUMES
> +
> +[Depex]
> +  gEfiSmbiosProtocolGuid
> diff --git
> a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCo
> mmonEntryPoint.c
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCo
> mmonEntryPoint.c
> new file mode 100644
> index 0000000000..eaa66be454
> --- /dev/null
> +++
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/SmbiosCo
> mmonEntryPoint.c
> @@ -0,0 +1,148 @@
> +/** @file
> +  AMD Smbios Common DXE entry point.
> +
> +  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +#include "SmbiosCommon.h"
> +
> +EFI_COMMON_SMBIOS_DATA  mSmbiosCommonDataFuncTable[] = {
> +  { &IpmiDeviceInformation     },
> +  { &SystemSlotInfoFunction    },
> +  { &PortConnectorInfoFunction },
> +  { &OemStringsFunction        },
> +  { &SystemCfgOptionsFunction  },
> +  { &BiosLanguageInfoFunction  }
> +};
> +
> +/**
> +  Add an SMBIOS record.
> +
> +  @param  Smbios                The EFI_SMBIOS_PROTOCOL instance.
> +  @param  SmbiosHandle          A unique handle will be assigned to the
> SMBIOS record.
> +  @param  Record                The data for the fixed portion of the SMBIOS
> record. The format of the record is
> +                                determined by EFI_SMBIOS_TABLE_HEADER.Type. The size of
> the formatted area is defined
> +                                by EFI_SMBIOS_TABLE_HEADER.Length and either followed
> by a double-null (0x0000) or
> +                                a set of null terminated strings and a null.
> +
> +  @retval EFI_SUCCESS           Record was added.
> +  @retval EFI_OUT_OF_RESOURCES  Record was not added due to lack of
> system resources.
> +
> +**/
> +EFI_STATUS
> +AddCommonSmbiosRecord (
> +  IN EFI_SMBIOS_PROTOCOL      *Smbios,
> +  OUT EFI_SMBIOS_HANDLE       *SmbiosHandle,
> +  IN EFI_SMBIOS_TABLE_HEADER  *Record
> +  )
> +{
> +  *SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
> +  return Smbios->Add (
> +                   Smbios,
> +                   NULL,
> +                   SmbiosHandle,
> +                   Record
> +                   );
> +}
> +
> +/**
> +  PciEnumerationComplete Protocol notification event handler.
> +
> +  @param[in] Event    Event whose notification function is being invoked.
> +  @param[in] Context  Pointer to the notification function's context.
> +**/
> +VOID
> +EFIAPI
> +OnPciEnumerationComplete (
> +  IN EFI_EVENT  Event,
> +  IN VOID       *Context
> +  )
> +{
> +  EFI_STATUS           EfiStatus;
> +  EFI_SMBIOS_PROTOCOL  *Smbios;
> +
> +  EfiStatus = gBS->LocateProtocol (
> +                     &gEfiSmbiosProtocolGuid,
> +                     NULL,
> +                     (VOID **)&Smbios
> +                     );
> +  if (EFI_ERROR (EfiStatus)) {
> +    DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol.  %r\n",
> EfiStatus));
> +  }
> +
> +  // Install Type 41 when PCI enumeration is complete
> +  EfiStatus = OnboardDevExtInfoFunction (Smbios);
> +  if (EFI_ERROR (EfiStatus)) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "Skip installing SMBIOS Table 41, ReturnStatus=%r\n",
> +      EfiStatus
> +      ));
> +  }
> +
> +  EfiStatus = InstallLomDevicePath ();
> +}
> +
> +/**
> +  EFI driver entry point. This driver parses mSmbiosCommonDataFuncTable
> +  structure and generates common platform smbios records.
> +
> +  @param  ImageHandle     Handle for the image of this driver
> +  @param  SystemTable     Pointer to the EFI System Table
> +
> +  @retval  EFI_SUCCESS    The data was successfully stored.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmbiosCommonEntryPoint (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  UINTN                Index;
> +  EFI_STATUS           EfiStatus;
> +  EFI_SMBIOS_PROTOCOL  *Smbios;
> +  EFI_EVENT            ProtocolNotifyEvent;
> +  VOID                 *Registration;
> +
> +  DEBUG ((DEBUG_INFO, "%a: Entry.\n", __func__));
> +
> +  EfiStatus = gBS->LocateProtocol (
> +                     &gEfiSmbiosProtocolGuid,
> +                     NULL,
> +                     (VOID **)&Smbios
> +                     );
> +  if (EFI_ERROR (EfiStatus)) {
> +    DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol.  %r\n",
> EfiStatus));
> +    return EfiStatus;
> +  }
> +
> +  ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent (
> +                          &gEfiPciEnumerationCompleteProtocolGuid,
> +                          TPL_CALLBACK,
> +                          OnPciEnumerationComplete,
> +                          NULL,
> +                          &Registration
> +                          );
> +  if (ProtocolNotifyEvent == NULL) {
> +    DEBUG ((DEBUG_ERROR, "Could not create PCI enumeration complete
> event\n"));
> +  }
> +
> +  for (Index = 0; Index < sizeof (mSmbiosCommonDataFuncTable)/sizeof
> (mSmbiosCommonDataFuncTable[0]); ++Index) {
> +    EfiStatus = (*mSmbiosCommonDataFuncTable[Index].Function)(Smbios);
> +    if (EFI_ERROR (EfiStatus)) {
> +      // Continue installing remaining tables if one table fails.
> +      DEBUG ((
> +        DEBUG_ERROR,
> +        "Skip installing SMBIOS Table Index=%d, ReturnStatus=%r\n",
> +        Index,
> +        EfiStatus
> +        ));
> +      continue;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type11Oe
> mStringsFunction.c
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type11Oe
> mStringsFunction.c
> new file mode 100644
> index 0000000000..53e7a57355
> --- /dev/null
> +++
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type11Oe
> mStringsFunction.c
> @@ -0,0 +1,91 @@
> +/** @file
> +  AMD SMBIOS Type 11 Record
> +
> +  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +#include "SmbiosCommon.h"
> +
> +/**
> +  This function adds OEM strings smbios record (Type 11).
> +
> +  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_OUT_OF_RESOURCES       Resource not available.
> +**/
> +EFI_STATUS
> +EFIAPI
> +OemStringsFunction (
> +  IN EFI_SMBIOS_PROTOCOL  *Smbios
> +  )
> +{
> +  EFI_STATUS           Status;
> +  EFI_SMBIOS_HANDLE    SmbiosHandle;
> +  SMBIOS_TABLE_TYPE11  *SmbiosRecord;
> +  UINT8                OemStrCount;
> +  UINTN                OemStrLen;
> +  UINTN                OemStrListSize;
> +  CHAR8                *OemStrPtr;
> +  UINT8                Idx;
> +  UINTN                StringOffset;
> +
> +  Status         = EFI_SUCCESS;
> +  SmbiosRecord   = NULL;
> +  OemStrListSize = 0;
> +
> +  if (Smbios == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  // Get number of OEM strings
> +  OemStrCount = PcdGet8 (PcdType11OemStringsCount);
> +
> +  // Calculate size of all OEM Strings
> +  OemStrPtr = (CHAR8 *)PcdGetPtr (PcdType11OemStrings);
> +  for (Idx = 0; Idx < OemStrCount; Idx++) {
> +    OemStrLen       = AsciiStrSize (OemStrPtr);
> +    OemStrPtr      += OemStrLen;
> +    OemStrListSize += OemStrLen;
> +  }
> +
> +  // Allocate memory for Type11 record
> +  SmbiosRecord = AllocateZeroPool (
> +                   sizeof (SMBIOS_TABLE_TYPE11) + OemStrListSize + 1
> +                   );
> +
> +  if (SmbiosRecord == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  SmbiosRecord->Hdr.Type    = SMBIOS_TYPE_OEM_STRINGS;
> +  SmbiosRecord->Hdr.Length  = sizeof (SMBIOS_TABLE_TYPE11);
> +  SmbiosRecord->Hdr.Handle  = 0;
> +  SmbiosRecord->StringCount = OemStrCount;
> +
> +  StringOffset = SmbiosRecord->Hdr.Length;
> +
> +  // Append strings at the end
> +  OemStrPtr = (CHAR8 *)PcdGetPtr (PcdType11OemStrings);
> +  for (Idx = 0; Idx < OemStrCount; Idx++) {
> +    OemStrLen = AsciiStrSize (OemStrPtr);
> +    CopyMem (
> +      (UINT8 *)SmbiosRecord + StringOffset,
> +      OemStrPtr,
> +      OemStrLen
> +      );
> +    OemStrPtr    += OemStrLen;
> +    StringOffset += OemStrLen;
> +  }
> +
> +  Status = AddCommonSmbiosRecord (
> +             Smbios,
> +             &SmbiosHandle,
> +             (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord
> +             );
> +
> +  FreePool (SmbiosRecord);
> +
> +  return Status;
> +}
> diff --git
> a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type12Sy
> stemCfgOptionsFunction.c
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type12Sy
> stemCfgOptionsFunction.c
> new file mode 100644
> index 0000000000..befb122372
> --- /dev/null
> +++
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type12Sy
> stemCfgOptionsFunction.c
> @@ -0,0 +1,90 @@
> +/** @file
> +  AMD SMBIOS Type 12 Record
> +
> +  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +#include "SmbiosCommon.h"
> +
> +/**
> +  This function adds System Configuration Options record (Type 12).
> +
> +  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_OUT_OF_RESOURCES       Resource not available.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SystemCfgOptionsFunction (
> +  IN EFI_SMBIOS_PROTOCOL  *Smbios
> +  )
> +{
> +  EFI_STATUS           Status;
> +  EFI_SMBIOS_HANDLE    SmbiosHandle;
> +  SMBIOS_TABLE_TYPE12  *SmbiosRecord;
> +  UINT8                SystemCfgOptionsCount;
> +  UINTN                SystemCfgOptionsLen;
> +  UINTN                SystemCfgOptionsListSize;
> +  CHAR8                *SystemCfgOptionsPtr;
> +  UINT8                Idx;
> +  UINTN                StringOffset;
> +
> +  Status                   = EFI_SUCCESS;
> +  SmbiosRecord             = NULL;
> +  SystemCfgOptionsListSize = 0;
> +
> +  if (Smbios == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  // Get number of System Configuration Options
> +  SystemCfgOptionsCount = PcdGet8 (PcdType12SystemCfgOptionsCount);
> +
> +  // Calculate size of all Strings
> +  SystemCfgOptionsPtr = (CHAR8 *)PcdGetPtr
> (PcdType12SystemCfgOptions);
> +  for (Idx = 0; Idx < SystemCfgOptionsCount; Idx++) {
> +    SystemCfgOptionsLen       = AsciiStrSize (SystemCfgOptionsPtr);
> +    SystemCfgOptionsPtr      += SystemCfgOptionsLen;
> +    SystemCfgOptionsListSize += SystemCfgOptionsLen;
> +  }
> +
> +  // Allocate memory for Type12 record
> +  SmbiosRecord = AllocateZeroPool (
> +                   sizeof (SMBIOS_TABLE_TYPE12) + SystemCfgOptionsListSize + 1
> +                   );
> +
> +  if (SmbiosRecord == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  SmbiosRecord->Hdr.Type    =
> SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS;
> +  SmbiosRecord->Hdr.Length  = sizeof (SMBIOS_TABLE_TYPE12);
> +  SmbiosRecord->Hdr.Handle  = 0;
> +  SmbiosRecord->StringCount = SystemCfgOptionsCount;
> +
> +  StringOffset = SmbiosRecord->Hdr.Length;
> +
> +  // Append strings at the end
> +  SystemCfgOptionsPtr = (CHAR8 *)PcdGetPtr
> (PcdType12SystemCfgOptions);
> +  for (Idx = 0; Idx < SystemCfgOptionsCount; Idx++) {
> +    SystemCfgOptionsLen = AsciiStrSize (SystemCfgOptionsPtr);
> +    CopyMem (
> +      (UINT8 *)SmbiosRecord + StringOffset,
> +      SystemCfgOptionsPtr,
> +      SystemCfgOptionsLen
> +      );
> +    SystemCfgOptionsPtr += SystemCfgOptionsLen;
> +    StringOffset        += SystemCfgOptionsLen;
> +  }
> +
> +  Status = AddCommonSmbiosRecord (
> +             Smbios,
> +             &SmbiosHandle,
> +             (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord
> +             );
> +  FreePool (SmbiosRecord);
> +
> +  return Status;
> +}
> diff --git
> a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type13Bio
> sLanguageInfoFunction.c
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type13Bi
> osLanguageInfoFunction.c
> new file mode 100644
> index 0000000000..7d3ada2769
> --- /dev/null
> +++
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type13Bi
> osLanguageInfoFunction.c
> @@ -0,0 +1,146 @@
> +/** @file
> +  AMD SMBIOS Type 13 Record
> +
> +  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +#include "SmbiosCommon.h"
> +
> +/**
> +  This function adds bios language information smbios record (Type 13).
> +
> +  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_OUT_OF_RESOURCES       Resource not available.
> +  @retval EFI_NOT_FOUND              Not able to locate PlatformLanguage.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BiosLanguageInfoFunction (
> +  IN  EFI_SMBIOS_PROTOCOL  *Smbios
> +  )
> +{
> +  EFI_STATUS           Status;
> +  EFI_SMBIOS_HANDLE    SmbiosHandle;
> +  SMBIOS_TABLE_TYPE13  *SmbiosRecord;
> +  UINTN                TotalSize;
> +  UINTN                StringOffset;
> +  UINTN                VarSize;
> +  UINTN                Idx;
> +  UINT8                NumSupportedLang;
> +  UINT8                CurrLangIdx;
> +  CHAR8                *CurrLang;
> +  CHAR8                *SupportedLang;
> +  CHAR8                *LangStr;
> +
> +  if (Smbios == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  CurrLang      = NULL;
> +  SupportedLang = NULL;
> +
> +  // Get the current language.
> +  Status = GetEfiGlobalVariable2 (
> +             L"PlatformLang",
> +             (void **)&CurrLang,
> +             &VarSize
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Failed to get PlatformLang: %r\n", Status));
> +
> +    VarSize = AsciiStrSize (
> +                (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang)
> +                );
> +    CurrLang = AllocateCopyPool (
> +                 VarSize,
> +                 (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLang)
> +                 );
> +    ASSERT (CurrLang != NULL);
> +  }
> +
> +  // Get the list of supported languages.
> +  Status = GetEfiGlobalVariable2 (
> +             L"PlatformLangCodes",
> +             (void **)&SupportedLang,
> +             &VarSize
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Failed to get PlatformLangCodes: %r\n",
> Status));
> +
> +    VarSize = AsciiStrSize (
> +                (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)
> +                );
> +    SupportedLang = AllocateCopyPool (
> +                      VarSize,
> +                      (CHAR8 *)PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)
> +                      );
> +    ASSERT (SupportedLang != NULL);
> +  }
> +
> +  // Calculate number of supported languages and index of current language
> in list.
> +  CurrLangIdx      = 0;
> +  NumSupportedLang = 0;
> +  LangStr          = SupportedLang;
> +
> +  for (Idx = 0; Idx < VarSize; Idx++) {
> +    if ((SupportedLang[Idx] == ';') || (SupportedLang[Idx] == '\0')) {
> +      // Found a language string, increment the language count.
> +      NumSupportedLang++;
> +
> +      // Replace string separator with null termination.
> +      SupportedLang[Idx] = '\0';
> +      if (!AsciiStrCmp (LangStr, CurrLang)) {
> +        CurrLangIdx = NumSupportedLang;
> +      }
> +
> +      // Point LangStr to next string in list.
> +      LangStr = &SupportedLang[Idx + 1];
> +    }
> +  }
> +
> +  if (CurrLangIdx == 0) {
> +    DEBUG ((DEBUG_ERROR, "Failed to locate PlatformLang in
> PlatformLangCode.\n"));
> +    Status = EFI_NOT_FOUND;
> +  } else {
> +    // Calculate record size and allocate memory for smbios record.
> +    TotalSize = sizeof (SMBIOS_TABLE_TYPE13) + VarSize + 1;
> +
> +    SmbiosRecord = AllocateZeroPool (TotalSize);
> +    if (SmbiosRecord == NULL) {
> +      Status = EFI_OUT_OF_RESOURCES;
> +    } else {
> +      // Fill record data and strings.
> +      SmbiosRecord->Hdr.Type             =
> SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION;
> +      SmbiosRecord->Hdr.Length           = sizeof (SMBIOS_TABLE_TYPE13);
> +      SmbiosRecord->Hdr.Handle           = 0;
> +      SmbiosRecord->InstallableLanguages = NumSupportedLang;
> +      SmbiosRecord->Flags                = 1; // Abbreviated Format.
> +      SmbiosRecord->CurrentLanguages     = CurrLangIdx;
> +
> +      // Add strings to bottom of data block
> +      StringOffset = SmbiosRecord->Hdr.Length;
> +      CopyMem ((UINT8 *)SmbiosRecord + StringOffset, SupportedLang,
> VarSize);
> +
> +      Status = AddCommonSmbiosRecord (
> +                 Smbios,
> +                 &SmbiosHandle,
> +                 (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord
> +                 );
> +      FreePool (SmbiosRecord);
> +    }
> +  }
> +
> +  if (CurrLang != NULL) {
> +    FreePool (CurrLang);
> +  }
> +
> +  if (SupportedLang != NULL) {
> +    FreePool (SupportedLang);
> +  }
> +
> +  return Status;
> +}
> diff --git
> a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type38Ip
> miDeviceInformation.c
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type38Ip
> miDeviceInformation.c
> new file mode 100644
> index 0000000000..e2ad2ddb3d
> --- /dev/null
> +++
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type38Ip
> miDeviceInformation.c
> @@ -0,0 +1,70 @@
> +/** @file
> +  AMD SMBIOS Type 38 Record
> +
> +  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +#include "SmbiosCommon.h"
> +
> +/**
> +  This function updates IPMI Device information changes to the contents of
> the
> +  Table Type 38.
> +
> +  @param[in]  Smbios  The EFI_SMBIOS_PROTOCOL protocol instance.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_UNSUPPORTED            Unexpected RecordType value.
> +**/
> +EFI_STATUS
> +EFIAPI
> +IpmiDeviceInformation (
> +  IN  EFI_SMBIOS_PROTOCOL  *Smbios
> +  )
> +{
> +  EFI_STATUS           Status;
> +  EFI_SMBIOS_HANDLE    SmbiosHandle;
> +  SMBIOS_TABLE_TYPE38  *SmbiosRecord;
> +
> +  //
> +  // Two zeros following the last string.
> +  //
> +  SmbiosRecord = AllocateZeroPool (sizeof (SMBIOS_TABLE_TYPE38) + 1 + 1);
> +  if (SmbiosRecord == NULL) {
> +    ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  SmbiosRecord->Hdr.Type   =
> EFI_SMBIOS_TYPE_IPMI_DEVICE_INFORMATION;
> +  SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE38);
> +  SmbiosRecord->Hdr.Handle = 0;
> +
> +  switch (FixedPcdGet8 (PcdIpmiInterfaceType)) {
> +    case IPMIDeviceInfoInterfaceTypeKCS:
> +      SmbiosRecord->InterfaceType             = IPMIDeviceInfoInterfaceTypeKCS;
> +      SmbiosRecord->IPMISpecificationRevision = 0x20; // IPMI v2.0
> +      SmbiosRecord->I2CSlaveAddress           = 0x00; // not used in KCS interface
> +      SmbiosRecord->NVStorageDeviceAddress    = 0xFF;
> +      // KCS port number base and set LSB bit 1 to mark IO ADDRESS space
> +      SmbiosRecord->BaseAddress                       = FixedPcdGet16
> (PcdIpmiKcsIoBaseAddress) | 0x1;
> +      SmbiosRecord->BaseAddressModifier_InterruptInfo = 0x00;
> +      SmbiosRecord->InterruptNumber                   = 0x00;
> +      //
> +      // Now we have got the full smbios record,
> +      // call smbios protocol to add this record.
> +      //
> +      Status = AddCommonSmbiosRecord (
> +                 Smbios,
> +                 &SmbiosHandle,
> +                 (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord
> +                 );
> +      break;
> +    default:
> +      // Do not add table
> +      Status = EFI_UNSUPPORTED;
> +      break;
> +  }
> +
> +  FreePool (SmbiosRecord);
> +  return Status;
> +}
> diff --git
> a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type41On
> boardDevExtInfoFunction.c
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type41On
> boardDevExtInfoFunction.c
> new file mode 100644
> index 0000000000..cbd4c75eaf
> --- /dev/null
> +++
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type41On
> boardDevExtInfoFunction.c
> @@ -0,0 +1,237 @@
> +/** @file
> +  AMD SMBIOS Type 41 Record
> +
> +  Copyright (C) 2023 - 2024  Advanced Micro Devices, Inc. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +#include <Pcd/SmbiosPcd.h>
> +#include "SmbiosCommon.h"
> +
> +#define MSR_MMIO_CFG_BASE  0xC0010058ul             // MMIO
> Configuration Base Address Register
> +
> +/**
> +  This function adds onboard devices extended information smbios record
> (Type 41).
> +
> +  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_OUT_OF_RESOURCES       Resource not available.
> +**/
> +EFI_STATUS
> +EFIAPI
> +OnboardDevExtInfoFunction (
> +  IN EFI_SMBIOS_PROTOCOL  *Smbios
> +  )
> +{
> +  EFI_STATUS                          Status;
> +  EFI_SMBIOS_HANDLE                   SmbiosHandle;
> +  SMBIOS_TABLE_TYPE41                 *SmbiosRecord;
> +  SMBIOS_ONBOARD_DEV_EXT_INFO_RECORD  *DevExtInfoRecord;
> +  UINT8                               DevIdx;
> +  UINT8                               Idx;
> +  UINT8                               NumberOfDevices;
> +  UINTN                               StringOffset;
> +  CHAR8                               *RefDesStr;
> +  UINTN                               RefDesStrLen;
> +  UINT16                              SegmentNum;
> +  UINT8                               BusNum;
> +  UINT8                               DevNum;
> +  UINT8                               Functions;
> +  UINT8                               DeviceFound;
> +
> +  if (Smbios == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  // Get the total number of onboard devices.
> +  NumberOfDevices = PcdGet8 (PcdAmdSmbiosType41Number);
> +  DEBUG ((DEBUG_INFO, "%a: Total number of AMD SMBIOS type41 PCD
> structure %d.\n", __func__, NumberOfDevices));
> +  DevExtInfoRecord = (SMBIOS_ONBOARD_DEV_EXT_INFO_RECORD
> *)PcdGetPtr (PcdAmdSmbiosType41);
> +
> +  // No device entries found
> +  if (NumberOfDevices == 0) {
> +    DEBUG ((DEBUG_INFO, "No onboard devices found.\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  // Generate type41 smbios record for each device and add it to Smbios
> table.
> +  for (DevIdx = 0; DevIdx < NumberOfDevices; DevIdx++) {
> +    DEBUG ((DEBUG_MANAGEABILITY, "Device number %d:\n", DevIdx));
> +    // Check whether reference designation strings are present.
> +    if (DevExtInfoRecord->ReferenceDesignation != 0) {
> +      RefDesStr    = DevExtInfoRecord->RefDesignationStr;
> +      RefDesStrLen = AsciiStrLen (RefDesStr) + 1;
> +    } else {
> +      RefDesStr    = NULL;
> +      RefDesStrLen = 1;
> +    }
> +
> +    DEBUG ((DEBUG_MANAGEABILITY, " - ReferenceDesignation = %d\n",
> DevExtInfoRecord->ReferenceDesignation));
> +    DEBUG ((DEBUG_MANAGEABILITY, " - DeviceType = %d\n",
> DevExtInfoRecord->DeviceType));
> +    DEBUG ((DEBUG_MANAGEABILITY, " - DeviceEnabled = %d\n",
> DevExtInfoRecord->DeviceEnabled));
> +    DEBUG ((DEBUG_MANAGEABILITY, " - DeviceTypeInstance = %d\n",
> DevExtInfoRecord->DeviceTypeInstance));
> +    DEBUG ((DEBUG_MANAGEABILITY, " - VendorId = %x\n",
> DevExtInfoRecord->VendorId));
> +    DEBUG ((DEBUG_MANAGEABILITY, " - DeviceId = %x\n", DevExtInfoRecord-
> >DeviceId));
> +    DEBUG ((DEBUG_MANAGEABILITY, " - RefDesignationStr = %a\n",
> DevExtInfoRecord->RefDesignationStr));
> +
> +    Status = GetBusDeviceInfo (
> +               &DevExtInfoRecord->VendorId,
> +               &DevExtInfoRecord->DeviceId,
> +               &DevExtInfoRecord->DeviceTypeInstance,
> +               &SegmentNum,
> +               &BusNum,
> +               &DevNum,
> +               &Functions,
> +               &DeviceFound
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "Could not get SBDF details for idx %d\n",
> DevIdx));
> +      continue;
> +    }
> +
> +    // Device not present
> +    if (DeviceFound == 0) {
> +      Status = EFI_NOT_FOUND;
> +      DEBUG ((
> +        DEBUG_ERROR,
> +        "No onboard device found matching VendorId: %x DeviceId: %x\n",
> +        DevExtInfoRecord->VendorId,
> +        DevExtInfoRecord->DeviceId
> +        ));
> +      continue;
> +    }
> +
> +    // Create one record for each function in a multi-function device
> +    for (Idx = 0; Idx <= 7; Idx++) {
> +      if ((Functions >> Idx) & 0x1) {
> +        SmbiosRecord = NULL;
> +        SmbiosRecord = AllocateZeroPool (
> +                         sizeof (SMBIOS_TABLE_TYPE41) + RefDesStrLen + 1
> +                         );
> +        if (SmbiosRecord == NULL) {
> +          Status = EFI_OUT_OF_RESOURCES;
> +          return Status;
> +        } else {
> +          SmbiosRecord->Hdr.Type             =
> SMBIOS_TYPE_ONBOARD_DEVICES_EXTENDED_INFORMATION;
> +          SmbiosRecord->Hdr.Length           = sizeof (SMBIOS_TABLE_TYPE41);
> +          SmbiosRecord->Hdr.Handle           = 0;
> +          SmbiosRecord->ReferenceDesignation = DevExtInfoRecord-
> >ReferenceDesignation;
> +          SmbiosRecord->DeviceType           = (DevExtInfoRecord->DeviceEnabled
> << 7) | DevExtInfoRecord->DeviceType;
> +          SmbiosRecord->DeviceTypeInstance   = DevExtInfoRecord-
> >DeviceTypeInstance;
> +          SmbiosRecord->SegmentGroupNum      = SegmentNum;
> +          SmbiosRecord->BusNum               = BusNum;
> +          SmbiosRecord->DevFuncNum           = (DevNum << 3) + Idx;
> +
> +          // Add strings to bottom of data block
> +          StringOffset = SmbiosRecord->Hdr.Length;
> +          CopyMem (
> +            (UINT8 *)SmbiosRecord + StringOffset,
> +            RefDesStr,
> +            RefDesStrLen
> +            );
> +          StringOffset += RefDesStrLen;
> +
> +          Status = AddCommonSmbiosRecord (
> +                     Smbios,
> +                     &SmbiosHandle,
> +                     (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord
> +                     );
> +          FreePool (SmbiosRecord);
> +        }
> +      }
> +    }
> +
> +    DevExtInfoRecord++;
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function gets the Bus, Device and Segment number of a PCI device
> when Vendor ID, Device ID and instance
> +  are provided.
> +
> +  @param[in]  VendorId        Vendor ID of the PCI device to be provided.
> +  @param[in]  DeviceId        Device ID of the PCI device to be provided
> +  @param[in]  Instance        Instance of the PCI device. If more than one
> devices with same vendor
> +                              and device ID is present, instance number is used.
> +  @param[out]  Segment        Segment number of the PCI device is assigned.
> +  @param[out]  Bus            Bus number of the PCI device is assigned.
> +  @param[out]  Device         Device number of the PCI device is assigned.
> +  @param[out]  Functions      Bits 0-7 of the Functions variable correspond to
> respective function numbers.
> +  @param[out]  DeviceFound    Set to 1 if the device is found.
> +
> +  @retval EFI_SUCCESS         All parameters were valid.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetBusDeviceInfo (
> +  IN  UINT16  *VendorId,
> +  IN  UINT16  *DeviceId,
> +  IN  UINT8   *Instance,
> +  OUT UINT16  *Segment,
> +  OUT UINT8   *Bus,
> +  OUT UINT8   *Device,
> +  OUT UINT8   *Functions,
> +  OUT UINT8   *DeviceFound
> +  )
> +{
> +  UINT16  SegIdx;
> +  UINT8   BusIdx;
> +  UINT16  BusIdx16;
> +  UINT8   DevIdx;
> +  UINT8   FuncIdx;
> +  UINT8   InstanceCount;
> +  UINT16  MaxSegments;
> +  UINT8   BusRangeIdentifier;
> +
> +  InstanceCount = *Instance;
> +  *DeviceFound  = 0;
> +
> +  BusRangeIdentifier = (AsmReadMsr64 (MSR_MMIO_CFG_BASE) >> 2) &
> 0xF;
> +  if ( BusRangeIdentifier <= 0x8 ) {
> +    MaxSegments = 1;
> +  } else if ((BusRangeIdentifier >= 0x9) && (BusRangeIdentifier <= 0xF)) {
> +    MaxSegments = 1 << (BusRangeIdentifier - 0x8);
> +  }
> +
> +  for (SegIdx = 0; SegIdx < MaxSegments; SegIdx++ ) {
> +    for (BusIdx16 = 0; BusIdx16 <= 255; BusIdx16++) {
> +      BusIdx = (UINT8)BusIdx16;
> +      for (DevIdx = 0; DevIdx < 32; DevIdx++) {
> +        if ((PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SegIdx, BusIdx,
> DevIdx, 0, 2)) == *DeviceId) &&
> +            (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SegIdx, BusIdx,
> DevIdx, 0, 0)) == *VendorId))
> +        {
> +          *DeviceFound = 1;
> +          *Functions   = 0;
> +          if (InstanceCount > 1) {
> +            *DeviceFound = 0;
> +            InstanceCount--;
> +            continue;
> +          } else {
> +            *Bus        = BusIdx;
> +            *Device     = DevIdx;
> +            *Segment    = SegIdx;
> +            *Functions |= 1;
> +            for (FuncIdx = 1; FuncIdx < 8; FuncIdx++) {
> +              if ((PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SegIdx, BusIdx,
> DevIdx, FuncIdx, 2)) == *DeviceId) &&
> +                  (PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SegIdx, BusIdx,
> DevIdx, FuncIdx, 0)) == *VendorId))
> +              {
> +                *Functions |= (1 << FuncIdx);
> +              }
> +            }
> +
> +            return EFI_SUCCESS;
> +          }
> +        }
> +      }
> +
> +      if (BusIdx == 255) {
> +        break;
> +      }
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type8Port
> ConnectorInfoFunction.c
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type8Port
> ConnectorInfoFunction.c
> new file mode 100644
> index 0000000000..844529d1f0
> --- /dev/null
> +++
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type8Port
> ConnectorInfoFunction.c
> @@ -0,0 +1,133 @@
> +/** @file
> +  AMD SMBIOS Type 8 Record
> +
> +  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +#include <Pcd/SmbiosPcd.h>
> +#include "SmbiosCommon.h"
> +
> +/**
> +  This function adds port connector information smbios record (Type 8).
> +
> +  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_OUT_OF_RESOURCES       Resource not available.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PortConnectorInfoFunction (
> +  IN EFI_SMBIOS_PROTOCOL  *Smbios
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  EFI_SMBIOS_HANDLE             SmbiosHandle;
> +  SMBIOS_TABLE_TYPE8            *SmbiosRecord;
> +  SMBIOS_PORT_CONNECTOR_RECORD  *PortConnRecord;
> +  UINT8                         PortIdx;
> +  UINT8                         NumberOfPortConnector;
> +  UINTN                         StringOffset;
> +  CHAR8                         *IntPortConDesStr;
> +  UINTN                         IntPortConDesStrLen;
> +  CHAR8                         *ExtPortConDesStr;
> +  UINTN                         ExtPortConDesStrLen;
> +
> +  if (Smbios == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  // Get the total number of port connectors.
> +  NumberOfPortConnector = PcdGet8 (PcdAmdSmbiosType8Number);
> +  DEBUG ((DEBUG_INFO, "%a: Total number of AMD SMBIOS type8 PCD
> structure %d.\n", __func__, NumberOfPortConnector));
> +  PortConnRecord = (SMBIOS_PORT_CONNECTOR_RECORD *)PcdGetPtr
> (PcdAmdSmbiosType8);
> +
> +  if (NumberOfPortConnector == 0) {
> +    DEBUG ((DEBUG_INFO, "No port connectors found.\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  // Generate type8 smbios record for each connector and add it to Smbios
> table.
> +  for (PortIdx = 0; PortIdx < NumberOfPortConnector; PortIdx++) {
> +    DEBUG ((DEBUG_MANAGEABILITY, "Port %d:\n", PortIdx));
> +    // Check whether Port connector designator strings are present or not.
> +    if (PortConnRecord->Type8Data.InternalReferenceDesignator != 0) {
> +      IntPortConDesStr    = PortConnRecord->DesinatorStr.IntDesignatorStr;
> +      IntPortConDesStrLen = AsciiStrLen (IntPortConDesStr) + 1;
> +      DEBUG ((DEBUG_MANAGEABILITY, "-- DesinatorStr.IntDesignatorStr =
> %a\n", IntPortConDesStr));
> +    } else {
> +      IntPortConDesStr    = NULL;
> +      IntPortConDesStrLen = 0;
> +    }
> +
> +    if (PortConnRecord->Type8Data.ExternalReferenceDesignator != 0) {
> +      ExtPortConDesStr    = PortConnRecord->DesinatorStr.ExtDesignatorStr;
> +      ExtPortConDesStrLen = AsciiStrLen (ExtPortConDesStr) + 1;
> +      DEBUG ((DEBUG_MANAGEABILITY, "-- DesinatorStr.ExtDesignatorStr =
> %a\n", ExtPortConDesStr));
> +    } else {
> +      ExtPortConDesStr    = NULL;
> +      ExtPortConDesStrLen = 0;
> +    }
> +
> +    SmbiosRecord = NULL;
> +    SmbiosRecord = AllocateZeroPool (
> +                     sizeof (SMBIOS_TABLE_TYPE8) + IntPortConDesStrLen +
> ExtPortConDesStrLen + 1
> +                     );
> +
> +    if (SmbiosRecord == NULL) {
> +      Status = EFI_OUT_OF_RESOURCES;
> +      return Status;
> +    } else {
> +      SmbiosRecord->Hdr.Type   =
> SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION;
> +      SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE8);
> +      SmbiosRecord->Hdr.Handle = 0;
> +
> +      SmbiosRecord->InternalReferenceDesignator =
> +        PortConnRecord->Type8Data.InternalReferenceDesignator;
> +      SmbiosRecord->InternalConnectorType =
> +        PortConnRecord->Type8Data.InternalConnectorType;
> +      SmbiosRecord->ExternalReferenceDesignator =
> +        PortConnRecord->Type8Data.ExternalReferenceDesignator;
> +      SmbiosRecord->ExternalConnectorType =
> +        PortConnRecord->Type8Data.ExternalConnectorType;
> +      SmbiosRecord->PortType =
> +        PortConnRecord->Type8Data.PortType;
> +      DEBUG ((DEBUG_MANAGEABILITY, " - InternalReferenceDesignator =
> %d\n", SmbiosRecord->InternalReferenceDesignator));
> +      DEBUG ((DEBUG_MANAGEABILITY, " - InternalConnectorType = %d\n",
> SmbiosRecord->InternalConnectorType));
> +      DEBUG ((DEBUG_MANAGEABILITY, " - ExternalReferenceDesignator =
> %d\n", SmbiosRecord->ExternalReferenceDesignator));
> +      DEBUG ((DEBUG_MANAGEABILITY, " - ExternalConnectorType = %d\n",
> SmbiosRecord->ExternalConnectorType));
> +      DEBUG ((DEBUG_MANAGEABILITY, " - PortType = %d\n", SmbiosRecord-
> >PortType));
> +
> +      // Add strings to bottom of data block
> +      StringOffset = SmbiosRecord->Hdr.Length;
> +      if (IntPortConDesStr != NULL) {
> +        CopyMem (
> +          (UINT8 *)SmbiosRecord + StringOffset,
> +          IntPortConDesStr,
> +          IntPortConDesStrLen
> +          );
> +        StringOffset += IntPortConDesStrLen;
> +      }
> +
> +      if (ExtPortConDesStr != NULL) {
> +        CopyMem (
> +          (UINT8 *)SmbiosRecord + StringOffset,
> +          ExtPortConDesStr,
> +          ExtPortConDesStrLen
> +          );
> +      }
> +
> +      Status = AddCommonSmbiosRecord (
> +                 Smbios,
> +                 &SmbiosHandle,
> +                 (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord
> +                 );
> +      FreePool (SmbiosRecord);
> +    }
> +
> +    PortConnRecord++;
> +  }
> +
> +  return Status;
> +}
> diff --git
> a/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type9Syst
> emSlotInfoFunction.c
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type9Syst
> emSlotInfoFunction.c
> new file mode 100644
> index 0000000000..568f44b427
> --- /dev/null
> +++
> b/Platform/AMD/AmdPlatformPkg/Universal/SmbiosCommonDxe/Type9Syst
> emSlotInfoFunction.c
> @@ -0,0 +1,94 @@
> +/** @file
> +  AMD SMBIOS Type 9 Record
> +
> +  Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +#include <Library/PrintLib.h>
> +#include "SmbiosCommon.h"
> +#include <Library/AmdPlatformSocLib.h>
> +
> +/**
> +  This function checks for system slot info and adds smbios record (Type 9).
> +
> +  @param[in]  Smbios                     The EFI_SMBIOS_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS                All parameters were valid.
> +  @retval EFI_OUT_OF_RESOURCES       Resource not available.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SystemSlotInfoFunction (
> +  IN  EFI_SMBIOS_PROTOCOL  *Smbios
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  EFI_SMBIOS_HANDLE            SmbiosHandle;
> +  SMBIOS_TABLE_TYPE9           *SmbiosRecord;
> +  UINTN                        SystemSlotCount;
> +  SMBIOS_TABLE_TYPE9           *SystemSlotInfo;
> +  UINTN                        Index;
> +  CHAR8                        SlotDesignationStr[SMBIOS_STRING_MAX_LENGTH];
> +  SMBIOS_TABLE_TYPE9_EXTENDED  SmbiosRecordExtended;
> +  UINTN                        SlotDesStrLen;
> +  UINTN                        TotalSize;
> +
> +  if (Smbios == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  SystemSlotInfo  = NULL;
> +  SystemSlotCount = 0;
> +  // Invoke GetSystemSlotInfo function to get the number of system slots.
> +  Status = GetSystemSlotInfo (&SystemSlotInfo, &SystemSlotCount);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  for (Index = 0; Index < SystemSlotCount; Index++) {
> +    SlotDesStrLen = AsciiSPrint (
> +                      SlotDesignationStr,
> +                      SMBIOS_STRING_MAX_LENGTH,
> +                      "PCIE-%d",
> +                      SystemSlotInfo[Index].SlotID
> +                      );
> +    // Two zeros following the last string.
> +    TotalSize    = sizeof (SMBIOS_TABLE_TYPE9) + sizeof
> (SMBIOS_TABLE_TYPE9_EXTENDED) + SlotDesStrLen + 2;
> +    SmbiosRecord = NULL;
> +    SmbiosRecord = AllocateZeroPool (TotalSize);
> +    if (SmbiosRecord == NULL) {
> +      Status = EFI_OUT_OF_RESOURCES;
> +    } else {
> +      CopyMem (SmbiosRecord, &SystemSlotInfo[Index], sizeof
> (SMBIOS_TABLE_TYPE9));
> +      SmbiosRecord->Hdr.Type                 = SMBIOS_TYPE_SYSTEM_SLOTS;
> +      SmbiosRecord->Hdr.Length               = sizeof (SMBIOS_TABLE_TYPE9) +
> sizeof (SMBIOS_TABLE_TYPE9_EXTENDED);
> +      SmbiosRecord->Hdr.Handle               = 0;
> +      SmbiosRecord->SlotDesignation          = 1;
> +      SmbiosRecordExtended.SlotHeight        = SlotHeightUnknown;
> +      SmbiosRecordExtended.SlotPitch         = 0;
> +      SmbiosRecordExtended.SlotPhysicalWidth = SmbiosRecord-
> >SlotDataBusWidth;
> +      CopyMem (&SmbiosRecord->SlotCharacteristics1, PcdGetPtr
> (PcdAmdSmbiosType9SlotCharacteristics1), sizeof
> (MISC_SLOT_CHARACTERISTICS1));
> +      CopyMem (&SmbiosRecord->SlotCharacteristics2, PcdGetPtr
> (PcdAmdSmbiosType9SlotCharacteristics2), sizeof
> (MISC_SLOT_CHARACTERISTICS2));
> +      CopyMem ((UINT8 *)SmbiosRecord->PeerGroups + SmbiosRecord-
> >PeerGroupingCount * sizeof (SmbiosRecord->PeerGroups), (UINT8
> *)&SmbiosRecordExtended, sizeof (SMBIOS_TABLE_TYPE9_EXTENDED));
> +      CopyMem ((UINT8 *)SmbiosRecord + SmbiosRecord->Hdr.Length,
> SlotDesignationStr, SlotDesStrLen);
> +      Status = AddCommonSmbiosRecord (
> +                 Smbios,
> +                 &SmbiosHandle,
> +                 (EFI_SMBIOS_TABLE_HEADER *)SmbiosRecord
> +                 );
> +      if (EFI_ERROR (Status)) {
> +        FreePool (SmbiosRecord);
> +        break;
> +      }
> +
> +      if (SmbiosRecord != NULL) {
> +        FreePool (SmbiosRecord);
> +      }
> +    }
> +  }
> +
> +  FreePool (SystemSlotInfo);
> +  return EFI_SUCCESS;
> +}
> --
> 2.34.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#119081): https://edk2.groups.io/g/devel/message/119081
Mute This Topic: https://groups.io/mt/106200547/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-05-20 11:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-20 10:23 [edk2-devel] [edk2-platforms] AmdPlatformPkg: Adds SmbiosCommonDxe driver Abdul Lateef Attar via groups.io
2024-05-20 11:00 ` Chang, Abner via groups.io

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox