Skip to content

Commit 374dad9

Browse files
authored
Merge pull request #1311 from nicholasbishop/bishop-watchdog
boot: Add freestanding set_watchdog_timer
2 parents d4e46c3 + a11f98a commit 374dad9

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

uefi-test-runner/src/boot/misc.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,14 @@ fn test_callback_with_ctx(bt: &BootServices) {
119119
}
120120

121121
fn test_watchdog(bt: &BootServices) {
122-
// Disable the UEFI watchdog timer
122+
// There's no way to check the watchdog timer value, so just test setting it.
123+
124+
// Disable the UEFI watchdog timer.
123125
bt.set_watchdog_timer(0, 0x10000, None)
124126
.expect("Could not set watchdog timer");
127+
128+
// Set the timer with the freestanding function.
129+
boot::set_watchdog_timer(240, 0x10000, None).expect("Could not set watchdog timer");
125130
}
126131

127132
/// Dummy protocol for tests

uefi/src/boot.rs

+47
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,53 @@ pub unsafe fn install_configuration_table(
804804
(bt.install_configuration_table)(guid_entry, table_ptr).to_result()
805805
}
806806

807+
/// Sets the watchdog timer.
808+
///
809+
/// UEFI will start a 5-minute countdown after an UEFI image is loaded. The
810+
/// image must either successfully load an OS and exit boot services in that
811+
/// time, or disable the watchdog.
812+
///
813+
/// Otherwise, the firmware will log the event using the provided numeric
814+
/// code and data, then reset the system.
815+
///
816+
/// This function allows you to change the watchdog timer's timeout to a
817+
/// certain amount of seconds or to disable the watchdog entirely. It also
818+
/// allows you to change what will be logged when the timer expires.
819+
///
820+
/// The watchdog codes from 0 to 0xffff (65535) are reserved for internal
821+
/// firmware use. Higher values can be used freely by applications.
822+
///
823+
/// If provided, the watchdog data must be a null-terminated string optionally
824+
/// followed by other binary data.
825+
///
826+
/// # Errors
827+
///
828+
/// * [`Status::INVALID_PARAMETER`]: `watchdog_code` is invalid.
829+
/// * [`Status::UNSUPPORTED`]: the system does not have a watchdog timer.
830+
/// * [`Status::DEVICE_ERROR`]: the watchdog timer could not be set due to a
831+
/// hardware error.
832+
pub fn set_watchdog_timer(
833+
timeout_in_seconds: usize,
834+
watchdog_code: u64,
835+
data: Option<&mut [u16]>,
836+
) -> Result {
837+
let bt = boot_services_raw_panicking();
838+
let bt = unsafe { bt.as_ref() };
839+
840+
let (data_len, data) = data
841+
.map(|d| {
842+
assert!(
843+
d.contains(&0),
844+
"Watchdog data must start with a null-terminated string"
845+
);
846+
(d.len(), d.as_mut_ptr())
847+
})
848+
.unwrap_or((0, ptr::null_mut()));
849+
850+
unsafe { (bt.set_watchdog_timer)(timeout_in_seconds, watchdog_code, data_len, data) }
851+
.to_result()
852+
}
853+
807854
/// Stalls execution for the given number of microseconds.
808855
pub fn stall(microseconds: usize) {
809856
let bt = boot_services_raw_panicking();

0 commit comments

Comments
 (0)