DynamicTablesPkg: Add SMBIOS Temperature Probe (Type 28) generator

Introduce a CM_ARCH_COMMON_TEMPERATURE_PROBE_INFO object to describe
temperature probes provided by the platform. The generator creates one
SMBIOS Type 28 record for each temperature probe object and populates
the description, location/status, probe limits, resolution, tolerance,
accuracy, OEM-defined data, and nominal value.

Add the CM object parser entry and wire the generator into the
DynamicTablesPkg build.

Signed-off-by: Varshit Pandya <varshit.pandya@arm.com>
This commit is contained in:
VarshitPandya 2026-06-24 15:56:28 +01:00 committed by mergify[bot]
parent 0c2e337351
commit 5628eaaf38
5 changed files with 557 additions and 0 deletions

View file

@ -116,6 +116,7 @@
DynamicTablesPkg/Library/Smbios/SmbiosType17Lib/SmbiosType17Lib.inf
DynamicTablesPkg/Library/Smbios/SmbiosType19Lib/SmbiosType19Lib.inf
DynamicTablesPkg/Library/Smbios/SmbiosType27Lib/SmbiosType27Lib.inf
DynamicTablesPkg/Library/Smbios/SmbiosType28Lib/SmbiosType28Lib.inf
# AML Fixup (Arm specific)
DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf
@ -167,6 +168,7 @@
NULL|DynamicTablesPkg/Library/Smbios/SmbiosType17Lib/SmbiosType17Lib.inf
NULL|DynamicTablesPkg/Library/Smbios/SmbiosType19Lib/SmbiosType19Lib.inf
NULL|DynamicTablesPkg/Library/Smbios/SmbiosType27Lib/SmbiosType27Lib.inf
NULL|DynamicTablesPkg/Library/Smbios/SmbiosType28Lib/SmbiosType28Lib.inf
}
[Components.RISCV64]

View file

@ -84,6 +84,7 @@ typedef enum ArchCommonObjectID {
EArchCommonObjMemoryDeviceInfo, ///< 56 - Memory Device Info
EArchCommonObjMemoryArrayMappedAddress, ///< 57 - Memory Array Mapped Address Info
EArchCommonObjCoolingDeviceInfo, ///< 58 - Cooling Device Info
EArchCommonObjTemperatureProbeInfo, ///< 59 - Temperature Probe Info
EArchCommonObjMax
} EARCH_COMMON_OBJECT_ID;
@ -1489,4 +1490,48 @@ typedef struct CmArchCommonCoolingDeviceInfo {
CHAR8 Description[SMBIOS_MAX_STRING_SIZE];
} CM_ARCH_COMMON_COOLING_DEVICE_INFO;
/** A structure that describes a temperature probe.
SMBIOS Specification v3.9.0 Type 28
ID: EArchCommonObjTemperatureProbeInfo
**/
typedef struct CmArchCommonTemperatureProbeInfo {
/// CM Object Token uniquely identifying this temperature probe.
CM_OBJECT_TOKEN TemperatureProbeToken;
/// Description of the temperature probe or its location.
CHAR8 Description[SMBIOS_MAX_STRING_SIZE];
/// Location and status of the temperature probe.
MISC_TEMPERATURE_PROBE_LOCATION LocationAndStatus;
/// Maximum value readable by the probe, in 1/10 degrees C.
/// A value of 0x8000 indicates unknown.
UINT16 MaximumValue;
/// Minimum value readable by the probe, in 1/10 degrees C.
/// A value of 0x8000 indicates unknown.
UINT16 MinimumValue;
/// Resolution for the probe reading, in 1/1000 degrees C.
/// A value of 0x8000 indicates unknown.
UINT16 Resolution;
/// Tolerance for the probe reading, plus/minus 1/10 degrees C.
/// A value of 0x8000 indicates unknown.
UINT16 Tolerance;
/// Accuracy for the probe reading, in plus/minus 1/100 percent.
/// A value of 0x8000 indicates unknown.
UINT16 Accuracy;
/// OEM- or firmware vendor-specific information.
UINT32 OemDefined;
/// Nominal temperature value, in 1/10 degrees C.
/// A value of 0x8000 indicates unknown.
UINT16 NominalValue;
} CM_ARCH_COMMON_TEMPERATURE_PROBE_INFO;
#pragma pack()

View file

@ -1235,6 +1235,21 @@ STATIC CONST CM_OBJ_PARSER CmArchCommonCoolingDeviceInfoParser[] = {
{ "Description", SMBIOS_MAX_STRING_SIZE, NULL, PrintString },
};
/** A parser for EArchCommonObjTemperatureProbeInfo.
*/
STATIC CONST CM_OBJ_PARSER CmArchCommonTemperatureProbeInfoParser[] = {
{ "TemperatureProbeToken", sizeof (CM_OBJECT_TOKEN), "0x%p", NULL },
{ "Description", SMBIOS_MAX_STRING_SIZE, NULL, PrintString },
{ "LocationAndStatus", sizeof (MISC_TEMPERATURE_PROBE_LOCATION), "0x%x", NULL },
{ "MaximumValue", sizeof (UINT16), "0x%x", NULL },
{ "MinimumValue", sizeof (UINT16), "0x%x", NULL },
{ "Resolution", sizeof (UINT16), "0x%x", NULL },
{ "Tolerance", sizeof (UINT16), "0x%x", NULL },
{ "Accuracy", sizeof (UINT16), "0x%x", NULL },
{ "OEMDefined", sizeof (UINT32), "0x%x", NULL },
{ "NominalValue", sizeof (UINT16), "0x%x", NULL },
};
/** A parser for Arch Common namespace objects.
*/
STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = {
@ -1298,6 +1313,7 @@ STATIC CONST CM_OBJ_PARSER_ARRAY ArchCommonNamespaceObjectParser[] = {
CM_PARSER_ADD_OBJECT (EArchCommonObjMemoryDeviceInfo, CmArchCommonMemoryDeviceInfoParser),
CM_PARSER_ADD_OBJECT (EArchCommonObjMemoryArrayMappedAddress, CmArchCommonMemoryArrayMappedAddressParser),
CM_PARSER_ADD_OBJECT (EArchCommonObjCoolingDeviceInfo, CmArchCommonCoolingDeviceInfoParser),
CM_PARSER_ADD_OBJECT (EArchCommonObjTemperatureProbeInfo, CmArchCommonTemperatureProbeInfoParser),
CM_PARSER_ADD_OBJECT_RESERVED (EArchCommonObjMax)
};

View file

@ -0,0 +1,465 @@
/** @file
SMBIOS Type28 Table Generator.
@par Reference(s):
- SMBIOS Specification 3.9.0, Type 28 Temperature Probe
Copyright (c) 2026, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/SmbiosStringTableLib.h>
// Module specific include files.
#include <ConfigurationManagerObject.h>
#include <ConfigurationManagerHelper.h>
#include <Protocol/ConfigurationManagerProtocol.h>
#include <Protocol/DynamicTableFactoryProtocol.h>
#include <IndustryStandard/SmBios.h>
/** SMBIOS Type 28 Temperature Probe Generator
Requirements:
The following Configuration Manager Object(s) are required by
this Generator:
- EArchCommonObjTemperatureProbeInfo
*/
/**
This macro expands to a function that retrieves the Temperature Probe
information from the Configuration Manager.
*/
GET_OBJECT_LIST (
EObjNameSpaceArchCommon,
EArchCommonObjTemperatureProbeInfo,
CM_ARCH_COMMON_TEMPERATURE_PROBE_INFO
);
/**
Type 28 records currently expose one string field: Description.
*/
#define SMBIOS_TYPE28_MAX_STRINGS (1)
/**
Valid SMBIOS Type 28 Status values are 0x01-0x06.
Valid Location values are 0x01-0x0F.
*/
#define SMBIOS_TYPE28_PROBE_STATUS_MIN 1
#define SMBIOS_TYPE28_PROBE_STATUS_MAX 6
#define SMBIOS_TYPE28_PROBE_LOCATION_MIN 1
#define SMBIOS_TYPE28_PROBE_LOCATION_MAX 15
/** Check whether a Type 28 temperature probe status value is valid.
@param [in] Status Temperature probe status value.
@retval TRUE The status value is valid.
@retval FALSE The status value is invalid.
**/
STATIC
BOOLEAN
IsValidTemperatureProbeStatus (
IN UINT8 Status
)
{
return (Status >= SMBIOS_TYPE28_PROBE_STATUS_MIN) &&
(Status <= SMBIOS_TYPE28_PROBE_STATUS_MAX);
}
/** Check whether a Type 28 temperature probe location value is valid.
@param [in] Location Temperature probe location value.
@retval TRUE The location value is valid.
@retval FALSE The location value is invalid.
**/
STATIC
BOOLEAN
IsValidTemperatureProbeLocation (
IN UINT8 Location
)
{
return (Location >= SMBIOS_TYPE28_PROBE_LOCATION_MIN) &&
(Location <= SMBIOS_TYPE28_PROBE_LOCATION_MAX);
}
/**
Free any resources allocated when installing SMBIOS Type 28 table.
@param [in] This Pointer to the SMBIOS table generator.
@param [in] TableFactoryProtocol Pointer to the SMBIOS Table Factory
Protocol interface.
@param [in] SmbiosTableInfo Pointer to the SMBIOS table information.
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
Protocol interface.
@param [in] Table Pointer to the SMBIOS table.
@param [in] CmObjectToken Pointer to the CM ObjectToken Array.
@param [in] TableCount Number of SMBIOS tables.
@retval EFI_SUCCESS Resources were freed successfully.
@retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
Manager is less than the Object size for
the requested object.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_NOT_FOUND Could not find information.
@retval EFI_OUT_OF_RESOURCES Could not allocate memory.
@retval EFI_UNSUPPORTED Unsupported configuration.
**/
STATIC
EFI_STATUS
FreeSmbiosType28TableEx (
IN CONST SMBIOS_TABLE_GENERATOR *CONST This,
IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
IN CONST CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
IN SMBIOS_STRUCTURE ***CONST Table,
IN CM_OBJECT_TOKEN **CmObjectToken,
IN CONST UINTN TableCount
)
{
UINTN Index;
SMBIOS_STRUCTURE **TableList;
TableList = *Table;
for (Index = 0; Index < TableCount; Index++) {
if (TableList[Index] != NULL) {
FreePool (TableList[Index]);
}
}
if (*CmObjectToken != NULL) {
FreePool (*CmObjectToken);
}
if (TableList != NULL) {
FreePool (TableList);
}
return EFI_SUCCESS;
}
/** Construct SMBIOS Type 28 Table describing temperature probes.
If this function allocates any resources then they must be freed
in the FreeXXXXTableResources function.
@param [in] This Pointer to the SMBIOS table generator.
@param [in] TableFactoryProtocol Pointer to the SMBIOS Table Factory
Protocol interface.
@param [in] SmbiosTableInfo Pointer to the SMBIOS table information.
@param [in] CfgMgrProtocol Pointer to the Configuration Manager
Protocol interface.
@param [out] Table Pointer to the SMBIOS table.
@param [out] CmObjectToken Pointer to the CM Object Token Array.
@param [out] TableCount Number of tables installed.
@retval EFI_SUCCESS Table generated successfully.
@retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
Manager is less than the Object size for
the requested object.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_NOT_FOUND Could not find information.
@retval EFI_OUT_OF_RESOURCES Could not allocate memory.
@retval EFI_UNSUPPORTED Unsupported configuration.
**/
STATIC
EFI_STATUS
BuildSmbiosType28TableEx (
IN CONST SMBIOS_TABLE_GENERATOR *This,
IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol,
IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo,
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol,
OUT SMBIOS_STRUCTURE ***Table,
OUT CM_OBJECT_TOKEN **CmObjectToken,
OUT UINTN *CONST TableCount
)
{
EFI_STATUS Status;
UINTN Index;
UINTN SmbiosRecordSize;
UINT32 TempProbeCount;
UINT8 Description;
STRING_TABLE StrTable;
SMBIOS_STRUCTURE **TableList;
SMBIOS_TABLE_TYPE28 *SmbiosRecord;
CM_OBJECT_TOKEN *CmObjectList;
CM_ARCH_COMMON_TEMPERATURE_PROBE_INFO *TempProbeInfo;
ASSERT (This != NULL);
ASSERT (SmbiosTableInfo != NULL);
ASSERT (CfgMgrProtocol != NULL);
ASSERT (CmObjectToken != NULL);
ASSERT (Table != NULL);
ASSERT (TableCount != NULL);
ASSERT (SmbiosTableInfo->TableGeneratorId == This->GeneratorID);
if ((This == NULL) || (SmbiosTableInfo == NULL) || (CfgMgrProtocol == NULL) ||
(Table == NULL) || (CmObjectToken == NULL) || (TableCount == NULL) ||
(SmbiosTableInfo->TableGeneratorId != This->GeneratorID))
{
DEBUG ((DEBUG_ERROR, "%a:Invalid Parameter\n ", __func__));
return EFI_INVALID_PARAMETER;
}
*Table = NULL;
*CmObjectToken = NULL;
*TableCount = 0;
TableList = NULL;
SmbiosRecord = NULL;
CmObjectList = NULL;
Status = GetEArchCommonObjTemperatureProbeInfo (
CfgMgrProtocol,
CM_NULL_TOKEN,
&TempProbeInfo,
&TempProbeCount
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: Failed to get temperature probe info. Status = %r\n",
__func__,
Status
));
return Status;
}
if (TempProbeCount == 0) {
DEBUG ((
DEBUG_ERROR,
"%a: No Temperature Probe CM Objects found\n",
__func__
));
return EFI_NOT_FOUND;
}
TableList = (SMBIOS_STRUCTURE **)AllocateZeroPool (sizeof (SMBIOS_STRUCTURE *) * TempProbeCount);
if (TableList == NULL) {
DEBUG ((
DEBUG_ERROR,
"%a: Failed to alloc memory for %u temperature probe table\n",
__func__,
TempProbeCount
));
Status = EFI_OUT_OF_RESOURCES;
goto exitErrorBuildSmbiosType28Table;
}
CmObjectList = AllocateZeroPool (
sizeof (CM_OBJECT_TOKEN) * TempProbeCount
);
if (CmObjectList == NULL) {
DEBUG ((
DEBUG_ERROR,
"%a: Failed to alloc memory for %u temperature probe table\n",
__func__,
TempProbeCount
));
Status = EFI_OUT_OF_RESOURCES;
goto exitErrorBuildSmbiosType28Table;
}
Index = 0;
for (Index = 0; Index < TempProbeCount; Index++) {
Status = StringTableInitialize (&StrTable, SMBIOS_TYPE28_MAX_STRINGS);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"%a: Failed to initialize string table for TempProbeInfo[%u]. Status = %r\n",
__func__,
Index,
Status
));
goto exitErrorBuildSmbiosType28Table;
}
Description = 0;
if (TempProbeInfo[Index].Description[0]) {
Status = StringTableAddString (&StrTable, TempProbeInfo[Index].Description, &Description);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Failed to add Description String %r\n", Status));
ASSERT (!EFI_ERROR (Status));
StringTableFree (&StrTable);
goto exitErrorBuildSmbiosType28Table;
}
}
SmbiosRecordSize = sizeof (SMBIOS_TABLE_TYPE28) + StringTableGetStringSetSize (&StrTable);
SmbiosRecord = (SMBIOS_TABLE_TYPE28 *)AllocateZeroPool (SmbiosRecordSize);
if (SmbiosRecord == NULL) {
Status = EFI_OUT_OF_RESOURCES;
StringTableFree (&StrTable);
goto exitErrorBuildSmbiosType28Table;
}
// Set up the header
SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_TEMPERATURE_PROBE;
SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE28);
if (!IsValidTemperatureProbeStatus (
TempProbeInfo[Index].LocationAndStatus.TemperatureProbeStatus
))
{
DEBUG ((
DEBUG_ERROR,
"%a: Invalid Temperature Probe Status 0x%x for TempProbeInfo[%u]\n",
__func__,
TempProbeInfo[Index].LocationAndStatus.TemperatureProbeStatus,
Index
));
Status = EFI_INVALID_PARAMETER;
StringTableFree (&StrTable);
goto exitErrorBuildSmbiosType28Table;
}
if (!IsValidTemperatureProbeLocation (
TempProbeInfo[Index].LocationAndStatus.TemperatureProbeSite
))
{
DEBUG ((
DEBUG_ERROR,
"%a: Invalid Temperature Probe Location 0x%x for TempProbeInfo[%u]\n",
__func__,
TempProbeInfo[Index].LocationAndStatus.TemperatureProbeSite,
Index
));
Status = EFI_INVALID_PARAMETER;
StringTableFree (&StrTable);
goto exitErrorBuildSmbiosType28Table;
}
SmbiosRecord->Description = Description;
SmbiosRecord->LocationAndStatus = TempProbeInfo[Index].LocationAndStatus;
SmbiosRecord->MaximumValue = TempProbeInfo[Index].MaximumValue;
SmbiosRecord->MinimumValue = TempProbeInfo[Index].MinimumValue;
SmbiosRecord->Resolution = TempProbeInfo[Index].Resolution;
SmbiosRecord->Tolerance = TempProbeInfo[Index].Tolerance;
SmbiosRecord->Accuracy = TempProbeInfo[Index].Accuracy;
SmbiosRecord->OEMDefined = TempProbeInfo[Index].OemDefined;
SmbiosRecord->NominalValue = TempProbeInfo[Index].NominalValue;
Status = StringTablePublishStringSet (
&StrTable,
(CHAR8 *)(SmbiosRecord + 1),
SmbiosRecordSize - sizeof (SMBIOS_TABLE_TYPE28)
);
if (EFI_ERROR (Status)) {
StringTableFree (&StrTable);
goto exitErrorBuildSmbiosType28Table;
}
StringTableFree (&StrTable);
TableList[Index] = (SMBIOS_STRUCTURE *)SmbiosRecord;
CmObjectList[Index] = TempProbeInfo[Index].TemperatureProbeToken;
SmbiosRecord = NULL;
}
*Table = TableList;
*CmObjectToken = CmObjectList;
*TableCount = TempProbeCount;
return EFI_SUCCESS;
exitErrorBuildSmbiosType28Table:
if (TableList != NULL) {
for (Index = 0; Index < TempProbeCount; Index++) {
if (TableList[Index] != NULL) {
FreePool (TableList[Index]);
}
}
FreePool (TableList);
}
if (CmObjectList != NULL) {
FreePool (CmObjectList);
}
if (SmbiosRecord != NULL) {
FreePool (SmbiosRecord);
}
return Status;
}
/** The interface for the SMBIOS Type28 Table Generator.
*/
STATIC
CONST
SMBIOS_TABLE_GENERATOR SmbiosType28Generator = {
// Generator ID
CREATE_STD_SMBIOS_TABLE_GEN_ID (EStdSmbiosTableIdType28),
// Generator Description
L"SMBIOS.TYPE28.GENERATOR",
// SMBIOS Table Type
EFI_SMBIOS_TYPE_TEMPERATURE_PROBE,
NULL,
NULL,
// Build table function.
BuildSmbiosType28TableEx,
// Free function.
FreeSmbiosType28TableEx,
};
/** Register the Generator with the SMBIOS Table Factory.
@param [in] ImageHandle The handle to the image.
@param [in] SystemTable Pointer to the System Table.
@retval EFI_SUCCESS The Generator is registered.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_ALREADY_STARTED The Generator for the Table ID
is already registered.
**/
EFI_STATUS
EFIAPI
SmbiosType28LibConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
Status = RegisterSmbiosTableGenerator (&SmbiosType28Generator);
DEBUG ((
DEBUG_INFO,
"SMBIOS Type 28: Register Generator. Status = %r\n",
Status
));
ASSERT_EFI_ERROR (Status);
return Status;
}
/** Deregister the Generator from the SMBIOS Table Factory.
@param [in] ImageHandle The handle to the image.
@param [in] SystemTable Pointer to the System Table.
@retval EFI_SUCCESS The Generator is deregistered.
@retval EFI_INVALID_PARAMETER A parameter is invalid.
@retval EFI_NOT_FOUND The Generator is not registered.
**/
EFI_STATUS
EFIAPI
SmbiosType28LibDestructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
Status = DeregisterSmbiosTableGenerator (&SmbiosType28Generator);
DEBUG ((
DEBUG_INFO,
"SMBIOS Type 28: Deregister Generator. Status = %r\n",
Status
));
ASSERT_EFI_ERROR (Status);
return Status;
}

View file

@ -0,0 +1,29 @@
## @file
# SMBIOS Type28 Table Generator
#
# Copyright (c) 2026, Arm Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
[Defines]
INF_VERSION = 0x0001001B
BASE_NAME = SmbiosType28LibArm
FILE_GUID = aeb393de-ec41-48af-8d92-d537fe5239e4
VERSION_STRING = 1.0
MODULE_TYPE = DXE_DRIVER
LIBRARY_CLASS = NULL|DXE_DRIVER
CONSTRUCTOR = SmbiosType28LibConstructor
DESTRUCTOR = SmbiosType28LibDestructor
[Sources]
SmbiosType28Generator.c
[Packages]
MdePkg/MdePkg.dec
DynamicTablesPkg/DynamicTablesPkg.dec
[LibraryClasses]
DebugLib
MemoryAllocationLib
SmbiosStringTableLib