# DxeIpmiUsb

## Function Table

| Address | Name | Description |
|---------|------|-------------|
|  | **ReadTimeStampCounter** |  |
|  | **ReadEflags** |  |
|  | **CpuPause** |  |
|  | **EnableInterrupts** |  |
|  | **DisableInterrupts** |  |
|  | **DebugPrint** |  |
|  | **AssertHandler** |  |
|  | **GetPcdBool** |  |
|  | **PciExpressMmioAddress** |  |
|  | **IoRead32** |  |
|  | **IoWrite16** |  |
|  | **MicrosecondDelay** |  |
|  | **ReadUnaligned64** |  |
|  | **MatchSioGuid** |  |
|  | **UsbClearEndpointHalt** |  |
|  | **SendIpmiUsbControlReport** |  |
|  | **IpmiUsbSendCommand** |  |
|  | **IpmiUsbReceiveResponse** |  |
|  | **IpmiUsbSelfTest** |  |
|  | **ReportSmmEvent** |  |
|  | **ConfigureIpmiUsbEndpoints** |  |
|  | **IpmiUsbSupported** |  |
|  | **IpmiUsbStart** |  |
|  | **IpmiUsbStop** |  |
|  | **DxeIpmiUsbEntryPoint** |  |
|  | **IpmiusbUsbIoProtocolNotify** |  |
| Global | **variable definitions** |  |
| EFI_HANDLE | **gImageHandle              = NULL;** |  |
| STATIC | **PCD_PROTOCOL                     *mPcdProtocol               = NULL; // qword_1FF8** |  |
| qword_2018 | **STATIC VOID                             *mHobList                   = NULL; // qword_2008** |  |
| qword_2010 | **//** |  |
| Current | **IPMI USB device instance pointer** |  |
| STATIC | **IPMI_USB_DEVICE                  *mIpmiDevice                = NULL; // qword_1FB8** |  |
| USB | **device descriptor fields and transfer tracking** |  |
| STATIC | **UINT16                           mUsbBcdDevice               = 0;    // word_1FC8** |  |
| dword_1FCC | **STATIC UINT8                            mTransferInProgress         = 0;    // byte_1FD0** |  |
| Internal | **Memory Operation Helpers (wrappers around BaseLib)** |  |
| CPU | **/ Platform Helpers** |  |
| ASSERT | **/ Debug Helpers** |  |
| Called | **by the ASSERT() macro when the test expression is FALSE.** |  |
| PCD | **Protocol Helper** |  |
| PCI | **Express MMIO Access** |  |
| Port | **I/O and Timer Helpers** |  |
| Split | **into whole milliseconds (each ~0x400000 TSC ticks)** |  |
| plus | **a remainder.** |  |
| NumMs | **= Microseconds >> 22;** |  |
| full | **1-ms chunk on subsequent iterations** |  |
| HOB | **(Hand-Off Block) List Helpers** |  |
| Load | **the SIO GUID for comparison.** |  |
| SioGuid1 | **= ReadUnaligned64 ((VOID *)(UINTN)&gEfiSioProtocolGuid);** |  |
| USB | **Endpoint Reset** |  |
| Use | **UsbIo->UsbControlTransfer with the ClearFeature(ENDPOINT_HALT)** |  |
| standard | **request (bmRequestType = 0x02, bRequest = 0x01** |  |
| wValue | **= 0x00, wIndex = Endpoint).** |  |
| This | **is a standard USB device request sent via the default pipe.** |  |
| return | **EFI_UNSUPPORTED; // Placeholder** | call UsbIo->UsbControlTransfer |
| USB | **Transfer / IPMI Command Send and Response Receive** |  |
| Step | **1: Send the report via control transfer.** |  |
| return | **UsbIo->UsbControlTransfer (** |  |
| DeviceRequest | **-- built internally by UsbIo** |  |
| Copy | **the IPMI request data into the device's data buffer.** |  |
| InternalCopyMem | **(Device->DataBuffer, Buffer, BufferSize);** |  |
| Increment | **the sequence number.** |  |
| Send | **via USB interrupt OUT endpoint (or control endpoint depending on** |  |
| the | **specific report type).** |  |
| if | **(ReportId == USB_ENDPOINT_INTERRUPT) {** |  |
| Interrupt | **OUT transfer for streaming data.** |  |
| UINTN | **TransferSize = BufferSize;** |  |
| Use | **the control endpoint with SET_REPORT.** |  |
| Status | **= SendIpmiUsbControlReport (** |  |
| Read | **from the interrupt IN endpoint.** |  |
| return | **UsbIo->UsbInterruptTransfer (** |  |
| IPMI | **USB Self-Test** |  |
| Set | **up the IPMI Get Device ID command parameters.** |  |
| The | **device's NetFunction field is set to NetFn Application (0x06).** |  |
| The | **LUN is 0x00.** |  |
| BmcStatus | **= 0;** |  |
| Send | **the command.** |  |
| Call | **SendCommand with the Get Device ID command.** |  |
| Status | **= Device->SendIpmiCommand (** |  |
| ReportId | **for the control endpoint** |  |
| SET_REPORT | **&BmcStatus** |  |
| Read | **the response.** |  |
| Status | **= Device->ReceiveIpmiResponse (** |  |
| Evaluate | **the self-test result from the first byte of the response.** |  |
| 0x55 | **= Self-test passed successfully** |  |
| 0x56 | **= Self-test completed with errors** |  |
| 0x57 | **= Self-test in progress** |  |
| 0xFF | **= Device not ready / self-test not implemented** |  |
| BmcStatus | **= Device->DataBuffer[0];** |  |
| Completion | **code < 0x55: self-test passed.** |  |
| SMM | **Communication (Reporting Events to SMM)** |  |
| Communicate | **via SMM with a platform-specific command.** |  |
| USB | **Endpoint Configuration Discovery** |  |
| Iterate | **the interface's endpoints and store the addresses.** |  |
| return | **EFI_SUCCESS;** |  |
| Driver | **Binding Protocol Implementation** |  |
| Open | **USB IO protocol BY_DRIVER.** |  |
| Status | **= gBS->OpenProtocol (** |  |
| Read | **the interface descriptor.** |  |
| DescSize | **= sizeof (IfcDesc);** |  |
| Check | **bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol.** |  |
| For | **IPMI USB: class=0xFF, subclass=0x01, protocol=0x86.** |  |
| if | **((IfcDesc[5] == IPMI_USB_INTERFACE_CLASS) &&** |  |
| Open | **USB IO protocol.** |  |
| Allocate | **the IPMI_USB_DEVICE (size 32834 = 0x8042 bytes).** |  |
| Device | **= (IPMI_USB_DEVICE *)AllocateZeroPool (sizeof (IPMI_USB_DEVICE));** |  |
| Initialize | **the device structure.** |  |
| Get | **the interface descriptor to discover endpoints.** |  |
| Store | **the endpoint addresses (stored at NetFunction and Lun fields)** |  |
| from | **the interface descriptor's endpoint addresses.** |  |
| The | **first endpoint is typically Interrupt IN (bit 7 set).** |  |
| The | **second endpoint is typically Interrupt OUT (bit 7 clear).** |  |
| Placeholder | **- would iterate endpoints** |  |
| Cache | **pointers for subsequent use.** |  |
| mIpmiDevice | **= Device;** |  |
| Run | **self-test.** |  |
| Status | **= IpmiUsbSelfTest (Device);** |  |
| If | **the self-test set the state to failed, return error.** |  |
| if | **(Device->CompletionCode == IPMI_USB_STATE_FAILED) {** |  |
| Install | **the protocol interface.** |  |
| Status | **= gBS->InstallMultipleProtocolInterfaces (** |  |
| Driver | **Binding Protocol instance** |  |
| STATIC | **EFI_DRIVER_BINDING_PROTOCOL  mDriverBinding = {** |  |
| Module | **Entry Point** |  |
| Global | **initialization.** |  |
| gImageHandle | **= ImageHandle;** |  |
| Initialize | **the HOB list pointer.** |  |
| GetHobList | **(SystemTable);** |  |
| Get | **PCI Express MMIO base address from PCD (token 5).** |  |
| mPciExpressMmioBase | **= GetPcdBool (5);** |  |
| Enable | **PCIe MMIO config in the chipset.** |  |
| Write | **0x500 to the PCI Express config register at address 1024064** |  |
| register | **that enables MMIO-based PCI config access).** |  |
| if | **(GetPcdBool (1024068) >= 0) {** |  |
| Set | **the enable bit in the PCD.** |  |
| GetPcdBool | **(1024068) |= 0x80;** |  |
| Check | **if interrupts were enabled before we enter our delay loop.** |  |
| if | **(ReadEflags () & 0x200) {** |  |
| Interrupts | **were enabled. Calibrate a TSC-based delay.** |  |
| TscStart | **= ReadTimeStampCounter () & 0xFFFFFF;** |  |
| Spin | **waiting for 357 TSC ticks (~1 us at 357 MHz TSC).** |  |
| while | **(((TscStart + 357 - (IoRead32 (0x508) & 0xFFFFFF)) & 0x800000) == 0) {** |  |
| Set | **up the Driver Binding Protocol.** |  |
| Install | **the Driver Binding Protocol.** |  |
| Register | **protocol notification to bind existing USB IO handles.** |  |
| EfiCreateProtocolNotifyEvent | **(** |  |
| This | **callback is invoked each time a USB IO protocol is registered.** |  |
| The | **actual binding happens through the UEFI Driver Binding Protocol** |  |
| which | **calls IpmiUsbSupported() and IpmiUsbStart() as USB IO handles** |  |
| are | **enumerated.** |  |

---
*Generated by HR650X BIOS Decompilation Project*