| 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