Skip to content

Commit

Permalink
Merge pull request #282 from rust-osdev/panic-unwind
Browse files Browse the repository at this point in the history
Handle panics by unwinding the stack and implement `check_event` method
  • Loading branch information
nicholasbishop authored Sep 7, 2021
2 parents 400c905 + 8da602f commit 1b55908
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 27 deletions.
4 changes: 0 additions & 4 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,6 @@ jobs:

- name: Run cargo test
uses: actions-rs/cargo@v1
env:
# This works around "duplicate item in crate core" errors:
# https://github.com/rust-lang/wg-cargo-std-aware/issues/56
CARGO_PROFILE_DEV_PANIC: unwind
with:
command: test
args: -Zbuild-std=std --target x86_64-unknown-linux-gnu --features=exts
Expand Down
6 changes: 0 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,6 @@ members = [
"uefi-test-runner",
]

[profile.dev]
panic = "abort"

[profile.release]
panic = "abort"

[patch.crates-io]
uefi-macros = { path = "uefi-macros" }
uefi = { path = "." }
33 changes: 23 additions & 10 deletions src/table/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub struct BootServices {
) -> Status,
signal_event: usize,
close_event: usize,
check_event: usize,
check_event: unsafe extern "efiapi" fn(event: Event) -> Status,

// Protocol handlers
install_protocol_interface: usize,
Expand Down Expand Up @@ -337,7 +337,17 @@ impl BootServices {
.into_with_val(|| event.assume_init())
}

/// Stops execution until an event is signaled
/// Sets the trigger for `EventType::TIMER` event.
pub fn set_timer(&self, event: Event, trigger_time: TimerTrigger) -> Result {
let (ty, time) = match trigger_time {
TimerTrigger::Cancel => (0, 0),
TimerTrigger::Periodic(hundreds_ns) => (1, hundreds_ns),
TimerTrigger::Relative(hundreds_ns) => (2, hundreds_ns),
};
unsafe { (self.set_timer)(event, ty, time) }.into()
}

/// Stops execution until an event is signaled.
///
/// This function must be called at priority level `Tpl::APPLICATION`. If an
/// attempt is made to call it at any other priority level, an `Unsupported`
Expand Down Expand Up @@ -379,14 +389,17 @@ impl BootServices {
)
}

/// Sets the trigger for `EventType::TIMER` event.
pub fn set_timer(&self, event: Event, trigger_time: TimerTrigger) -> Result {
let (ty, time) = match trigger_time {
TimerTrigger::Cancel => (0, 0),
TimerTrigger::Periodic(hundreds_ns) => (1, hundreds_ns),
TimerTrigger::Relative(hundreds_ns) => (2, hundreds_ns),
};
unsafe { (self.set_timer)(event, ty, time) }.into()
/// Checks to see if an event is signaled, without blocking execution to wait for it.
///
/// The returned value will be `true` if the event is in the signaled state,
/// otherwise `false` is returned.
pub fn check_event(&self, event: Event) -> Result<bool> {
let status = unsafe { (self.check_event)(event) };
match status {
Status::SUCCESS => Ok(true.into()),
Status::NOT_READY => Ok(false.into()),
_ => Err(status.into()),
}
}

/// Query a handle for a certain protocol.
Expand Down
26 changes: 19 additions & 7 deletions uefi-test-runner/src/boot/misc.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
use uefi::prelude::*;
use uefi::table::boot::{BootServices, EventType, TimerTrigger, Tpl};
use uefi::{prelude::*, Event};

pub fn test(bt: &BootServices) {
info!("Testing timer...");
test_timer(bt);
info!("Testing events...");
test_event_callback(bt);
info!("Testing watchdog...");
test_watchdog(bt);
}

fn test_watchdog(bt: &BootServices) {
// Disable the UEFI watchdog timer
bt.set_watchdog_timer(0, 0x10000, None)
.expect_success("Could not set watchdog timer");
}

fn test_timer(bt: &BootServices) {
let timer_event = unsafe { bt.create_event(EventType::TIMER, Tpl::APPLICATION, None) }
.expect_success("Failed to create TIMER event");
Expand All @@ -23,3 +19,19 @@ fn test_timer(bt: &BootServices) {
bt.wait_for_event(&mut events)
.expect_success("Wait for event failed");
}

fn test_event_callback(bt: &BootServices) {
fn callback(_event: Event) {
info!("Inside the event callback");
}
let event = unsafe { bt.create_event(EventType::NOTIFY_WAIT, Tpl::CALLBACK, Some(callback)) }
.expect_success("Failed to create custom event");
bt.check_event(event)
.expect_success("Failed to check event");
}

fn test_watchdog(bt: &BootServices) {
// Disable the UEFI watchdog timer
bt.set_watchdog_timer(0, 0x10000, None)
.expect_success("Could not set watchdog timer");
}

0 comments on commit 1b55908

Please sign in to comment.