# SmbiosDataUpdateDxeLightningRidgeEXRP

## Function Table

| Address | Name | Description |
|---------|------|-------------|
|  | **ReadUnaligned64** |  |
|  | **WriteUnaligned64** |  |
|  | **AsciiStrLen** |  |
|  | **StrLen** |  |
|  | **AsciiStrnLenS** |  |
|  | **UnicodeStrnToAsciiStrS** |  |
|  | **ReadUnaligned32** |  |
|  | **CompareGuid** |  |
|  | **FreePool** |  |
|  | **GetConfigTable** |  |
|  | **GetPlatformLang** |  |
|  | **DebugPrint** |  |
|  | **AssertHandler** |  |
|  | **AddSmbiosString** |  |
|  | **FindFirstSmbiosString** |  |
|  | **RemoveAndAddSmbiosString** |  |
|  | **RemoveAllSmbiosStringsOfType** |  |
|  | **GetSmbiosStructuresAfterField** |  |
|  | **UpdateSmbiosStringField** |  |
|  | **BuildSmbiosStringRecord** |  |
|  | **BuildSmbiosType9Record** |  |
|  | **BuildSmbiosType41Record** |  |
|  | **MmPciWriteConfig** |  |
|  | **SmbiosDataUpdateDispatch** |  |
|  | **SmbiosDataUpdateEntry** |  |
|  | **SmbiosDataUpdateInit** |  |
|  | **ModuleEntryPoint** |  |
| Global | **UEFI system table pointers (initialized by SmbiosDataUpdateInit)** |  |
| EFI_HANDLE | **gImageHandle = NULL;        ///< 0x3928 - EFI image handle** |  |
| Cached | **protocol/state pointers** |  |
| VOID | ***mDebugProtocol = NULL;          ///< 0x3938 - Cached DebugLib protocol** |  |
| Global | **state** |  |
| EFI_GUID | **mSmbiosConfigGuid;           ///< 0x38F0 - Board-specific SMBIOS config GUID** |  |
| GUID | **Definitions (protocol and config identifiers)** |  |
| GUID | **for the UBA config protocol opened from ImageHandle.** |  |
| Contains | **board-specific SMBIOS configuration data.** |  |
| static | **EFI_GUID mUbaConfigProtocolGuid = {** |  |
| GUID | **for "en-US" default language (RFC 4646).** |  |
| Used | **as default platform language when PlatformLang variable is not set.** |  |
| static | **UINT16 mDefaultLanguage[] = L"en-US";** |  |
| HOB | **list GUID for configuration table lookup.** |  |
| static | **EFI_GUID mHobListGuid = {** |  |
| DXE | **Services Table GUID.** |  |
| static | **EFI_GUID mDxeServicesTableGuid = {** |  |
| Global | **Variable GUID for UEFI standard variables (PlatformLang).** |  |
| static | **EFI_GUID mGlobalVariableGuid = {** |  |
| DebugLib | **protocol GUID.** |  |
| static | **EFI_GUID mDebugLibProtocolGuid = {** |  |
| HII | **Font protocol GUID.** |  |
| static | **EFI_GUID mHiiFontProtocolGuid = {** |  |
| HII | **Database protocol GUID.** |  |
| static | **EFI_GUID mHiiDatabaseProtocolGuid = {** |  |
| HII | **Package List protocol GUID.** |  |
| static | **EFI_GUID mHiiPackageListProtocolGuid = {** |  |
| HII | **String protocol GUID.** |  |
| static | **EFI_GUID mHiiStringProtocolGuid = {** |  |
| static | **EFI_GUID mSmbiosProtocolGuid = {** |  |
| MM | **PCIe Base protocol GUID.** |  |
| static | **EFI_GUID mMmPciBaseProtocolGuid = {** |  |
| UBA | **SMBIOS Data protocol GUID.** |  |
| This | **protocol is used to register SMBIOS data update configuration.** |  |
| static | **EFI_GUID mUbaSmbiosDataProtocolGuid = {** |  |
| SMBIOS | **string package GUID for HII registration.** |  |
| Identifies | **this driver's HII string package for SMBIOS strings.** |  |
| static | **EFI_GUID mSmbiosStringPackageGuid = {** |  |
| SMBIOS | **String Descriptor Table** |  |
| SMBIOS | **Type 2 (Baseboard) string descriptor table (30 entries).** |  |
| Each | **entry is 10 bytes: {Type, FieldNum, StringId(16), Encoding, Offset, MaxLen, Flags, Reserved(16)}** |  |
| These | **descriptors define which SMBIOS Type 2 string fields to update and** |  |
| which | **HII string tokens to use for localized string lookup.** |  |
| SMBIOS | **Type 2 fields: Manufacturer, ProductName, Version, SerialNumber** |  |
| static | **CONST SMBIOS_STRING_DESC mSmbiosType2Descriptors[30] = {** |  |
| Entry | **0:  Type=8 (Type2), Field=3, StrId=0x0002, Enc=0x08, Off=8, Max=3, Flag=0x08000000** |  |
| Entry | **1:  Type=8 (Type2), Field=4, StrId=0x04, Enc=0x10, Off=8, Max=16, Flag=5** |  |
| Entries | **2-29 follow the same pattern with different field numbers** |  |
| string | **IDs, encodings, offsets, max lengths, and flags.** |  |
| Full | **descriptor table details available in the disassembly at sub_77C.** |  |
| The | **table is a 300-byte (30 * 10) embedded constant array.** |  |
| Key | **field numbers: 5 (Manufacturer), 6 (ProductName), 7 (Version)** |  |
| 8 | **(SerialNumber), 9 (AssetTag), 10-29 (additional board strings).** |  |
| Forward | **Declarations of Internal Functions** |  |
| Zero | **8-byte aligned chunks first.** |  |
| SetMem | **(Buf, Length & ~7, 0);** |  |
| Zero | **remaining bytes (0-7).** |  |
| SetMem | **(&Buf[Length & ~7], Length & 7, 0);** |  |
| Copy | **backwards from the end to avoid corruption.** |  |
| Src | **= &Src[Length - 1];** |  |
| Copy | **remaining 8-byte chunks backward** |  |
| No | **overlap or destination before source: copy forward.** |  |
| CountQwords | **= Length >> 3;** |  |
| Copy | **8-byte aligned chunks.** |  |
| CopyMem | **(Dst, Src, CountQwords * 8);** |  |
| Copy | **remaining bytes.** |  |
| CopyMem | **(Dst, Src, CountRemaining);** |  |
| Memory | **and String Library Functions** |  |
| Check | **for overlap between source and destination buffers.** |  |
| Overlap | **= FALSE;** |  |
| Overlap | **error, treated as buffer error** |  |
| Convert | **each UCS-2 character to ASCII.** |  |
| while | **(*Src != 0) {** |  |
| GUID | **Manipulation** |  |
| Memory | **Allocation** |  |
| Status | **= gBootServices->AllocatePool (** |  |
| Status | **= gBootServices->FreePool (Buffer);** |  |
| Configuration | **Table Access** |  |
| Compare | **GUIDs using 128-bit comparison.** |  |
| if | **(CompareGuid (&ConfigTable[Index].VendorGuid, TableGuid)) {** |  |
| HOB | **List Access** |  |
| Return | **cached pointer if already initialized.** |  |
| HobList | **= mHobList;** |  |
| Find | **the HOB list in the configuration table.** |  |
| Status | **= GetConfigTable (&mHobListGuid, &mHobList);** |  |
| Verify | **the HOB list was found.** |  |
| if | **(mHobList == NULL) {** |  |
| Language | **and Variable Services** |  |
| Call | **GetVariable with zero size first to get required buffer size.** |  |
| Status | **= gRuntimeServices->GetVariable (** |  |
| Allocate | **buffer of required size.** |  |
| LangBuffer | **= AllocatePool (BufferSize);** |  |
| Read | **the variable data.** |  |
| Determine | **the length of the language to check.** |  |
| If | **full match mode (LanguageMatch != 0) is disabled (0)** |  |
| use | **the full string; otherwise truncate to 3 characters.** |  |
| if | **(LanguageMatch == 0) {** |  |
| Full | **match: use the complete string length, but truncated** |  |
| to | **3 chars if zero mode is off and string is long.** |  |
| SupportedLen | **= 0;** |  |
| Scan | **the supported languages string for a match.** |  |
| if | **(LanguageMatch != 0) {** |  |
| Full | **match mode: iterate through each language list entry.** |  |
| Supported | **= SupportedLanguages;** |  |
| Skip | **';' separators.** |  |
| while | **(*Supported == ';') {** |  |
| Get | **the length of this supported language entry.** |  |
| Match | **found - allocate buffer and copy the language.** |  |
| ResultLen | **= SupportedLen + 1;** |  |
| Short | **match mode: truncate language to 3 characters, compare.** |  |
| if | **(CheckLen <= 3) {** |  |
| Scan | **supported languages.** |  |
| If | **full check fails, try truncating to 3 chars.** |  |
| if | **(CheckLen > 3 && 3 <= SupportedLen) {** |  |
| Handle | **RFC 4646 language tags with '-' separator.** |  |
| while | **(Supported[SupportedLen] == '-') {** |  |
| Move | **to next language string in varargs.** |  |
| LangToCheck | **= VA_ARG (Args, CONST CHAR8 *);** |  |
| Debug | **Output** |  |
| DebugProtocol | **= mDebugProtocol;** |  |
| Allocate | **pool as a probe. The allocation size is 31 bytes** |  |
| PoolSize | **= MEMORY_TYPE_BOOT_SERVICES_DATA;** |  |
| This | **is a non-standard check unique to this implementation.** |  |
| if | **((UINTN)mDebugProtocol > 0x10) {** |  |
| Status | **= gBootServices->LocateProtocol (** |  |
| Suspicious | **allocation pointer - treat as failure.** |  |
| mDebugProtocol | **= NULL;** |  |
| Get | **the DebugLib protocol; if not available, skip the print.** |  |
| DebugProtocol | **= GetDebugLibProtocol ();** |  |
| Read | **the platform SKU from RTC CMOS register 0x4B.** |  |
| The | **NMI-disable bit (0x80) is preserved in the index write.** |  |
| IoWrite8 | **(RTC_CMOS_INDEX_PORT, (IoRead8 (RTC_CMOS_INDEX_PORT) & 0x80) | RTC_CMOS_INDEX_SKU);** |  |
| Determine | **effective SKU:** |  |
| EffectiveSku | **= CmosSku;** |  |
| Read | **platform info register for IIO mode detection.** |  |
| Bit | **1 of 0xFDAF0490 indicates IIO configuration mode.** |  |
| EffectiveSku | **= (*(volatile UINT8 *)PLATFORM_INFO_REGISTER & 0x02) | 0x01;** |  |
| Map | **platform SKU to debug level filter mask.** |  |
| Valid | **SKU range (1-4 maps to 0-3).** |  |
| FilterMask | **= UBA_DEBUG_ERROR;   // Default: only errors** |  |
| If | **the requested debug level passes the filter, call DebugPrint.** |  |
| if | **((FilterMask & DebugLevel) != 0) {** |  |
| DebugProtocol | **layout:** |  |
| Call | **DebugProtocol->Assert (at offset +8).** |  |
| HII | **Protocol Services** |  |
| Call | **with NULL buffer to get required size.** |  |
| Now | **get the actual string.** |  |
| Status | **= ((EFI_HII_GET_STRING_INFO)((VOID **)mHiiFont)[3])(** |  |
| Validate | **parameters.** |  |
| if | **(HiiHandle == NULL) {** |  |
| Get | **the supported languages for this HII string package.** |  |
| SupportedLanguages | **= GetHiiSupportedLanguages (HiiHandle, StringId, Type, MaxLen);** |  |
| Get | **the current platform language.** |  |
| Match | **the platform language against supported languages.** |  |
| Use | **"en-US" as default language for matching.** |  |
| Fall | **back to the first supported language.** |  |
| MatchedLanguage | **= GetSupportedLanguage (** |  |
| Get | **the localized string size by calling HiiFont->StringToImage (offset +8)** |  |
| with | **NULL buffer to get required size.** |  |
| Allocate | **buffer for the string.** |  |
| ResultString | **= AllocatePool (StringSize);** |  |
| Get | **the actual string.** |  |
| Status | **= ((EFI_HII_STRING_TO_IMAGE)((VOID **)mHiiFont)[1])(** |  |
| Clean | **up temporary allocations.** |  |
| FreePool | **(SupportedLanguages);** |  |
| ResultString | **was allocated separately, keep it** |  |
| Call | **StringToImage with NULL buffer to get required size.** |  |
| Allocate | **buffer.** |  |
| String | **= AllocatePool (Size);** |  |
| if | **(Guid == NULL) {** |  |
| If | **no string entries, return NULL handle.** |  |
| if | **(StringPackage == NULL) {** |  |
| Calculate | **total package size.** |  |
| Each | **entry header has size-4 in the first 4 bytes.** |  |
| We | **need to sum all entry sizes (excluding the 4-byte header** |  |
| contribution | **counted as size-4 per entry).** |  |
| Entry | **= StringPackage;** |  |
| Allocate | **buffer for the entire package list (header + data).** |  |
| The | **HII package list header is sizeof(EFI_HII_PACKAGE_LIST_HEADER)** |  |
| which | **includes a GUID (16 bytes) and package length (24 bytes total).** |  |
| DataSize | **= TotalSize + sizeof (EFI_HII_PACKAGE_LIST_HEADER);** |  |
| Fill | **in the package list header.** |  |
| Copy | **the GUID to the beginning of the package list.** |  |
| CopyGuid | **((EFI_GUID *)PackageData, Guid);** |  |
| Copy | **all package entries.** |  |
| Add | **the terminating 4-byte zero entry.** |  |
| CopyMem | **(Dst, &mZeroGuid, 4);** |  |
| Call | **HiiDatabase->NewPackageList (at offset +0 of qword_3968).** |  |
| Get | **or locate the SMBIOS protocol.** |  |
| SmbiosProto | **= mSmbiosProtocol3;** |  |
| Initialize | **handle to "uninitialized" (0xFFFE).** |  |
| The | **SMBIOS AddString function at protocol offset 0 uses:** |  |
| Handle | **= SMBIOS_HANDLE_UNINITIALIZED;** |  |
| SmbiosProto | **= mSmbiosProtocol1;** |  |
| Search | **for the first matching string.** |  |
| The | **SMBIOS protocol GetNext function at offset +24 enumerates strings:** |  |
| SearchType | **= TypeId;** |  |
| Find | **and remove the current string, then add the replacement.** |  |
| Status | **= FindFirstSmbiosString (TypeId, &Handle);** |  |
| Remove | **the old string at protocol offset +16.** |  |
| Add | **the new string at protocol offset 0.** |  |
| SmbiosProto | **= mSmbiosProtocol2;** |  |
| Locate | **the SMBIOS protocol.** |  |
| if | **(gBootServices->LocateProtocol (** |  |
| Enumerate | **and remove all strings of the given type.** |  |
| Remove | **each string of this type.** |  |
| for | **(; Count > 0; Count--) {** |  |
| FieldCount | ***TotalLength = Length;** |  |
| Scan | **through the string data to find the end.** |  |
| Strings | **are terminated by a double-null (one after each string** |  |
| plus | **a final null to mark end of all strings).** |  |
| while | **(TRUE) {** |  |
| Found | **a null terminator. Check if it's the end of strings** |  |
| if | **(*++Scan == '\0') {** |  |
| Count | **characters until next null.** |  |
| for | **(Index = 0; Index < 64; Index++) {** |  |
| No | **null found in 64 chars - likely an error.** |  |
| Get | **the source string length.** |  |
| StringLen | **= AsciiStrLen (NewString);** |  |
| Get | **the SMBIOS structure length.** |  |
| GetSmbiosStructuresAfterField | **(RecordBuffer, &TotalLen);** |  |
| Calculate | **the field position within the record.** |  |
| FieldPos | **= Buf[1];  // FieldCount (offset to first string)** |  |
| Scan | **through fields to find the target field position.** |  |
| if | **(FieldIndex > 1) {** |  |
| Check | **if the new string length matches the field's existing length.** |  |
| If | **AsciiStrLen of FieldPtr's region matches StringLen, we can do an** |  |
| FieldLen | **= AsciiStrLen (FieldPtr);** |  |
| Same | **length - in-place replacement.** |  |
| if | **(FieldPtr != NULL) {** |  |
| if | **(FieldPtr >= (UINT8 *)NewString ||** |  |
| No | **overlap, direct copy.** |  |
| if | **(FieldPtr == (UINT8 *)NewString) {** |  |
| Same | **pointer, nothing to do.** |  |
| return | **EFI_SUCCESS;** |  |
| Recalculate | **the structure after the field.** |  |
| Overlap | **detected - use auxiliary buffer for safe copy.** |  |
| SMBIOS_STRING_RECORD_SIZE | **if (RecordBuffer2 == NULL) {** |  |
| Copy | **the record to auxiliary buffer, modify, and copy back.** |  |
| CopyMem | **(RecordBuffer2, RecordBuffer, FieldPos + v13 + Buf[1]);** |  |
| Write | **new string.** |  |
| AsciiStrCpyS | **(** |  |
| Copy | **back and recalculate.** |  |
| GetSmbiosStructuresAfterField | **(RecordBuffer2, &TotalLen);** |  |
| Copy | **the updated record back.** |  |
| CopyMem | **(&Buf[FieldPos + v13 + Buf[1]], &FieldPtr[FieldLen - StringLen + 1], StringLen + 1);** |  |
| Final | **size update.** |  |
| Null | **field pointer - append? This is a complex path.** |  |
| Different | **length - need to insert/remove space.** |  |
| Allocate | **auxiliary buffer for safe manipulation.** |  |
| AuxBuffer | **= (UINTN)AllocateZeroPool (SMBIOS_STRING_RECORD_SIZE);** |  |
| Copy | **the part before the new string.** |  |
| Copy | **the part after the old string, skipping it.** |  |
| Calculate | **new total length.** |  |
| AuxTotalLen | **= TotalLen - FieldLen + StringLen;** |  |
| Copy | **back to original buffer.** |  |
| GetSmbiosStructuresAfterField | **((VOID *)AuxBuffer, &TotalLen);** |  |
| Clean | **up.** |  |
| FreePool | **((VOID *)AuxBuffer);** |  |
| Get | **the descriptor entry for this index.** |  |
| Desc | **= &mSmbiosType2Descriptors[DescriptorIndex];** |  |
| Initialize | **the SMBIOS string record header.** |  |
| Byte | **0: Type (8 = Type 2 Baseboard)** |  |
| Byte | **1: FieldCount (29 = total fields -1)** |  |
| Word | **2-3: Handle (0xFFFE = uninitialized)** |  |
| SMBIOS | **type 2** |  |
| 30 | **fields, index 0-29** |  |
| Copy | **the descriptor field metadata into the record header at offsets 4-7.** |  |
| From | **the original binary (sub_77C, 0x77C):** |  |
| If | **StringId is non-zero, look up the localized string.** |  |
| A | **zero StringId means this descriptor has no associated string.** |  |
| if | **(StringId != 0) {** |  |
| Get | **the localized string from HII font protocol.** |  |
| LocalizedString | **= GetHiiString (** |  |
| Write | **the string into the SMBIOS record buffer.** |  |
| The | **function handles buffer manipulation, overlap-safe** |  |
| No | **explicit FreePool needed here.** |  |
| The | **function at address 0xA20 constructs Type 9 SMBIOS records.** |  |
| It | **follows a similar pattern to BuildSmbiosStringRecord but for** |  |
| SMBIOS | **Type 9 (System Slots) fields.** |  |
| From | **the dispatch function (SmbiosDataUpdateDispatch), this function** |  |
| is | **called for 8 iterations (0-7). It takes a working buffer and index** |  |
| builds | **the record, and the caller then writes it to SMBIOS.** |  |
| return | **EFI_UNSUPPORTED;** |  |
| The | **function at address 0xD98 constructs Type 41 SMBIOS records.** |  |
| SMBIOS | **Type 41 (Onboard Devices Extended Information) fields.** |  |
| is | **called for 4 iterations (0-3). It takes a working buffer and index** |  |
| MM | **PCI Configuration** |  |
| Encode | **the PCI address.** |  |
| Address | **format: ((Func & 7) | (8 * ((Dev & 0x1F) | (32 * Bus)))) << 12** |  |
| UINT32 | **Address;** |  |
| Prepare | **address structure for MmPciBase->Write.** |  |
| Encode | **the PCI address: Bits [14:12] = Func, [19:15] = Dev, [24:20] = Bus.** |  |
| Call | **MmPciUsra->Write (at offset +24) with the address structure.** |  |
| if | **(mMmPciUsra == NULL) {** |  |
| SMBIOS | **Data Update Dispatch** |  |
| Allocate | **working buffer for SMBIOS string record construction.** |  |
| WorkBuffer | **= AllocateZeroPool (SMBIOS_STRING_RECORD_SIZE);** |  |
| Phase | **1: Process 30 SMBIOS Type 2 (Baseboard) string fields.** |  |
| Remove | **all existing Type 2 strings first.** |  |
| RemoveAllSmbiosStringsOfType | **(SMBIOS_TYPE_BASEBOARD);** |  |
| Process | **each Type 2 string field.** |  |
| for | **(i = 0; i < SMBIOS_TYPE2_COUNT; i++) {** |  |
| Phase | **2: Process 8 SMBIOS Type 9 (System Slot) string fields.** |  |
| RemoveAllSmbiosStringsOfType | **(SMBIOS_TYPE_SYSTEM_SLOTS);** |  |
| Phase | **3: Process 4 SMBIOS Type 41 (Onboard Device) string fields.** |  |
| RemoveAllSmbiosStringsOfType | **(SMBIOS_TYPE_ONBOARD_DEVICES);** |  |
| FreePool | **(WorkBuffer);** |  |
| Main | **Entry Point (SmbiosDataUpdateEntry)** |  |
| Open | **the UBA config protocol installed on ImageHandle.** |  |
| Status | **= gBootServices->OpenProtocol (** |  |
| Print | **module identification string.** |  |
| Copy | **the board-specific SMBIOS config GUID from UBA config data.** |  |
| The | **config data is at UbaConfig + 4 bytes (first 4 bytes are header).** |  |
| CopyGuid | **(&mSmbiosConfigGuid, (EFI_GUID *)((UINT8 *)UbaConfig + 4));** |  |
| Register | **the HII string package.** |  |
| gSmbiosStringPackHandle | **= RegisterHiiPackageList (** |  |
| String | **data from HII table** |  |
| Prepare | **the dispatch configuration buffer.** |  |
| ZeroMem | **(ConfigBuffer, sizeof (ConfigBuffer));** |  |
| Version | **ConfigBuffer[2] = 9;           // Dispatch function index** |  |
| Locate | **the UBA SMBIOS Data protocol.** |  |
| if | **(mUbaSmbiosDataProtocol == NULL) {** |  |
| Register | **the SMBIOS config with the UBA protocol.** |  |
| This | **call triggers the SmbiosDataUpdateDispatch callback.** |  |
| return | **((UBA_SMBIOS_DATA_PROTOCOL *)mUbaSmbiosDataProtocol)->SetSmbiosData (** |  |
| Initialization | **Function (SmbiosDataUpdateInit)** |  |
| The | **initialization logic from the original sub_38C (address 0x38C)** |  |
| has | **been inlined into ModuleEntryPoint() below.** |  |
| This | **function is kept as a stub for documentation purposes since the** |  |
| original | **binary had this as a separate function called from the entry** |  |
| MM | **PCIe base protocol) is now performed directly in ModuleEntryPoint().** |  |
| Module | **Entry Point** |  |
| Step | **1: Initialize global UEFI service table pointers.** |  |
| gImageHandle | **= ImageHandle;** |  |
| Step | **2: Locate HII services protocols.** |  |
| Locate | **HII Font protocol.** |  |
| Locate | **HII String protocol.** |  |
| Locate | **HII Database protocol.** |  |
| Locate | **HII Package List protocol.** |  |
| Locate | **HII Package List protocol interface.** |  |
| Step | **3: Find DXE Services Table from SystemTable->ConfigurationTable.** |  |
| Status | **= GetConfigTable (&mDxeServicesTableGuid, &mHobList);** |  |
| Step | **4: Optionally locate MM PCIe base protocol.** |  |
| This | **may already be cached from a previous lookup.** |  |
| Step | **5: Initialize HOB list.** |  |
| HobLibInit | **();** |  |
| Step | **6: Perform SMBIOS data update.** |  |
| Status | **= SmbiosDataUpdateEntry (ImageHandle);** |  |

---
*Generated by HR650X BIOS Decompilation Project*