Skip to content

Commit 6629c7e

Browse files
boot: Add freestanding create_event
1 parent aa0628b commit 6629c7e

File tree

1 file changed

+50
-4
lines changed

1 file changed

+50
-4
lines changed

uefi/src/boot.rs

+50-4
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
use crate::data_types::PhysicalAddress;
66
use crate::proto::device_path::DevicePath;
77
use crate::proto::{Protocol, ProtocolPointer};
8+
use crate::util::opt_nonnull_to_ptr;
89
use core::ffi::c_void;
910
use core::ops::{Deref, DerefMut};
1011
use core::ptr::{self, NonNull};
11-
use core::slice;
1212
use core::sync::atomic::{AtomicPtr, Ordering};
13-
use uefi::{table, Handle, Result, Status, StatusExt};
13+
use core::{mem, slice};
14+
use uefi::{table, Event, Handle, Result, Status, StatusExt};
1415

1516
#[cfg(doc)]
1617
use {
@@ -19,9 +20,10 @@ use {
1920
};
2021

2122
pub use uefi::table::boot::{
22-
AllocateType, LoadImageSource, OpenProtocolAttributes, OpenProtocolParams, SearchType,
23+
AllocateType, EventNotifyFn, LoadImageSource, OpenProtocolAttributes, OpenProtocolParams,
24+
SearchType,
2325
};
24-
pub use uefi_raw::table::boot::{MemoryType, Tpl};
26+
pub use uefi_raw::table::boot::{EventType, MemoryType, Tpl};
2527

2628
/// Global image handle. This is only set by [`set_image_handle`], and it is
2729
/// only read by [`image_handle`].
@@ -162,6 +164,50 @@ pub unsafe fn free_pool(ptr: NonNull<u8>) -> Result {
162164
unsafe { (bt.free_pool)(ptr.as_ptr()) }.to_result()
163165
}
164166

167+
/// Creates an event
168+
///
169+
/// This function creates a new event of the specified type and returns it.
170+
///
171+
/// Events are created in a "waiting" state, and may switch to a "signaled"
172+
/// state. If the event type has flag `NotifySignal` set, this will result in
173+
/// a callback for the event being immediately enqueued at the `notify_tpl`
174+
/// priority level. If the event type has flag `NotifyWait`, the notification
175+
/// will be delivered next time `wait_for_event` or `check_event` is called.
176+
/// In both cases, a `notify_fn` callback must be specified.
177+
///
178+
/// # Safety
179+
///
180+
/// This function is unsafe because callbacks must handle exit from boot
181+
/// services correctly.
182+
///
183+
/// # Errors
184+
///
185+
/// * [`Status::INVALID_PARAMETER`]: an invalid combination of parameters was provided.
186+
/// * [`Status::OUT_OF_RESOURCES`]: the event could not be allocated.
187+
pub unsafe fn create_event(
188+
event_ty: EventType,
189+
notify_tpl: Tpl,
190+
notify_fn: Option<EventNotifyFn>,
191+
notify_ctx: Option<NonNull<c_void>>,
192+
) -> Result<Event> {
193+
let bt = boot_services_raw_panicking();
194+
let bt = unsafe { bt.as_ref() };
195+
196+
let mut event = ptr::null_mut();
197+
198+
// Safety: the argument types of the function pointers are defined
199+
// differently, but are compatible and can be safely transmuted.
200+
let notify_fn: Option<uefi_raw::table::boot::EventNotifyFn> = mem::transmute(notify_fn);
201+
202+
let notify_ctx = opt_nonnull_to_ptr(notify_ctx);
203+
204+
// Now we're ready to call UEFI
205+
(bt.create_event)(event_ty, notify_tpl, notify_fn, notify_ctx, &mut event).to_result_with_val(
206+
// OK to unwrap: event is non-null for Status::SUCCESS.
207+
|| Event::from_ptr(event).unwrap(),
208+
)
209+
}
210+
165211
/// Connect one or more drivers to a controller.
166212
///
167213
/// Usually one disconnects and then reconnects certain drivers

0 commit comments

Comments
 (0)