From 9d3a022e084eaec8875a22a55ff7ed6d7a6ff3bb Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Thu, 30 Oct 2025 13:27:58 -0400 Subject: [PATCH] feat(bootloader-interface): add support for marking when the menu is being display --- src/integrations/bootloader_interface.rs | 5 +++++ src/main.rs | 3 ++- src/menu.rs | 12 +++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/integrations/bootloader_interface.rs b/src/integrations/bootloader_interface.rs index 2581f19..d1fd77a 100644 --- a/src/integrations/bootloader_interface.rs +++ b/src/integrations/bootloader_interface.rs @@ -25,6 +25,11 @@ impl BootloaderInterface { Self::mark_time("LoaderTimeExecUSec", timer) } + /// Tell the system that Sprout is about to display the menu. + pub fn mark_menu(timer: &PlatformTimer) -> Result<()> { + Self::mark_time("LoaderTimeMenuUsec", timer) + } + /// Tell the system about the current time as measured by the platform timer. /// Sets the variable specified by `key` to the number of microseconds. fn mark_time(key: &str, timer: &PlatformTimer) -> Result<()> { diff --git a/src/main.rs b/src/main.rs index 15579c5..13d030b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -285,7 +285,8 @@ fn run() -> Result<()> { .context(format!("unable to find entry: {force_boot_entry}"))? } else { // Delegate to the menu to select an entry to boot. - menu::select(menu_timeout, &entries).context("unable to select entry via boot menu")? + menu::select(&timer, menu_timeout, &entries) + .context("unable to select entry via boot menu")? }; // Tell the bootloader interface what the selected entry is. diff --git a/src/menu.rs b/src/menu.rs index baa7ea0..a735bb1 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -1,4 +1,6 @@ use crate::entries::BootableEntry; +use crate::integrations::bootloader_interface::BootloaderInterface; +use crate::platform::timer::PlatformTimer; use anyhow::{Context, Result, bail}; use log::info; use std::time::Duration; @@ -162,7 +164,15 @@ fn select_with_input<'a>( /// Shows a boot menu to select a bootable entry to boot. /// The actual work is done internally in [select_with_input] which is called /// within the context of the standard input device. -pub fn select(timeout: Duration, entries: &[BootableEntry]) -> Result<&BootableEntry> { +pub fn select<'live>( + timer: &'live PlatformTimer, + timeout: Duration, + entries: &'live [BootableEntry], +) -> Result<&'live BootableEntry> { + // Notify the bootloader interface that we are about to display the menu. + BootloaderInterface::mark_menu(timer) + .context("unable to mark menu display in bootloader interface")?; + // Acquire the standard input device and run the boot menu. uefi::system::with_stdin(move |input| select_with_input(input, timeout, entries)) }