* [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