AxlSmbus – SMBus / I2C block access
AxlSmbus — SMBus / I2C block access
SMBus session abstraction that gives UEFI apps block read/write over whichever controller the platform publishes. Dispatches on the first available firmware-provided transport:
Kind |
Mechanism |
Who owns framing |
|---|---|---|
|
|
firmware |
|
|
this module |
Auto-detect preference: SMBus HC → I2C Master. The I2C fallback
constructs the SMBus block-transfer wire format ([cmd][count][data]
on writes, [count][data] on reads) on top of raw I2C operations.
Consumers
AxlIpmi SSIF transport — every IPMI round-trip over SSIF goes through an
AxlSmbussession.AxlSpd (planned, Phase B3) — DDR4/5 SPD readers at the canonical 0xA0–0xAE addresses.
Usage
#include <axl/axl-smbus.h>
AXL_AUTOPTR(AxlSmbus) s = axl_smbus_new();
if (s == NULL) {
axl_error("No SMBus controller available");
return -1;
}
uint8_t buf[32];
size_t len = sizeof(buf);
if (axl_smbus_read_block(s, /*slave=*/0x10, /*cmd=*/0x03,
buf, &len) != 0) {
axl_error("SMBus read failed");
return -1;
}
// buf[0..len-1] carries the payload (count byte already stripped).
AXL_AUTOPTR frees the session at scope exit; firmware owns the
underlying protocol instance so nothing in the shim is leaked.
Layout
src/smbus/
├── axl-smbus.c session lifecycle + auto-detect
├── axl-smbus-internal.h transport vtable + session layout
├── axl-smbus-hc.c EFI_SMBUS_HC_PROTOCOL pass-through
├── axl-smbus-i2c.c EFI_I2C_MASTER_PROTOCOL framing (B1 code path)
└── axl-smbus-format.c enum-to-string helpers
Wire format (I2C path)
SMBus 2.0 §5.5.7/5.5.8. The SMBus HC protocol inserts and strips the byte-count for us; the I2C Master protocol does not, so this module builds it manually:
Block write: [cmd] [count] [payload_0 ... payload_{count-1}]
Block read: (write cmd) → (read) [count] [payload_0 ... payload_{count-1}]
On reads, the count byte is stripped before the payload is copied to
the caller’s buffer. On writes, it is inserted at tx[1]. Both sides
are asserted on by test/unit/axl-test-smbus.c via a capturing mock
protocol — any future regression of this framing fails CI without a
BMC in the loop.
Limits
Max block payload: 32 bytes (spec limit;
AXL_SMBUS_BLOCK_MAX).Higher-level SMBus commands (quick, byte, byte_data, word_data, process_call, bus enumeration) are not implemented yet — they land when AxlSpd’s scope demands them, not speculatively.
API Reference
Defines
-
AXL_SMBUS_BLOCK_MAX
SMBus block transfer payload limit — the count byte is one byte wide and the spec caps block length at 32 data bytes.
Typedefs
Enums
Functions
-
AxlSmbus *axl_smbus_new(void)
Open a session against the first available SMBus controller.
Probes EFI_SMBUS_HC_PROTOCOL first (full block protocol provided by firmware); falls back to EFI_I2C_MASTER_PROTOCOL (this module builds the SMBus block-transfer framing on top).
- Returns:
session handle, or NULL if no controller is available.
-
void axl_smbus_free(AxlSmbus *s)
Free an SMBus session. NULL-safe.
- Parameters:
s – session to free (NULL-safe)
-
AxlSmbusTransport axl_smbus_transport(const AxlSmbus *s)
Report which transport a session selected.
- Parameters:
s – session (NULL returns UNKNOWN)
-
int axl_smbus_read_block(AxlSmbus *s, uint8_t slave, uint8_t command, uint8_t *buf, size_t *len)
SMBus block read.
Issues an SMBus block-read transaction: the command byte is written to slave, the device responds with a byte count followed by up to AXL_SMBUS_BLOCK_MAX payload bytes. The byte count is stripped by this function; the caller sees only the payload.
- Parameters:
s – open session.
slave – 7-bit SMBus slave address (bit 0 is the R/W bit and is supplied by the transport).
command – SMBus command byte.
buf – (out) receives the payload.
len – (in/out) buffer capacity on entry; bytes written on success (clamped to capacity if the device returned more than requested).
- Returns:
0 on success, -1 on transport error or invalid arguments.
-
int axl_smbus_write_block(AxlSmbus *s, uint8_t slave, uint8_t command, const uint8_t *buf, size_t len)
SMBus block write.
Issues an SMBus block-write transaction: command byte, byte count, then len payload bytes. The byte-count prefix is inserted by this function.
- Parameters:
s – open session.
slave – 7-bit SMBus slave address.
command – SMBus command byte.
buf – payload bytes.
len – payload length; must not exceed AXL_SMBUS_BLOCK_MAX.
- Returns:
0 on success, -1 on transport error or invalid arguments.
-
const char *axl_smbus_transport_string(AxlSmbusTransport kind)
Human-readable name for an AxlSmbusTransport value.
- Returns:
static string; never NULL.