AxlHii — UEFI HII setup-form reader
UEFI HII setup-form reader via the HII database + IFR opcode walk.
Header: <axl/axl-hii.h>. The platform’s BIOS Setup menus are published
as HII form sets — a tree of IFR (Internal Forms Representation) opcodes
in the HII database, backed by EFI variables or driver-private config
storage. This module locates the HII protocols
(EFI_HII_DATABASE/STRING/CONFIG_ROUTING/CONFIG_ACCESS), exports every
form package once, walks the IFR stream into a cached typed model, and
projects each setting as an AxlHiiQuestion.
A consumer (e.g. a remote BIOS-setup UI) enumerates form sets, reads a question’s current value, and writes a new one without ever touching the raw HII protocols or decoding IFR.
if (axl_hii_available()) {
size_t n = axl_hii_formset_count();
for (size_t f = 0; f < n; f++) {
char title[128], help[128];
size_t qcount;
if (axl_hii_formset_get(f, title, sizeof title,
help, sizeof help, NULL, &qcount) != AXL_OK) {
continue;
}
for (size_t q = 0; q < qcount; q++) {
AxlHiiQuestion question;
uint64_t value;
if (axl_hii_question_get(f, q, &question) == AXL_OK &&
axl_hii_question_read(f, q, &value) == AXL_OK) {
axl_printf("%a = %lu\n", question.prompt, value);
}
}
}
}
Scope
ONE_OF, CHECKBOX, NUMERIC, and STRING questions. STRING questions
are enumerated (prompt/help/min/max size); their text values go through
the dedicated axl_hii_question_read_string / _write_string pair, not
the u64 read/write (which return AXL_ERR for STRING). Forms,
cross-references, suppression/grayout expressions, and default stores are
out of scope: this is a flat list of the answerable questions in each
form set, not a form-browser.
Value I/O
axl_hii_question_read resolves the question’s variable store and reads
the value at its offset — first via GetVariable (EFI-backed stores),
falling back to the HII config-routing / config-access path
(ExtractConfig -> ConfigToBlock) for driver-private block stores.
axl_hii_question_write is the inverse (GetVariable/patch/SetVariable,
or BlockToConfig -> RouteConfig). Writes are guarded by the question’s
read-only flag; the caller is responsible for passing a firmware-valid
value (a real ONE_OF option, or an in-range NUMERIC) — the module does
not range-check against the question’s constraints.
STRING questions use axl_hii_question_read_string / _write_string,
which read/write the CHAR16 text field at the question’s offset (sized
by max_size) and convert to/from UTF-8. _write_string rejects input
longer than max_size and honors the read-only flag. (Every STRING
question stock OVMF/AAVMF publish is read-only, so the write path is
exercised on real hardware rather than in QEMU.)
Lifecycle
The model is parsed lazily on the first axl_hii_* call and cached for
the life of the process (freed via an internal axl_atexit handler).
Values are read live on each axl_hii_question_read, so they reflect
writes made by this or any other agent.
API Reference
UEFI HII setup-form reader — enumerate Setup form sets and get/read/write their questions.
The platform’s BIOS Setup menus are published as HII form sets: a tree of IFR (Internal Forms Representation) opcodes in the HII database, backed by EFI variables or driver-private config storage. This module locates the HII protocols, walks every form package once into a cached typed model, and projects each setting as an AxlHiiQuestion. A consumer (e.g. a remote BIOS-setup UI) can then enumerate form sets, read a question’s current value, and write a new one — without touching the raw HII protocols or decoding IFR.
if (axl_hii_available()) {
size_t n = axl_hii_formset_count();
for (size_t f = 0; f < n; f++) {
char title[128], help[128];
size_t qcount;
if (axl_hii_formset_get(f, title, sizeof title,
help, sizeof help, NULL, &qcount) != AXL_OK) {
continue;
}
for (size_t q = 0; q < qcount; q++) {
AxlHiiQuestion question;
if (axl_hii_question_get(f, q, &question) != AXL_OK) {
continue;
}
uint64_t value;
if (axl_hii_question_read(f, q, &value) == AXL_OK) {
// ... report question.prompt = value ...
}
}
}
}
Scope: ONE_OF, CHECKBOX, NUMERIC, and STRING questions. STRING questions are enumerated (prompt/help/min/max size) but their values are not read or written through the u64 API — axl_hii_question_read and _write return AXL_ERR for them (a string-valued variant may be added later). Forms, grefs, suppression/grayout expressions, and default stores are out of scope; this is a flat list of the answerable questions in each form set, not a form-browser.
The model is parsed lazily on the first axl_hii_* call and cached for the life of the process (freed via an internal atexit handler). Values are read live on each axl_hii_question_read, so they reflect writes made by this or any other agent.
Enums
-
enum AxlHiiQuestionType
Question (setting) kind.
The four IFR statement kinds this module surfaces. The active union arm of AxlHiiQuestion is selected by this type: AXL_HII_ONE_OF ->
u.one_of, AXL_HII_NUMERIC ->u.numeric, AXL_HII_STRING ->u.string. AXL_HII_CHECKBOX has no extra data (its value is 0 or 1).Values:
-
enumerator AXL_HII_ONE_OF
enumerated choice from a fixed option list
-
enumerator AXL_HII_CHECKBOX
boolean (value 0 or 1, width 1)
-
enumerator AXL_HII_NUMERIC
integer within a min/max range
-
enumerator AXL_HII_STRING
free text (value not read via the u64 API)
-
enumerator AXL_HII_ONE_OF
Functions
-
bool axl_hii_available(void)
Report whether any HII setup form sets are present.
Triggers the lazy parse on first call. A cheap gate a consumer can branch on before enumerating: true means the HII database is published and at least one form set with a title was parsed. False covers both a firmware with no HII database (rare) and one that published no form packages. The parse result is cached, so this is cheap after the first call.
- Returns:
true if at least one form set is available, false otherwise.
-
size_t axl_hii_formset_count(void)
Number of discovered HII form sets.
Triggers the lazy parse on first call. Valid form-set indices are
[0, axl_hii_formset_count()).- Returns:
the form-set count (0 if none / no HII database).
-
int axl_hii_formset_get(size_t index, char *title, size_t title_cap, char *help, size_t help_cap, AxlGuid *guid, size_t *question_count)
Read a form set’s metadata by index.
Copies the form set’s resolved title and help into the caller’s buffers (NUL-terminated, truncated to fit), its form-set GUID, and how many questions it has. Any of
title,help,guid, orquestion_countmay be NULL to skip that field; a 0 capacity also skips the matching string copy. The GUID is the IFR form-set class GUID — a stable identity a consumer can use to recognize a well-known form set (or label it) regardless of the localized title.- Parameters:
index – form-set index in [0, count)
title – [out] title buffer, or NULL to skip
title_cap – capacity of
titlein byteshelp – [out] help buffer, or NULL to skip
help_cap – capacity of
helpin bytesguid – [out] form-set GUID, or NULL to skip
question_count – [out] number of questions, or NULL to skip
- Returns:
AXL_OK on success, AXL_ERR if
indexis out of range.
-
int axl_hii_question_get(size_t formset_index, size_t question_index, AxlHiiQuestion *out)
Read a question’s static description.
Projects question
question_indexof form setformset_indexintoout:type, prompt/help, width, read-only/reset-required flags, and the per-type constraints (options, min/max/step, or string sizes). This is the static IFR description; the live value is read separately viaaxl_hii_question_read.- Parameters:
formset_index – form-set index in [0, count)
question_index – question index in [0, question_count)
out – [out] populated on success
- Returns:
AXL_OK on success, AXL_ERR if either index is out of range or
outis NULL.
-
int axl_hii_question_read(size_t formset_index, size_t question_index, uint64_t *value)
Read a question’s current value.
Resolves the question’s variable store and reads the value at its offset — first via
GetVariable(EFI-backed stores), falling back to the HII config-routing/config-access path for driver-private block stores. The result is the raw integer, width-extended to 64 bits (for CHECKBOX, 0 or 1; for ONE_OF, the selected option’s value).- Parameters:
formset_index – form-set index in [0, count)
question_index – question index in [0, question_count)
value – [out] current value on success
- Returns:
AXL_OK on success. AXL_ERR if either index is out of range,
valueis NULL, the question is AXL_HII_STRING (not supported by the u64 API), or the value cannot be read (no backing store / unreadable variable).
-
int axl_hii_question_write(size_t formset_index, size_t question_index, uint64_t value)
Write a question’s value.
Writes
valueinto the question’s variable store at its offset — viaGetVariable/patch/SetVariablefor EFI-backed stores, or the config-routingBlockToConfig-> config-accessRouteConfigpath for driver-private block stores. The caller is responsible for passing a value the firmware accepts (a valid ONE_OF option, or an in-range NUMERIC); this module does not range-check against the question’s constraints.- Parameters:
formset_index – form-set index in [0, count)
question_index – question index in [0, question_count)
value – value to store
- Returns:
AXL_OK on success. AXL_ERR if either index is out of range, the question is read-only or AXL_HII_STRING, or the underlying write fails.
-
int axl_hii_question_read_string(size_t formset_index, size_t question_index, char *buf, size_t buf_cap)
Read an AXL_HII_STRING question’s current text.
The string counterpart of
axl_hii_question_read(which rejects STRING questions). Resolves the question’s variable store, reads theCHAR16text stored at its offset (bounded by the question’smax_size), and converts it to UTF-8 intobuf— NUL-terminated and truncated tobuf_cap. The sameGetVariable/ config-routing resolution as the integer reader is used.- Parameters:
formset_index – form-set index in [0, count)
question_index – question index in [0, question_count)
buf – [out] UTF-8 text, NUL-terminated
buf_cap – capacity of
bufin bytes
- Returns:
AXL_OK on success. AXL_ERR if either index is out of range,
bufis NULL orbuf_capis 0, the question is not AXL_HII_STRING, or the value cannot be read (no backing store / unreadable variable).
-
int axl_hii_question_write_string(size_t formset_index, size_t question_index, const char *value)
Write an AXL_HII_STRING question’s text.
The string counterpart of
axl_hii_question_write. Converts the UTF-8valuetoCHAR16, requires its length not exceed the question’smax_size(the field is then NUL-padded to that width), and stores it at the question’s offset —GetVariable/patch/SetVariablefor EFI-backed stores, or the config-routing path for block stores. Themin_sizeconstraint is left to the firmware to enforce.- Parameters:
formset_index – form-set index in [0, count)
question_index – question index in [0, question_count)
value – UTF-8 text to store
- Returns:
AXL_OK on success. AXL_ERR if either index is out of range,
valueis NULL, the question is read-only or not AXL_HII_STRING,valueis longer thanmax_size, or the underlying write fails.
-
struct AxlHiiOption
- #include <axl-hii.h>
One selectable choice of a ONE_OF question.
valueis whataxl_hii_question_readreturns when this option is selected (and what to pass to_writeto select it).labelis the resolved, NUL-terminated display string (truncated to fit).
-
struct AxlHiiQuestion
- #include <axl-hii.h>
A single setup question, projected from IFR.
idis the IFR question id, stable within its form set across boots for a given firmware.widthis the value’s byte width (1/2/4/8) for the integer kinds, and 0 for AXL_HII_STRING.read_onlyfolds in both the IFR read-only and callback flags (a callback-driven question is not safely writable as a plain variable).reset_requiredis the IFR hint that changing this setting needs a reboot to take effect.The
uunion is valid only for the matchingtype:AXL_HII_ONE_OF:
u.one_of.options[0..option_count)lists the allowed value/label pairs (capped at 16).AXL_HII_NUMERIC:
u.numericgives the inclusive min/max and the step (0 means “no step constraint”).AXL_HII_STRING:
u.stringgives the min/max character counts.AXL_HII_CHECKBOX: no union arm is used.
Public Members
-
uint32_t id
IFR question id (stable within a form set)
-
AxlHiiQuestionType type
question kind; selects the
uarm
-
char prompt[128]
resolved prompt string (NUL-terminated)
-
char help[128]
resolved help string (NUL-terminated)
-
bool read_only
read-only or callback-driven (not plainly writable)
-
bool reset_required
changing it needs a reboot to take effect
-
uint8_t width
value width 1/2/4/8 (0 for STRING)
-
AxlHiiOption options[16]
allowed choices
-
size_t option_count
number of valid entries in
options
-
struct AxlHiiQuestion one_of
-
uint64_t min
inclusive minimum
-
uint64_t max
inclusive maximum
-
uint64_t step
increment (0 = unconstrained)
-
struct AxlHiiQuestion numeric
-
uint8_t min_size
minimum character count
-
uint8_t max_size
maximum character count
-
struct AxlHiiQuestion string
-
union AxlHiiQuestion u