How UEFI Applications Query Battery Status

This article explains how Unified Extensible Firmware Interface (UEFI) applications retrieve battery information on mobile platforms such as laptops, tablets, and handhelds. It covers the primary UEFI protocols used for battery management, how applications communicate with underlying hardware fuel gauges, and the fallback mechanisms through ACPI and direct bus communication before the operating system boots.

The Primary Mechanism: UEFI Battery Protocols

UEFI applications typically do not interface directly with raw hardware registers. Instead, they leverage firmware abstractions provided by platform initialization code. On modern mobile platforms, the primary interface is the EFI_BATTERY_CHARGING_PROTOCOL (or its updated revision, EFI_BATTERY_CHARGING_SOFTWARE2_PROTOCOL).

These protocols are commonly implemented by silicon vendors (such as Intel, AMD, and Qualcomm) and device OEMs to facilitate pre-OS charging displays and safe-boot battery thresholds.

To query status using this protocol:

  1. Locate the Protocol: The application calls the UEFI Boot Services function gBS->LocateProtocol() using the protocol's Globally Unique Identifier (EFI_BATTERY_CHARGING_PROTOCOL_GUID).
  2. Execute Status Functions: Once the interface pointer is obtained, the application calls member functions such as GetBatteryStatus().
  3. Parse Battery Data: The function populates data structures containing:
    • State of Charge (SoC) percentage.
    • Current battery voltage and capacity (in millivolts/milliwatt-hours).
    • Charging state (e.g., charging, discharging, idle).
    • Battery temperature.
    • Critical health and error flags.

Fallback: Direct Bus Interfaces (I2C and SMBus)

When higher-level battery charging protocols are not exposed by the platform firmware, applications on embedded or reference mobile boards can query the battery fuel gauge directly.

Battery management ICs (BMICs)—such as standard Texas Instruments or Maxim fuel gauges—are typically wired to the platform via I2C or System Management Bus (SMBus).

  • I2C Protocol: Applications locate the EFI_I2C_IO_PROTOCOL to perform synchronous write-read transactions to the fuel gauge’s slave address.
  • SMBus Protocol: Applications locate the EFI_SMBUS_HC_PROTOCOL and invoke standard Smart Battery Specification commands (such as reading register 0x0D for relative state of charge or 0x09 for voltage).

ACPI Table Parsing

On standard x86 mobile PCs, battery management is heavily tied to the Advanced Configuration and Power Interface (ACPI) managed by an on-board Embedded Controller (EC). While ACPI control methods (_BST for Battery Status and _BIX/_BIF for Battery Information) are normally evaluated by an OS-level ACPI driver via an AML interpreter, UEFI applications can still access raw ACPI structures.

A UEFI application locates the Root System Description Pointer (RSDP) via the EFI_SYSTEM_TABLE Configuration Table array. By traversing to the Differentiated System Description Table (DSDT), the application can verify the presence of a Control Method Battery device (e.g., hardware ID PNP0C0A). However, executing these methods directly inside a basic UEFI application requires an embedded AML interpreter, making standard UEFI protocols the preferred route for pre-boot environments.

Standard Implementation Flow

A typical UEFI application implements a prioritized discovery pattern:

EFI_STATUS Status;
EFI_BATTERY_CHARGING_PROTOCOL *BatteryProtocol = NULL;
UINT32 BatteryPercentage = 0;
UINT32 Voltage = 0;
EFI_BATTERY_CHARGING_STATUS BatteryStatus;

// 1. Attempt to locate standard firmware charging protocol
Status = gBS->LocateProtocol(
    &gEfiBatteryChargingProtocolGuid,
    NULL,
    (VOID **)&BatteryProtocol
);

if (!EFI_ERROR(Status)) {
    // 2. Query status from the protocol
    Status = BatteryProtocol->GetBatteryStatus(
        BatteryProtocol,
        &BatteryPercentage,
        &Voltage,
        &BatteryStatus
    );
} else {
    // 3. Fallback to platform-specific OEM protocols or SMBus
}

This tiered approach ensures that pre-boot environments can safely determine if the system has sufficient power to execute firmware updates, perform recovery tasks, or display low-battery warnings before handing control over to the operating system bootloader.