From 6c29b628f7c7e4f9d3b39fe09e424481c906e70b Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 22 Sep 2026 12:51:48 +0200 Subject: [PATCH] If "reboot into BIOS Setup", skip UI This can happen in two cases: - From the OS, the user requests booting into the setup menu - On linux via `systemctl reboot --firmware` - On Windows via `shutdown /r /fw /t 0` - From the app by pressing F12 The latter case currently does not work on our hardware because the "app" is actually loaded as a driver with a depex before the setup menu. So pressing F12 will just land you back into the app. I never noticed this in my testing because I usually run it as an app from the UEFI shell. Signed-off-by: Daniel Schaefer --- src/main.rs | 10 +++++++++- src/state_machine.rs | 12 ++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 0e1b04d..eba08dc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -100,7 +100,15 @@ fn main(image_handle: Handle, mut system_table: SystemTable) -> Status { // Show the UI if we can't tell the BIOS settings or they indicate we need to show the UI let show_ui = show_ui(boot_services) != Some(false); - let reset = if force_ui || show_ui { + // If a reboot into the setup menu was requested (e.g. via F12 in this app), don't get + // in the way. The firmware only acts on OsIndications after this driver has run. + let setup_requested = + state_machine::boot_to_fw_ui_requested(system_table.runtime_services()); + if setup_requested { + info!("Boot to firmware UI requested, skipping UI"); + } + + let reset = if force_ui || (show_ui && !setup_requested) { ec_comm::set_uefi_app_mode(&ec, true); let gui_res = state_machine::start(boot_services, &system_table, &ec, force_ui); ec_comm::set_uefi_app_mode(&ec, false); diff --git a/src/state_machine.rs b/src/state_machine.rs index b1c3911..796a7dd 100644 --- a/src/state_machine.rs +++ b/src/state_machine.rs @@ -1000,6 +1000,18 @@ fn has_bay_issue( None } +/// Check whether the firmware was asked to boot into the setup menu (`OsIndications` has +/// `EFI_OS_INDICATIONS_BOOT_TO_FW_UI` set), for example by F12 in this app or by the OS. +pub fn boot_to_fw_ui_requested(rt: &RuntimeServices) -> bool { + let vendor = VariableVendor(EFI_GLOBAL_VARIABLE_GUID); + let mut buf = [0; 8]; + match rt.get_variable(cstr16!("OsIndications"), &vendor, &mut buf) { + Ok(_) => u64::from_ne_bytes(buf) & EFI_OS_INDICATIONS_BOOT_TO_FW_UI != 0, + // Variable doesn't exist (or is unreadable) -> nothing requested + Err(_) => false, + } +} + /// Set OS indications so that a reboot will boot into setup menu fn set_os_indications_setupmenu(rt: &RuntimeServices) { let vendor = VariableVendor(EFI_GLOBAL_VARIABLE_GUID);