# SmbiosType39

## Function Table

| Address | Name | Description |
|---------|------|-------------|
|  | **InternalReadUnaligned64** |  |
|  | **AsciiStrLen** |  |
|  | **StrLen** |  |
|  | **EfiGetSystemConfigurationTable** |  |
|  | **SendHeciPowerSupplyCommand** |  |
|  | **GetHobList** |  |
|  | **FreePoolOrBuffer** |  |
|  | **DebugPrint** |  |
|  | **InstallSmbiosType39Structure** |  |
|  | **SmbiosType39EntryPoint** |  |
| Global | **data** |  |
| EFI_HANDLE | **gImageHandle  = NULL;** |  |
| GUID | **definitions (referenced from global data section)** |  |
| extern | **EFI_GUID  gEfiSmbiosProtocolGuid;** |  |
| HECI | **command message for power supply queries** |  |
| 0x8A0A | **= HECI_GROUP_ID << 8 | 0x0A** |  |
| HECI | **command byte** |  |
| Parameter | **data (varies per command)** |  |
| HECI | **command template: GroupId = 0x8A0A** |  |
| ME | **FWS (Firmware Status) register bits** |  |
| Zero | **out 8 bytes at a time, then remaining bytes** |  |
| ZeroMem | **(Buffer, Length);** |  |
| PcdMaximumAsciiStringLength | **exceeded** |  |
| Ensure | **buffers do not overlap in a way that would cause corruption** |  |
| ASSERT | **((UINTN)((CHAR8 *)Destination - Source) > AsciiStrLen (Source));** |  |
| Build | **the HECI request header** |  |
| 0x8A0A | **Request.Command  = Command;** |  |
| supply | **bay index in low byte** |  |
| Send | **the command via HECI with the default buffer size** |  |
| ResponseLength | **= sizeof (Response);** |  |
| Check | **response: if HeciMsg[1] is non-zero but not 0xA3, no data available** |  |
| if | **(Response[1] != 0) {** |  |
| Copy | **the returned data to the caller's buffer** |  |
| DataPtr | **= &Response[3];** |  |
| Allocate | **31 pages for PCD protocol usage** |  |
| Pages | **= EFI_SIZE_TO_PAGES (31);** |  |
| Not | **enough pages - return NULL** |  |
| return | **NULL;** |  |
| Locate | **the PCD protocol** |  |
| Status | **= gBS->LocateProtocol (** |  |
| Read | **CMOS to determine current debug level** |  |
| CmosByte | **= IoRead8 (0x70);** |  |
| Determine | **the error mask based on the debug level** |  |
| if | **(DebugLevel > 3) {** |  |
| Initialize | **the INVALID string length for fallback** |  |
| V2 | **= AsciiStrLen ("INVALID");** |  |
| Locate | **the SMBIOS protocol** |  |
| SmbiosRecord | **= (SMBIOS_TABLE_TYPE39 *)(UINTN)GetSmbiosProtocol ();** |  |
| Close | **the notification event** |  |
| Status | **= gBS->CloseEvent (Event);** |  |
| Locate | **the HECI protocol** |  |
| HeciProtocol | **= GetHeciProtocol ();** |  |
| Check | **ME firmware status to determine if ME is in normal mode** |  |
| NvRamVariable | **= 512;** |  |
| ME | **is not in S0/M0 normal operation state** |  |
| DEBUG | **((DEBUG_INFO, "MeFs1.Bits.CurrentState == %d\n", CurrentMeState));** |  |
| Enumerate | **power supply bays (0 and 1)** |  |
| SupplyBay | **= 0;** |  |
| Step | **1: Get Device Name (command = 0x9A, -102 signed)** |  |
| AsciiStrCpyS | **(DeviceName, "INVALID");** |  |
| Step | **2: Get Manufacturer (command = 0x99, -103 signed)** |  |
| Step | **3: Get Serial Number (command = 0x62, -98 signed as 0x9E)** |  |
| Step | **4: Get Asset Tag (command = 0xF1, -15 signed)** |  |
| Asset | **tag command** |  |
| Step | **5: Get Model Part Number (command = 0x9B, -101 signed)** |  |
| Step | **6: Get Revision Level (command = 0xA7, -89 signed)** |  |
| Step | **7: Get Max Power Capacity** |  |
| Capacity | **request parameter** |  |
| Step | **8: Get Power Supply Present / Status** |  |
| Same | **as capacity command** |  |
| Status | **= Unknown** |  |
| Determine | **power supply status based on response byte** |  |
| If | **bit 1 of response[2] is clear -> status = 1 (Present, Unknown)** |  |
| If | **bit 1 of response[2] is set   -> status = 3 (Present, Good)** |  |
| PowerSupplyStatus | **= ((PsuResponse[2] & 0x02) != 0) ? 1 : 3;** |  |
| Step | **9: Allocate and build SMBIOS Type 39 record** |  |
| TotalStringLength | **= AsciiStrLen (DeviceName)** |  |
| Fill | **in the SMBIOS Type 39 record fields** |  |
| Set | **power unit group (2 = "From the Mapping to the Power Unit Group")** |  |
| Build | **the power supply status flags** |  |
| Bit | **0   = Power Supply Present** |  |
| Bits | **6-7 = Power Supply Status (00=Unknown, 01=OK, 10=Non-critical, 11=Critical)** |  |
| PowerSupplyFlags | **= (PowerSupplyPresent & 1) | ((PowerSupplyStatus & 7) << 6);** |  |
| Now | **fill the string area.** |  |
| Strings | **are packed as null-terminated ASCII after the fixed structure.** |  |
| CurrentStringPtr | **= (CHAR8 *)(SmbiosRecord + 1);** |  |
| Step | **10: Add the Type 39 record via SMBIOS protocol** |  |
| Cleanup | **allocated buffers** |  |
| FreePool | **(StringBuffer);** |  |
| Move | **to the next supply bay** |  |
| SupplyBayIncrement | **+= 2;** |  |
| Initialize | **global variables** |  |
| gImageHandle | **= ImageHandle;** |  |
| Initialize | **HOB list and PCD protocol** |  |
| GetHobList | **();** |  |
| Look | **up the DXE Services Table via system configuration** |  |
| Status | **= EfiGetSystemConfigurationTable (** |  |
| Look | **up the MM PCI base protocol (for MMIO PCI config access)** |  |
| Register | **a callback on the SMBIOS protocol installation** |  |
| When | **SMBIOS protocol becomes available, InstallSmbiosType39Structure** |  |
| will | **be called.** |  |
| Status | **= gBS->CreateEvent (** |  |

---
*Generated by HR650X BIOS Decompilation Project*