Newer
Older
AMI-Aptio-BIOS-Reversed / DxeIpmiUsb / DxeIpmiUsb.md
@Ajax Dong Ajax Dong 2 days ago 7 KB Init

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