use log::error;
use uefi::{
Status, boot, cstr16,
runtime::{self, ResetType, VariableAttributes, VariableVendor},
};
use crate::{
BootResult,
system::variable::{get_variable, set_variable},
};
const EFI_OS_INDICATIONS_BOOT_TO_FW_UI: u64 = 1;
pub fn reset_to_firmware() -> ! {
if let Err(e) = set_reset_to_firmware_flag() {
error!("Failed to set OsIndications: {e}");
boot::stall(5_000_000);
}
runtime::reset(ResetType::WARM, Status::SUCCESS, None)
}
fn set_reset_to_firmware_flag() -> BootResult<()> {
let mut osind = get_variable::<u64>(
cstr16!("OsIndications"),
Some(VariableVendor::GLOBAL_VARIABLE),
)?; osind |= EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
set_variable::<u64>(
cstr16!("OsIndications"),
Some(VariableVendor::GLOBAL_VARIABLE),
Some(
VariableAttributes::NON_VOLATILE
| VariableAttributes::BOOTSERVICE_ACCESS
| VariableAttributes::RUNTIME_ACCESS,
),
Some(osind),
)?;
Ok(())
}