/**
* @file Smbios.h
* @brief SMBIOS DXE driver - Header
*
* Manages SMBIOS tables in the UEFI environment. Provides services for
* installing, updating, and enumerating SMBIOS structures (both 2.x and 3.0).
*
* Source path: AmiCompatibilityPkg\Smbios\Smbios.c
*
* (Decompiled from Smbios.efi - HR650X BIOS)
*/
#ifndef __SMBIOS_H__
#define __SMBIOS_H__
#include <Uefi.h>
#include <Protocol/Smbios.h>
#include <Protocol/SmbiosAmi.h>
//
// SMBIOS Entry Point signatures
//
#define SMBIOS_ENTRY_POINT_SIG "_SM_"
#define SMBIOS_V3_ENTRY_POINT_SIG "_SM3_"
//
// SMBIOS structure terminator type
//
#define SMBIOS_TERMINATOR_TYPE 127
//
// Default SMBIOS table size (8KB)
//
#define SMBIOS_DEFAULT_TABLE_SIZE 0x2000
//
// Number of producer handle table entries
//
#define SMBIOS_PRODUCER_HANDLE_COUNT 512
//
// Invalid/unused handle value
//
#define SMBIOS_INVALID_HANDLE 0xFFFF
#define SMBIOS_STARTING_HANDLE 0xFFFE
//
// SMBIOS structure types (key)
//
#define SMBIOS_TYPE_BIOS_CHARACTERISTICS 0
#define SMBIOS_TYPE_SYSTEM_INFORMATION 1
#define SMBIOS_TYPE_BASEBOARD_INFORMATION 2
#define SMBIOS_TYPE_SYSTEM_ENCLOSURE 3
#define SMBIOS_TYPE_PROCESSOR_INFORMATION 4
#define SMBIOS_TYPE_CACHE_INFORMATION 7
#define SMBIOS_TYPE_SYSTEM_SLOTS 9
#define SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY 16
#define SMBIOS_TYPE_MEMORY_DEVICE 17
#define SMBIOS_TYPE_ONBOARD_DEVICES 41
#define SMBIOS_TYPE_ONBOARD_DEVICES_EXT 42
//
// SMBIOS update operation types
//
#define SMBIOS_ADD_STRUCTURE 0
#define SMBIOS_DELETE_STRUCTURE 1
#define SMBIOS_INSERT_STRUCTURE 2
//
// SMBIOS v2.x EPS structure (31 bytes)
//
#pragma pack(1)
typedef struct {
UINT8 AnchorString[4]; // "_SM_"
UINT8 Checksum;
UINT8 Length; // 0x1F (31)
UINT8 MajorVersion;
UINT8 MinorVersion;
UINT16 MaxStructureSize;
UINT8 EntryPointRevision;
UINT8 FormattedArea[5];
UINT8 IntermediateAnchor[5]; // "_DMI_"
UINT8 IntermediateChecksum;
UINT16 TableLength;
UINT32 TableAddress;
UINT16 NumberOfSmbiosStructures;
UINT8 SmbiosBcdRevision;
} SMBIOS_ENTRY_POINT;
#pragma pack()
//
// SMBIOS v3.0 EPS structure (24 bytes)
//
#pragma pack(1)
typedef struct {
UINT8 AnchorString[5]; // "_SM3_"
UINT8 Checksum;
UINT8 Length; // 0x18 (24)
UINT8 MajorVersion;
UINT8 MinorVersion;
UINT8 DocRev;
UINT8 EntryPointRevision;
UINT8 Reserved;
UINT32 TableMaximumSize;
UINT64 TableAddress;
} SMBIOS_V3_ENTRY_POINT;
#pragma pack()
//
// SMBIOS structure header (for raw parsing)
//
#pragma pack(1)
typedef struct {
UINT8 Type;
UINT8 Length;
UINT16 Handle;
} SMBIOS_STRUCTURE_HEADER;
#pragma pack()
//
// Producer handle table entry
// Maps SMBIOS structure handles to producer EFI_HANDLEs
//
#pragma pack(1)
typedef struct {
UINT16 Handle; // SMBIOS structure handle, -1 if unused
UINT64 Reserved; // Padding
EFI_HANDLE ImageHandle; // The image that produced this structure
} PRODUCER_HANDLE_ENTRY;
#pragma pack()
//
// Global data (extern declarations)
//
extern EFI_SYSTEM_TABLE *gSystemTable;
extern EFI_BOOT_SERVICES *gBootServices;
extern EFI_RUNTIME_SERVICES_TABLE *gRuntimeServices;
extern UINT8 *gSmbiosTableBase; // qword_9138 - Base of SMBIOS table
extern UINT16 gSmbiosTableSize; // n0x2000 - Allocated table size
extern UINT8 *gSmbiosEntryPoint; // off_8A80 - "_SM_" EPS
extern UINT8 *gSmbiosV3EntryPoint; // i / aSm3 - "_SM3_" EPS
extern UINT16 gNextSmbiosHandle; // word_958E / n0xFFFD
extern UINT8 gSmbiosTableExpansionEnabled; // byte_8C1A
extern UINT8 gSmbiosTableLocked; // byte_9158
extern PRODUCER_HANDLE_ENTRY gProducerHandleTable[SMBIOS_PRODUCER_HANDLE_COUNT]; // word_95A0
//
// Protocol interfaces
//
typedef struct _SMBIOS_PROTOCOL SMBIOS_PROTOCOL;
typedef struct _SMBIOS_AMI_PROTOCOL SMBIOS_AMI_PROTOCOL;
//
// SMBIOS PI Protocol (EFI_SMBIOS_PROTOCOL)
//
struct _SMBIOS_PROTOCOL {
UINT64 Revision;
EFI_STATUS (EFIAPI *Add)( SMBIOS_PROTOCOL *This, EFI_HANDLE ImageHandle,
SMBIOS_STRUCTURE_HEADER *Structure, SMBIOS_HANDLE *Key);
EFI_STATUS (EFIAPI *UpdateString)(SMBIOS_PROTOCOL *This, SMBIOS_HANDLE *Handle,
UINT8 *StringNumber, UINT8 *String);
EFI_STATUS (EFIAPI *Remove)( SMBIOS_PROTOCOL *This, SMBIOS_HANDLE Handle);
EFI_STATUS (EFIAPI *GetNext)( SMBIOS_PROTOCOL *This, SMBIOS_HANDLE *Handle,
UINT8 *Type, SMBIOS_STRUCTURE_HEADER **Record,
EFI_HANDLE *ProducerHandle);
};
//
// SMBIOS AMI Protocol
//
struct _SMBIOS_AMI_PROTOCOL {
UINT64 Revision;
// Custom AMI extensions beyond PI spec
};
//
// Function prototypes
//
/**
* UEFI Driver Entry Point
*/
EFI_STATUS
EFIAPI
SmbiosDriverEntryPoint(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
/**
* Update the SMBIOS v2.x and v3.0 entry point structures.
* Recalculates checksums, updates table address, and writes to SMBIOS area.
*/
VOID
UpdateSmbiosTableHeader(
VOID
);
/**
* Update the SMBIOS v2.x EPS header.
*/
VOID
UpdateEPSHeader(
VOID
);
/**
* Update the SMBIOS v3.0 EPS header.
*/
VOID
UpdateEPSHeader3(
VOID
);
/**
* Add, delete, or insert a SMBIOS structure in the table.
*
* @param[in] Operation 0=Add, 1=Delete, 2=Insert (before handle)
* @param[in] Handle Target handle (for insert/delete)
* @param[in] Structure Pointer to SMBIOS structure data
* @param[in] Size Size of the structure data
* @param[in] HandleValue Handle value to assign
* @return EFI_STATUS
*/
EFI_STATUS
UpdateSmbiosTable(
IN UINTN Operation,
IN SMBIOS_HANDLE *Handle OPTIONAL,
IN SMBIOS_STRUCTURE_HEADER *Structure,
IN UINT16 Size,
IN SMBIOS_HANDLE HandleValue
);
/**
* Handle EndOfDxe event - locks the SMBIOS table regions and programs
* the SMBIOS entry points into legacy (E/F segment) memory.
*/
VOID
EFIAPI
SmbiosEndOfDxe(
IN EFI_EVENT Event,
IN VOID *Context
);
/**
* Handle SMBIOS dynamic update notification.
* Called at EndOfDxe to populate onboard device data and NVRAM-based structures.
*/
VOID
EFIAPI
SmbiosDynamicUpdate(
IN EFI_EVENT Event,
IN VOID *Context
);
/**
* Update SMBIOS structures from NVRAM data.
*/
VOID
UpdateStructuresWithNvramData(
VOID
);
//
// Internal helper functions
//
/**
* Calculate the total size of a SMBIOS structure row
* (header + strings + terminating double-null).
*/
UINT16
GetSmbiosStructureSize(
IN SMBIOS_STRUCTURE_HEADER *Record
);
/**
* Calculate the total table size (sum of all structure rows + terminator).
*/
UINT16
GetSmbiosTotalTableSize(
IN UINT8 *TableBase
);
/**
* Find a SMBIOS structure by type.
*
* @param[in,out] TableBase On input, start of search; on output, points to found structure or end.
* @param[in] Type SMBIOS structure type to find.
* @return TRUE if found.
*/
BOOLEAN
FindStructureByType(
IN OUT UINT8 **TableBase,
IN UINT8 Type
);
/**
* Find a SMBIOS structure by handle.
*
* @param[in,out] TableBase On input, start of search; on output, points to found structure or end.
* @param[in] Handle SMBIOS handle to find.
* @return TRUE if found.
*/
BOOLEAN
FindStructureByHandle(
IN OUT UINT8 **TableBase,
IN UINT16 Handle
);
/**
* Advance to the Nth string in a SMBIOS structure.
*
* @param[in,out] Record Pointer to update to point to the Nth string.
* @param[in] StringNum String number (1-based).
* @return TRUE if the string position is within bounds.
*/
BOOLEAN
FindStringByNumber(
IN OUT SMBIOS_STRUCTURE_HEADER **Record,
IN UINT8 StringNum
);
/**
* Replace a string in a SMBIOS structure, truncating trailing content.
*
* @param[in,out] Record The structure to modify.
* @param[in] StringNum 1-based string number to replace.
* @param[in] String New null-terminated string.
*/
VOID
ReplaceStringInStructure(
IN OUT UINT8 *Record,
IN UINT8 StringNum,
IN UINT8 *String
);
/**
* Update string reference counts in a SMBIOS structure.
*/
VOID
UpdateStringRefCount(
IN UINT8 *StructureData,
IN UINT16 Handle
);
/**
* Clear fields in SMBIOS structure referenced by a bitmap.
*/
VOID
ClearSmbiosFieldsByBitmap(
IN OUT UINT8 *StructureData,
IN UINT32 Bitmap,
IN UINT8 *DefaultFieldMap
);
/**
* Delete a SMBIOS structure by handle.
*
* @param[in] Handle SMBIOS handle to delete.
* @return EFI_STATUS
*/
EFI_STATUS
DeleteStructureByHandle(
IN SMBIOS_HANDLE Handle
);
/**
* Add a SMBIOS structure by handle.
*
* @param[in] Handle SMBIOS handle to assign.
* @param[in] Record Structure data.
* @param[in] Size Structure data size.
* @return EFI_STATUS
*/
EFI_STATUS
AddStructureByHandle(
IN SMBIOS_HANDLE Handle,
IN UINT8 *Record,
IN UINT16 Size
);
/**
* Add a SMBIOS structure by index (insert before given handle).
*/
EFI_STATUS
AddStructureByIndex(
IN SMBIOS_HANDLE InsertBeforeHandle,
IN UINT8 *Record,
IN UINT16 Size,
IN SMBIOS_HANDLE Handle
);
/**
* Read a SMBIOS structure by type.
*/
EFI_STATUS
ReadStructureByType(
IN UINT8 Type,
OUT UINT8 **Buffer,
OUT UINT16 *Size
);
/**
* Read a SMBIOS structure by handle.
*/
EFI_STATUS
ReadStructureByHandle(
IN SMBIOS_HANDLE Handle,
OUT UINT8 **Buffer,
OUT UINT16 *Size
);
/**
* Find the next available (unused) SMBIOS handle.
*/
SMBIOS_HANDLE
FindNextAvailableHandle(
VOID
);
/**
* Register a producer handle for a SMBIOS structure handle.
*/
PRODUCER_HANDLE_ENTRY *
RegisterProducerHandle(
IN SMBIOS_HANDLE SmbiosHandle,
IN EFI_HANDLE ImageHandle
);
//
// PI SMBIOS Protocol API
//
EFI_STATUS
EFIAPI
SmbiosPiAddStructure(
IN SMBIOS_PROTOCOL *This,
IN EFI_HANDLE ProducerHandle,
IN OUT SMBIOS_STRUCTURE_HEADER *Structure,
OUT SMBIOS_HANDLE *Key OPTIONAL
);
EFI_STATUS
EFIAPI
SmbiosPiUpdateString(
IN SMBIOS_PROTOCOL *This,
IN OUT SMBIOS_HANDLE *Handle,
IN UINT8 *StringNumber,
IN UINT8 *String
);
EFI_STATUS
EFIAPI
SmbiosPiRemoveStructure(
IN SMBIOS_PROTOCOL *This,
IN SMBIOS_HANDLE Handle
);
EFI_STATUS
EFIAPI
SmbiosPiGetNextStructure(
IN SMBIOS_PROTOCOL *This,
IN OUT SMBIOS_HANDLE *Handle,
IN UINT8 *Type OPTIONAL,
OUT SMBIOS_STRUCTURE_HEADER **Record,
OUT EFI_HANDLE *ProducerHandle OPTIONAL
);
#endif // __SMBIOS_H__