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);