|  | 
| 21 | 21 | 
 | 
| 22 | 22 | pub use uefi::table::boot::{ | 
| 23 | 23 |     AllocateType, EventNotifyFn, LoadImageSource, OpenProtocolAttributes, OpenProtocolParams, | 
| 24 |  | -    SearchType, | 
|  | 24 | +    SearchType, TimerTrigger, | 
| 25 | 25 | }; | 
| 26 | 26 | pub use uefi_raw::table::boot::{EventType, MemoryType, Tpl}; | 
| 27 | 27 | 
 | 
| @@ -233,6 +233,78 @@ pub fn check_event(event: Event) -> Result<bool> { | 
| 233 | 233 |     } | 
| 234 | 234 | } | 
| 235 | 235 | 
 | 
|  | 236 | +/// Sets the trigger for an event of type [`TIMER`]. | 
|  | 237 | +/// | 
|  | 238 | +/// # Errors | 
|  | 239 | +/// | 
|  | 240 | +/// * [`Status::INVALID_PARAMETER`]: `event` is not valid. | 
|  | 241 | +/// | 
|  | 242 | +/// [`TIMER`]: EventType::TIMER | 
|  | 243 | +pub fn set_timer(event: &Event, trigger_time: TimerTrigger) -> Result { | 
|  | 244 | +    let bt = boot_services_raw_panicking(); | 
|  | 245 | +    let bt = unsafe { bt.as_ref() }; | 
|  | 246 | + | 
|  | 247 | +    let (ty, time) = match trigger_time { | 
|  | 248 | +        TimerTrigger::Cancel => (0, 0), | 
|  | 249 | +        TimerTrigger::Periodic(hundreds_ns) => (1, hundreds_ns), | 
|  | 250 | +        TimerTrigger::Relative(hundreds_ns) => (2, hundreds_ns), | 
|  | 251 | +    }; | 
|  | 252 | +    unsafe { (bt.set_timer)(event.as_ptr(), ty, time) }.to_result() | 
|  | 253 | +} | 
|  | 254 | + | 
|  | 255 | +/// Stops execution until an event is signaled. | 
|  | 256 | +/// | 
|  | 257 | +/// This function must be called at priority level [`Tpl::APPLICATION`]. | 
|  | 258 | +/// | 
|  | 259 | +/// The input [`Event`] slice is repeatedly iterated from first to last until | 
|  | 260 | +/// an event is signaled or an error is detected. The following checks are | 
|  | 261 | +/// performed on each event: | 
|  | 262 | +/// | 
|  | 263 | +/// * If an event is of type [`NOTIFY_SIGNAL`], then a | 
|  | 264 | +///   [`Status::INVALID_PARAMETER`] error is returned with the index of the | 
|  | 265 | +///   event that caused the failure. | 
|  | 266 | +/// * If an event is in the signaled state, the signaled state is cleared | 
|  | 267 | +///   and the index of the event that was signaled is returned. | 
|  | 268 | +/// * If an event is not in the signaled state but does have a notification | 
|  | 269 | +///   function, the notification function is queued at the event's | 
|  | 270 | +///   notification task priority level. If the execution of the event's | 
|  | 271 | +///   notification function causes the event to be signaled, then the | 
|  | 272 | +///   signaled state is cleared and the index of the event that was signaled | 
|  | 273 | +///   is returned. | 
|  | 274 | +/// | 
|  | 275 | +/// To wait for a specified time, a timer event must be included in `events`. | 
|  | 276 | +/// | 
|  | 277 | +/// To check if an event is signaled without waiting, an already signaled | 
|  | 278 | +/// event can be used as the last event in the slice being checked, or the | 
|  | 279 | +/// [`check_event`] interface may be used. | 
|  | 280 | +/// | 
|  | 281 | +/// # Errors | 
|  | 282 | +/// | 
|  | 283 | +/// * [`Status::INVALID_PARAMETER`]: `events` is empty, or one of the events of | 
|  | 284 | +///   of type [`NOTIFY_SIGNAL`]. | 
|  | 285 | +/// * [`Status::UNSUPPORTED`]: the current TPL is not [`Tpl::APPLICATION`]. | 
|  | 286 | +/// | 
|  | 287 | +/// [`NOTIFY_SIGNAL`]: EventType::NOTIFY_SIGNAL | 
|  | 288 | +pub fn wait_for_event(events: &mut [Event]) -> Result<usize, Option<usize>> { | 
|  | 289 | +    let bt = boot_services_raw_panicking(); | 
|  | 290 | +    let bt = unsafe { bt.as_ref() }; | 
|  | 291 | + | 
|  | 292 | +    let number_of_events = events.len(); | 
|  | 293 | +    let events: *mut uefi_raw::Event = events.as_mut_ptr().cast(); | 
|  | 294 | + | 
|  | 295 | +    let mut index = 0; | 
|  | 296 | +    unsafe { (bt.wait_for_event)(number_of_events, events, &mut index) }.to_result_with( | 
|  | 297 | +        || index, | 
|  | 298 | +        |s| { | 
|  | 299 | +            if s == Status::INVALID_PARAMETER { | 
|  | 300 | +                Some(index) | 
|  | 301 | +            } else { | 
|  | 302 | +                None | 
|  | 303 | +            } | 
|  | 304 | +        }, | 
|  | 305 | +    ) | 
|  | 306 | +} | 
|  | 307 | + | 
| 236 | 308 | /// Connect one or more drivers to a controller. | 
| 237 | 309 | /// | 
| 238 | 310 | /// Usually one disconnects and then reconnects certain drivers | 
|  | 
0 commit comments