# IpmiDeviceAmount

## Function Table

| Address | Name | Description |
|---------|------|-------------|
|  | **ModuleEntryPoint** |  |
|  | **sub_1748** |  |
|  | **sub_17C8** |  |
|  | **sub_18F4** |  |
|  | **sub_1BE8** |  |
|  | **sub_2088** |  |
|  | **sub_20A8** |  |
| rbx | **unsigned __int8 *v3; // r13** |  |
| r14 | **__int64 v5; // rax** |  |
| rsi | **unsigned __int64 v8; // r12** |  |
| r15 | **__int64 v10; // rax** |  |
| rdx | **__int64 v12; // rax** |  |
| rsi | **__int64 v14; // r12** |  |
| rax | **__int64 v16; // rax** |  |
| r14 | **unsigned __int64 v18; // r13** |  |
| cl | **__int64 v20; // r14** |  |
| rcx | **__int64 v22; // rax** |  |
| rsi | **__int64 v24; // rax** |  |
| r15 | **__int64 v26; // r15** |  |
| rax | **unsigned int v28; // r15d** |  |
| r9 | **_QWORD *v30; // r10** |  |
| r8 | **// NOTE: Full decompilation was too large for IDA output.** |  |
| See | **sub_A24 for the per-controller enumeration logic** |  |
| and | **sub_E2C for the per-controller iteration.** |  |
| This | **function appears to be the outermost dispatcher.** |  |
| r14 | **- capacity GB integer part** |  |
| rax | **__int64 v9;             // rdi - status** |  |
| r15 | **- loop index** |  |
| rsi | **- offset into handle buffer** |  |
| rax | **- status (OpenProtocol for ATA)** |  |
| rdx | **- line number for assert** |  |
| rax | **- status** |  |
| r9 | **- swap index** |  |
| eax | **- loop counter for model swap** |  |
| rcx | **__int64 v20;            // r8** |  |
| dl | **- temp for byte swap** |  |
| rax | **- trim loop** |  |
| rcx | **- capacity sectors** |  |
| rcx | **- capacity in bytes** |  |
| rbx | **- capacity fractional GB** |  |
| Allocate | **pool for model string buffer (256 bytes)** |  |
| Allocate | **pool for capacity string buffer (256 bytes)** |  |
| Open | **the ATA Pass Thru protocol on the controller handle** |  |
| to | **get the list of available ports/devices** |  |
| Check | **if port is enabled (bit 3 of attributes)** |  |
| Open | **ATA protocol interface on this port** |  |
| Check | **if device matches expected GUID (unk_2CC0)** |  |
| Get | **device type info (HDD vs SSD detection)** |  |
| Allocate | **IDENTIFY data buffer (512 bytes)** |  |
| Zero | **the IDENTIFY buffer** |  |
| Send | **IDENTIFY DEVICE command via ATA Pass Thru** |  |
| Parse | **model name from ATA IDENTIFY data (byte-swapped)** |  |
| ATA | **model name is in words 27-46 (54 bytes), byte-swapped** |  |
| Trim | **trailing spaces from model name** |  |
| Format | **model name as ASCII string** |  |
| Calculate | **capacity** |  |
| Device | **does not support LBA - use ATAPI fallback** |  |
| Convert | **sectors to GB (sector size = 512 bytes = << 9)** |  |
| total | **bytes** |  |
| GB | **integer part** |  |
| GB | **fractional part (1 decimal)** |  |
| Categorize | **as SSD or HDD** |  |
| SSD | **count** |  |
| SSD | **total capacity** |  |
| Free | **IDENTIFY buffer** |  |
| ASSERT | **on failure** |  |
| rax | **__int64 v10;             // rbx - status** |  |
| rcx | **__int64 v18;             // rax - status from sub_A24** |  |
| Locate | **all handles supporting ATA Pass Thru protocol** |  |
| ByProtocol | **&unk_2D00,      // ATA Pass Thru GUID** |  |
| Open | **ATA Pass Thru protocol on this handle** |  |
| Open | **Block IO protocol to get device topology info** |  |
| Get | **device location (SATA port, bus, device, function)** |  |
| Reset | **the ATA controller port** |  |
| Debug | **print: SATA controller location** |  |
| Enumerate | **devices on this controller** |  |
| Accumulate | **HDD count** |  |
| Accumulate | **HDD capacity** |  |
| Accumulate | **SSD count** |  |
| Accumulate | **SSD capacity** |  |
| r13 | **unsigned __int8 v2;      // r15** |  |
| r12 | **__int64 v4;              // rdx** |  |
| rcx | **__int64 v6;              // rbx** |  |
| di | **__int64 v8;              // rbx** |  |
| rdx | **char v10;                // r8** |  |
| cl | **_BYTE *v12;              // rdx** |  |
| cl | **__int64 n0x7FFF;         // rdx** |  |
| rcx | **__int64 v16;             // r8** |  |
| bl | **__int64 v18;             // rdi** |  |
| rax | **unsigned __int8 v20;     // r14** |  |
| ebx | **unsigned __int8 v22;     // si** |  |
| rax | **unsigned __int8 v24;     // di** |  |
| bl | **unsigned __int8 *v26;    // rbx** |  |
| rdi | **__int64 v28;             // r9** |  |
| rax | **__int64 result;          // rax** |  |
| rdx | **__int64 v32;             // rax** |  |
| This | **function registers a ReadyToBoot callback that reads CPU** |  |
| the | **HDD and SSD counts to the BMC.** |  |
| rbx | **unsigned __int64 n0xF4240; // rdi - counter, max 1,000,000** |  |
| rax | **_WORD *v2; // rbx** |  |
| rdx | **__int64 v4; // r8** |  |
| r9 | **__int64 v6; // r10** |  |
| r11 | **unsigned __int64 n3; // rdi** |  |
| rcx | **__int16 v10; // dx** |  |
| rax | **result = SSD_1;** |  |
| Compare | **first 5 characters for "SSD" pattern match** |  |
| Compare | **with known SSD model prefix table** |  |
| 5 | **wide chars** |  |
| Try | **next SSD keyword pattern** |  |
| rdx | **__int64 v3; // rcx** |  |
| r8 | **__int64 v5; // r9** |  |
| GUID | **comparison - checks all 4 fields of the GUID structure** |  |
| Returns | **current time formatted as a string buffer** |  |
| Used | **for debug/timestamp output** |  |
| rax | **va_list va; // [rsp+48h] [rbp+10h] BYREF** |  |
| Wraps | **DebugPrint or similar UEFI debug output function** |  |
| Standard | **UEFI ASSERT implementation:** |  |
| Registers | **sub_10C0 as a ReadyToBoot callback** |  |
| Uses | **gBS->CreateEventEx(EVT_NOTIFY_SIGNAL, TPL_CALLBACK, sub_10C0, ...)** |  |
| or | **gBS->RegisterProtocolNotify(...)** |  |
| Initialize | **UEFI libraries:** |  |
| Wraps | **gBS->SetMem() or BaseMemoryLib SetMem()** |  |
| Converts | **ASCII string to uppercase** |  |
| Reads | **CPU information via HOB or SMBIOS** |  |
| Wraps | **UnicodeSPrint(dst, size, fmt, ...)** |  |
| Full | **serial/console print implementation with format string support** |  |
| Returns | **current serial port configuration** |  |

---
*Generated by HR650X BIOS Decompilation Project*