# Smbios

## Function Table

| Address | Name | Description |
|---------|------|-------------|
|  | **GetSmbiosStructureSize** |  |
|  | **GetSmbiosTotalTableSize** |  |
|  | **FindStructureByType** |  |
|  | **FindStructureByHandle** |  |
|  | **FindStringByNumber** |  |
|  | **ReplaceStringInStructure** |  |
|  | **ClearSmbiosFieldsByBitmap** |  |
|  | **UpdateEPSHeader** |  |
|  | **UpdateEPSHeader3** |  |
|  | **UpdateSmbiosTableHeader** |  |
|  | **UpdateSmbiosTable** |  |
|  | **DeleteStructureByHandle** |  |
|  | **AddStructureByHandle** |  |
|  | **AddStructureByIndex** |  |
|  | **ReadStructureByType** |  |
|  | **ReadStructureByHandle** |  |
|  | **SmbiosEndOfDxe** |  |
|  | **SmbiosDynamicUpdate** |  |
|  | **UpdateStructuresWithNvramData** |  |
|  | **SmbiosPiAddStructure** |  |
|  | **SmbiosPiUpdateString** |  |
|  | **SmbiosPiRemoveStructure** |  |
|  | **SmbiosPiGetNextStructure** |  |
|  | **SmbiosDriverEntryPoint** |  |
|  | **_ModuleEntryPoint** |  |
| Global | **Data** |  |
| EFI_SYSTEM_TABLE | ***gSystemTable          = NULL;   // qword_9208** |  |
| qword_91F8 | **EFI_RUNTIME_SERVICES_TABLE *gRuntimeServices      = NULL;   // qword_9200** |  |
| qword_9138 | **- SMBIOS table base** |  |
| n0x2000 | **UINT8                       *gSmbiosEntryPoint    = NULL;   // off_8A80 - "_SM_" EPS** |  |
| word_958E | **/ n0xFFFD** |  |
| word_95A0 | **//** |  |
| byte_8C1A | **(in rdata)** |  |
| byte_9158 | **UINT8  gSmbiosFirstDynamicUpdateSeen  = TRUE;       // byte_8BA8** |  |
| Protocol | **GUIDs (referenced via global data)** |  |
| EFI_SMBIOS_PROTOCOL | **GUID:  {0x0358B4B4, 0x4B47, 0x46B7, {0x9C, 0x6C, 0xD4, 0x8F, 0x8A, 0x56, 0x43, 0x55}}** |  |
| AMI_SMBIOS_PROTOCOL | **GUID:   {0x8C3D856A, 0x6D47, 0x4C1B, {0xA0, 0x49, 0x3C, 0x59, 0x0B, 0xD7, 0x0C, 0x28}}** |  |
| extern | **EFI_GUID gEfiSmbiosProtocolGuid;** |  |
| PCD | **Protocol handle** |  |
| VOID | ***mPcdProtocol = NULL;    // qword_9228** |  |
| MM | **PCI Base Protocol handle** |  |
| VOID | ***mPciUsra = NULL;        // qword_9198** |  |
| SMBIOS | **static table FV file GUID** |  |
| extern | **EFI_GUID gSmbiosStaticTableFileGuid;  // unk_8920** |  |
| Debug | **helper: macro to call DebugPrint / sub_4F00** |  |
| sub_4F00 | **is DebugPrint with error level as first arg** |  |
| Forward | **declarations of static helpers** |  |
| Start | **after the formatted area (the header-defined portion)** |  |
| StringArea | **= (UINT8 *)Record + Record->Length;** |  |
| Walk | **through the null-terminated strings area** |  |
| while | **(*StringArea != 0) {** |  |
| Skip | **the terminating null of the last string** |  |
| Now | **StringArea points to the double-null terminator.** |  |
| Include | **the final null.** |  |
| Add | **the terminator structure size** |  |
| TotalSize | **+= GetSmbiosStructureSize ((SMBIOS_STRUCTURE_HEADER *)Cursor);** |  |
| Advance | **to the Nth string (1-based), walking past null-terminated strings** |  |
| for | **(Index = 1; Index < StringNum; Index++) {** |  |
| Skip | **null terminator** |  |
| Check | **if we are still within the structure** |  |
| if | **((UINTN)StrPos >= (UINTN)EndPos) {** |  |
| For | **now, a placeholder that calls down to the internal implementation.** |  |
| The | **actual decompiled logic (sub_1BEC) performs an in-place string swap** |  |
| with | **compaction of the trailing content.** |  |
| Full | **implementation from decompilation would:** |  |
| ASSERT | **(FALSE);  // Not yet fully reimplemented; see sub_1BEC decompilation.** |  |
| Null | **out the specific byte offset (field clearing)** |  |
| Each | **entry is 3 bytes (offset, skip, reserved)** |  |
| SMBIOS | **v2.x EPS update** |  |
| Calculate | **the intermediate checksum value** |  |
| Set | **the SMBIOS table address (lower 32 bits)** |  |
| Count | **the number of SMBIOS structures (excluding the terminator)** |  |
| Cursor | **= gSmbiosTableBase;** |  |
| Include | **the terminator in the count** |  |
| Compute | **the maximum string size across all structures** |  |
| Fill | **EPS fields** |  |
| Compute | **EPS checksum (checksum of bytes 0..length-1 should be 0)** |  |
| Clear | **checksum field first** |  |
| Bytes | **16-30 inclusive** |  |
| Compute | **the intermediate EPS checksum (for the _DMI_ area)** |  |
| Reset | **EPS checksum** |  |
| Write | **the EPS to the legacy region at the pre-allocated address** |  |
| if | **(gSmbiosEntryPoint != NULL) {** |  |
| SMBIOS | **v3.0 EPS update** |  |
| Set | **the table maximum size and address** |  |
| Compute | **EPS checksum (bytes 5..23 sum to zero)** |  |
| Clear | **checksum** |  |
| Write | **the v3 EPS to the pre-allocated region** |  |
| if | **(gSmbiosV3EntryPoint != NULL) {** |  |
| Update | **both EPS headers and re-program to legacy region** |  |
| If | **a legacy region protocol is available, unprotect the E/F segment** |  |
| Update | **v2.x EPS** |  |
| UpdateEPSHeader | **();** |  |
| Update | **v3.0 EPS** |  |
| DEBUG | **((EFI_D_INFO, ":::  SMBIOS - Exit UpdateSmbiosTableHeader  :::\n"));** |  |
| Core | **SMBIOS table update function** |  |
| Debug | **trace** |  |
| DEBUG | **((EFI_D_INFO, "***  SMBIOS - UpdateSmbiosTable  ***\n"));** |  |
| If | **a LegacyRegionProtocol is available, unprotect** |  |
| if | **(Operation == SMBIOS_DELETE_STRUCTURE) {** |  |
| Delete | **the structure at the given pointer** |  |
| DEBUG | **((EFI_D_INFO, "Deleting structure\n"));** |  |
| SmbiosCopyMem | **((VOID *)Structure, (UINT8 *)Structure + StructSize, RemainingSize);** |  |
| Fill | **vacated space with 0xFF** |  |
| SmbiosSetMem | **((UINT8 *)Structure + RemainingSize, -1, StructSize);** |  |
| Unknown | **operation** |  |
| return | **EFI_INVALID_PARAMETER;** |  |
| DEBUG | **((EFI_D_INFO, "Adding structure\n"));** |  |
| Check | **if the handle already exists (for inserts requiring uniqueness)** |  |
| if | **(HandleValue <= 0xFFFD) {** |  |
| Validate | **structure integrity** |  |
| if | **(*(UINT16 *)((UINT8 *)Structure + Size - 2) != 0) {** |  |
| Handle | **special case: Type 4 (Processor) with Length 42 (0x2A)** |  |
| that | **has empty type-specific fields - clip trailing zeros** |  |
| if | **(Structure->Type == SMBIOS_TYPE_PROCESSOR_INFORMATION &&** |  |
| Compact | **away the empty fields at offset 42** |  |
| SmbiosCopyMem | **((UINT8 *)Structure + 42, (UINT8 *)Structure + 48, Size - 48);** |  |
| Allocate | **scratch buffer** |  |
| ScratchBuffer | **= AllocatePool (gSmbiosTableSize + Size);** |  |
| Copy | **existing table into scratch** |  |
| SmbiosCopyMem | **(ScratchBuffer, gSmbiosTableBase, gSmbiosTableSize);** |  |
| Calculate | **current used size** |  |
| NewTableSize | **= GetSmbiosTotalTableSize (gSmbiosTableBase);** |  |
| Check | **if there is enough free space in the table** |  |
| if | **(Size <= gSmbiosTableSize - NewTableSize) {** |  |
| if | **(gSmbiosTableSize - NewTableSize >= Size) {** |  |
| Enough | **space - do in-place operation** |  |
| Need | **to expand the table** |  |
| if | **(!gSmbiosTableExpansionEnabled) {** |  |
| Cannot | **allocate after EndOfDxe** |  |
| DEBUG | **((EFI_D_ERROR** |  |
| Locate | **insertion point** |  |
| Find | **structure by handle to insert before** |  |
| while | **(*WriteCursor != SMBIOS_TERMINATOR_TYPE) {** |  |
| Find | **insertion point by handle value ordering** |  |
| while | **(*WriteCursor != SMBIOS_TERMINATOR_TYPE &&** |  |
| Assign | **the handle** |  |
| if | **(HandleValue > 0xFFFD) {** |  |
| Insert | **the new structure** |  |
| SmbiosCopyMem | **(WriteCursor, Structure, Size);** |  |
| Copy | **the remaining structures after the insertion point** |  |
| Walk | **original table from OldCursor to end to compute trail size** |  |
| while | **(*TrailSrc != SMBIOS_TERMINATOR_TYPE) {** |  |
| terminator | **SmbiosCopyMem (TrailDst, OldCursor, TrailSize);** |  |
| Check | **for handle collision and fix up** |  |
| if | **(HandleValue >= ((SMBIOS_STRUCTURE_HEADER *)CheckCursor)->Handle) {** |  |
| Also | **update the global next handle tracker** |  |
| if | **(HandleValue >= gNextSmbiosHandle) {** |  |
| Free | **scratch and update EPS** |  |
| if | **(ScratchBuffer != NULL) {** |  |
| Restore | **legacy region protection** |  |
| DEBUG | **((EFI_D_INFO, "Status = %r\n", EFI_SUCCESS));** |  |
| If | **the table was reallocated, free the old one and update the pointer** |  |
| Delete | **a structure by handle** |  |
| Specialized | **path for Processor type structures with specific flags** |  |
| Status | **= EFI_UNSUPPORTED;  // Placeholder for sub_26E0 path** |  |
| Add | **a structure by index (insert before given handle)** |  |
| Specialized | **path** |  |
| Status | **= EFI_UNSUPPORTED;** |  |
| Read | **a structure by type** |  |
| Find | **the next available handle** |  |
| Producer | **handle table management** |  |
| If | **the first entry is unused, take it** |  |
| if | **(Entry->Handle == SMBIOS_INVALID_HANDLE) {** |  |
| Search | **for an existing entry with this handle, or an unused slot** |  |
| for | **(Index = 0; Index < SMBIOS_PRODUCER_HANDLE_COUNT; Index++) {** |  |
| Found | **existing entry for this handle (update in place)** |  |
| Found | **an empty slot** |  |
| Table | **full; silently fail (original behavior)** |  |
| return | **NULL;** |  |
| EndOfDxe | **Event Handler** |  |
| Close | **the event (it is a one-shot notification)** |  |
| Allocate | **a scratch buffer to work with the SMBIOS table** |  |
| ScratchBuffer | **= AllocatePool (gSmbiosTableSize);** |  |
| Locate | **LegacyRegionProtocol to unprotect E/F segment for EPS programming** |  |
| Status | **= gBS->LocateProtocol (&gEfiLegacyRegionProtocolGuid, NULL, (VOID **)&LegacyRegion);** |  |
| Continue | **without legacy region programming if protocol unavailable** |  |
| LegacyRegion | **= NULL;** |  |
| Copy | **the SMBIOS table to scratch for processing** |  |
| Update | **both EPS headers and program to legacy region** |  |
| Lock | **the table (no further expansion allowed)** |  |
| gSmbiosTableExpansionEnabled | **= FALSE;** |  |
| Close | **the event** |  |
| Create | **onboard device data (type 41 structures)** |  |
| Create | **onboard device extended info (type 42)** |  |
| Populate | **runtime-configurable structures from NVRAM** |  |
| Perform | **dynamic update of SMBIOS structures (types populated from data sources)** |  |
| DEBUG | **((EFI_D_INFO, "***  SMBIOS - DynamicUpdateStructures  ***\n"));** |  |
| First | **time through: populate from firmware data sources** |  |
| After | **all dynamic updates, trigger memory type information update** |  |
| Check | **if system is in S5/S6 state for memory data decisions** |  |
| Signal | **the new table to listeners** |  |
| Close | **and re-create the periodic event** |  |
| Update | **entry points** |  |
| Decompiled | **logic from sub_B70:** |  |
| DEBUG | **((EFI_D_INFO, "***  SMBIOS - UpdateStructuresWithNvramData  ***\n"));** |  |
| Placeholder | **for the full NVRAM update logic.** |  |
| The | **decompiled function (sub_B70, ~800 instructions) performs:** |  |
| PI | **SMBIOS Protocol implementation** |  |
| if | **(!FindNextAvailableHandle (0) /* check availability */) {** |  |
| Use | **the provided handle (replace existing if applicable)** |  |
| if | **(!AddStructureByHandle (Structure->Handle, (UINT8 *)Structure, StructSize)) {** |  |
| Locate | **the structure by handle** |  |
| if | **(!FindStructureByHandle (&Cursor, *Handle)) {** |  |
| Validate | **string number** |  |
| Compute | **new string length** |  |
| NewStringLen | **= 0;** |  |
| ScratchBuffer | **= AllocatePool (StructSize + NewStringLen + 1);** |  |
| Copy | **structure to scratch** |  |
| SmbiosCopyMem | **(ScratchBuffer, Cursor, StructSize);** |  |
| Replace | **the string** |  |
| ReplaceStringInStructure | **(ScratchBuffer, *StringNumber, String);** |  |
| Delete | **old structure** |  |
| DEBUG | **((EFI_D_INFO, "Deleting structure with handle = %x\n", *Handle));** |  |
| Add | **updated structure** |  |
| DEBUG | **((EFI_D_INFO, "Adding structure with handle = %x\n", *Handle));** |  |
| Clean | **up** |  |
| FreePool | **(ScratchBuffer);** |  |
| Remove | **from producer handle table (compact entries)** |  |
| EntryToRemove | **= SMBIOS_PRODUCER_HANDLE_COUNT;** |  |
| Compact | **the table** |  |
| SmbiosCopyMem | **(** |  |
| Clear | **the last entry** |  |
| No | **type filter - just advance past current handle** |  |
| if | **(*Handle != SMBIOS_STARTING_HANDLE) {** |  |
| Advance | **to next** |  |
| if | **(*Cursor == SMBIOS_TERMINATOR_TYPE) {** |  |
| Type | **filter active** |  |
| Advance | **past current** |  |
| Find | **next matching type** |  |
| Found | **a structure** |  |
| if | **(*Cursor != SMBIOS_TERMINATOR_TYPE) {** |  |
| Look | **up producer handle** |  |
| if | **(ProducerHandle != NULL) {** |  |
| Search | **producer handle table** |  |
| if | **(*Handle != SMBIOS_TERMINATOR_TYPE) {** |  |
| No | **more structures** |  |
| Driver | **Entry Point** |  |
| Initialize | **global service pointers** |  |
| if | **(gSystemTable == NULL) {** |  |
| 1 | **page = 4KB, more than enough for 31 bytes** |  |
| Initialize | **the EPS memory with the "_SM_" signature** |  |
| SmbiosCopyMem | **(gSmbiosEntryPoint, SMBIOS_ENTRY_POINT_SIG, 31);** |  |
| Initialize | **the v3 EPS memory with the "_SM3_" signature** |  |
| SmbiosCopyMem | **(gSmbiosV3EntryPoint, SMBIOS_V3_ENTRY_POINT_SIG, 24);** |  |
| Read | **"Setup" variable** |  |
| DataSize | **= sizeof (SetupVar);** |  |
| Read | **"SecureBoot" variable** |  |
| DataSize | **= sizeof (BOOLEAN);** |  |
| Locate | **all handles that support FirmwareVolume2 protocol** |  |
| Search | **each FV for the SMBIOS static table file** |  |
| for | **(Index = 0; Index < NumberOfHandles; Index++) {** |  |
| Read | **the raw section from the FV file** |  |
| Found | **the static SMBIOS data section** |  |
| StaticTableFound | **= TRUE;** |  |
| Skip | **section header** |  |
| Locate | **the last handle in the static table and fix up** |  |
| Update | **the terminator handle to the next available** |  |
| No | **static table; start with an empty table (just a terminator)** |  |
| StaticTableSize | **= 0x2000;   // Use default table size** |  |
| Initialize | **to 0xFF** |  |
| SmbiosSetMem | **(gSmbiosTableBase, -1, gSmbiosTableSize);** |  |
| Copy | **the static table into the new buffer** |  |
| SmbiosCopyMem | **(gSmbiosTableBase, StaticTableData, StaticTableSize);** |  |
| Free | **the FV section data** |  |
| DEBUG | **((EFI_D_INFO, "Freeing Buffer\n"));** |  |
| Create | **an empty terminator structure** |  |
| Length | **= 4 bytes (Type, Length, Handle[2])** |  |
| Read | **any NVRAM-based structures from Setup variable** |  |
| Populate | **structures from the NVRAM data store** |  |
| DEBUG | **((EFI_D_INFO, "Before UpdateStructuresWithNvramData\n"));** |  |
| Register | **the EndOfDxe event group notification** |  |
| Status | **= gBS->CreateEventEx (** |  |
| Initialize | **the producer handle table to invalid state** |  |
| Walk | **the table and register each existing structure's handle** |  |
| Update | **both EPS headers** |  |
| the | **.data section (off_8A38). This is a reconstructed representation.** |  |
| SmbiosProtocol | **= AllocateZeroPool (sizeof (SMBIOS_PROTOCOL));** |  |
| Library | **constructors (ProcessLibraryConstructorList) are called** |  |
| in | **the AutoGen before reaching the entry function body.** |  |
| ProcessLibraryConstructorList | **(ImageHandle, SystemTable);** |  |
| Call | **the real driver entry point** |  |
| return | **SmbiosDriverEntryPoint (ImageHandle, SystemTable);** |  |

---
*Generated by HR650X BIOS Decompilation Project*