Skip to content

uefi: Add HiiKeywordHandler and HiiConfigAccess protocol #1684

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions uefi-raw/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
## Added
- Added `AllocateType`.
- Added `PciRootBridgeIoProtocol`.
- Added `HiiKeywordHandlerProtocol`.
- Added `HiiConfigAccessProtocol`.


# uefi-raw - 0.11.0 (2025-05-04)
Expand Down
174 changes: 174 additions & 0 deletions uefi-raw/src/protocol/hii/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// SPDX-License-Identifier: MIT OR Apache-2.0

//! Bindings for HII protocols relating to system configuration.

use core::fmt::Debug;

use crate::{Char16, Guid, Status, guid};

/// EFI_KEYWORD_HANDLER_PROTOCOL
#[derive(Debug)]
#[repr(C)]
pub struct HiiKeywordHandlerProtocol {
pub set_data: unsafe extern "efiapi" fn(
this: *mut Self,
keyword_string: *const Char16,
progress: *mut *const Char16,
progress_err: *mut u32,
) -> Status,
pub get_data: unsafe extern "efiapi" fn(
this: *const Self,
namespace_id: *const Char16,
keyword_string: *const Char16,
progress: *mut *const Char16,
progress_err: *mut u32,
results: *mut *const Char16,
) -> Status,
}

impl HiiKeywordHandlerProtocol {
pub const GUID: Guid = guid!("0a8badd5-03b8-4d19-b128-7b8f0edaa596");
}

newtype_enum! {
/// Type of action taken by the form browser
#[derive(Default)]
pub enum EfiBrowserAction: u32 => {
/// Called before the browser changes the value in the display (for questions which have a value)
/// or takes an action (in the case of an action button or cross-reference).
/// If EFI_SUCCESS is returned, the browser uses the value returned by Callback().
CHANGING = 0,
/// Called after the browser has changed its internal copy of the question value and displayed it (if appropriate).
/// For action buttons, this is called after processing. Errors are ignored.
CHANGED = 1,
/// Called after the browser has read the current question value but before displaying it.
/// If EFI_SUCCESS is returned, the updated value is used.
RETRIEVE = 2,
/// Called for each question on a form prior to its value being retrieved or displayed.
/// If a question appears on more than one form, this may be called more than once.
FORM_OPEN = 3,
/// Called for each question on a form after processing any submit actions for that form.
/// If a question appears on multiple forms, this will be called more than once.
FORM_CLOSE = 4,
/// Called after the browser submits the modified question value.
/// ActionRequest is ignored.
SUBMITTED = 5,
/// Represents the standard default action, selecting a default value based on lower-priority methods.
DEFAULT_STANDARD = 0x1000,
/// Represents the manufacturing default action, selecting a default value relevant to manufacturing.
DEFAULT_MANUFACTURING = 0x1001,
/// Represents the safe default action, selecting the safest possible default value.
DEFAULT_SAFE = 0x1002,
/// Represents platform-defined default values within a range of possible store identifiers.
DEFAULT_PLATFORM = 0x2000,
/// Represents hardware-defined default values within a range of possible store identifiers.
DEFAULT_HARDWARE = 0x3000,
/// Represents firmware-defined default values within a range of possible store identifiers.
DEFAULT_FIRMWARE = 0x4000,
}
}

newtype_enum! {
/// Represents actions requested by the Forms Browser in response to user interactions.
#[derive(Default)]
pub enum EfiBrowserActionRequest: usize => {
/// No special behavior is taken by the Forms Browser.
NONE = 0,
/// The Forms Browser will exit and request the platform to reset.
RESET = 1,
/// The Forms Browser will save all modified question values to storage and exit.
SUBMIT = 2,
/// The Forms Browser will discard all modified question values and exit.
EXIT = 3,
/// The Forms Browser will write all modified question values on the selected form to storage and exit the form.
FORM_SUBMIT_EXIT = 4,
/// The Forms Browser will discard the modified question values on the selected form and exit the form.
FORM_DISCARD_EXIT = 5,
/// The Forms Browser will write all modified current question values on the selected form to storage.
FORM_APPLY = 6,
/// The Forms Browser will discard the current question values on the selected form and replace them with the original values.
FORM_DISCARD = 7,
/// The user performed a hardware or software configuration change, requiring controller reconnection.
/// The Forms Browser calls `DisconnectController()` followed by `ConnectController()`.
RECONNECT = 8,
/// The Forms Browser will write the current modified question value on the selected form to storage.
QUESTION_APPLY = 9,
}
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EfiHiiTime {
pub hour: u8,
pub minute: u8,
pub second: u8,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EfiHiiDate {
pub year: u16,
pub month: u8,
pub day: u8,
}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct EfiHiiRef {
pub question_id: EfiQuestionId,
pub form_id: EfiFormId,
pub guid: Guid,
pub string_id: EfiStringId,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub union EfiIfrTypeValue {
pub u8: u8, // EFI_IFR_TYPE_NUM_SIZE_8
pub u16: u16, // EFI_IFR_TYPE_NUM_SIZE_16
pub u32: u32, // EFI_IFR_TYPE_NUM_SIZE_32
pub u64: u64, // EFI_IFR_TYPE_NUM_SIZE_64
pub b: bool, // EFI_IFR_TYPE_BOOLEAN
pub time: EfiHiiTime, // EFI_IFR_TYPE_TIME
pub date: EfiHiiDate, // EFI_IFR_TYPE_DATE
pub string: EfiStringId, // EFI_IFR_TYPE_STRING, EFI_IFR_TYPE_ACTION
pub hii_ref: EfiHiiRef, // EFI_IFR_TYPE_REF
}
impl core::fmt::Debug for EfiIfrTypeValue {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("EfiIfrTypeValue").finish()
}
}

pub type EfiQuestionId = u16;
pub type EfiFormId = u16;
pub type EfiStringId = u16;

/// EFI_HII_CONFIG_ACCESS_PROTOCOL
#[derive(Debug)]
#[repr(C)]
pub struct HiiConfigAccessProtocol {
pub extract_config: unsafe extern "efiapi" fn(
this: *const Self,
request: *const Char16,
progress: *mut *const Char16,
results: *mut *const Char16,
) -> Status,
pub route_config: unsafe extern "efiapi" fn(
this: *const Self,
configuration: *const Char16,
progress: *mut *const Char16,
) -> Status,
pub callback: unsafe extern "efiapi" fn(
this: *const Self,
action: EfiBrowserAction,
question_id: u16,
value_type: u8,
value: *mut EfiIfrTypeValue,
action_request: *mut EfiBrowserActionRequest,
) -> Status,
}

impl HiiConfigAccessProtocol {
pub const GUID: Guid = guid!("330d4706-f2a0-4e4f-a369-b66fa8d54385");
}
1 change: 1 addition & 0 deletions uefi-raw/src/protocol/hii/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

//! HII Protocols

pub mod config;
pub mod database;

use crate::{Char16, Guid};
Expand Down
3 changes: 3 additions & 0 deletions uefi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
- Added `ConfigTableEntry::MEMORY_ATTRIBUTES_GUID` and `ConfigTableEntry::IMAGE_SECURITY_DATABASE_GUID`.
- Added `proto::usb::io::UsbIo`.
- Added `proto::pci::PciRootBridgeIo`.
- Added `proto::hii::config::HiiKeywordHandler`.
- Added `proto::hii::config::HiiConfigAccess`.
- Added `proto::hii::config_str::ConfigurationString`.

## Changed
- **Breaking:** `boot::stall` now take `core::time::Duration` instead of `usize`.
Expand Down
30 changes: 30 additions & 0 deletions uefi/src/proto/hii/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: MIT OR Apache-2.0

//! HII Configuration protocols.

use uefi_macros::unsafe_protocol;
use uefi_raw::protocol::hii::config::{HiiConfigAccessProtocol, HiiKeywordHandlerProtocol};

/// The HII Keyword Handler Protocol.
///
/// # UEFI Spec Description
///
/// This protocol provides the mechanism to set and get the values associated
/// with a keyword exposed through a x-UEFI- prefixed configuration language namespace.
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(HiiKeywordHandlerProtocol::GUID)]
pub struct HiiKeywordHandler(HiiKeywordHandlerProtocol);

/// The HII Configuration Access Protocol.
///
/// # UEFI Spec Description
///
/// This protocol is responsible for facilitating access to configuration data from HII.
/// It is typically invoked by the HII Configuration Routing Protocol for handling
/// configuration requests. Forms browsers also interact with this protocol through
/// the `Callback()` function.
#[derive(Debug)]
#[repr(transparent)]
#[unsafe_protocol(HiiConfigAccessProtocol::GUID)]
pub struct HiiConfigAccess(HiiConfigAccessProtocol);
Loading