1 //! Miscellaneous protocols. 2 3 use uefi_raw::protocol::misc::{ 4 ResetNotificationProtocol, ResetSystemFn, TimestampProperties, TimestampProtocol, 5 }; 6 7 use crate::proto::unsafe_protocol; 8 use crate::{Result, StatusExt}; 9 10 /// Protocol for retrieving a high-resolution timestamp counter. 11 /// **Note:** 12 /// If your UEFI firmware not support timestamp protocol which first added at UEFI spec 2.4 2013. 13 /// you also could use `RDTSC` in rust, here is a demo [Slint-UI](https://github.com/slint-ui/slint/blob/2c0ba2bc0f151eba8d1fa17839fa2ac58832ca80/examples/uefi-demo/main.rs#L28-L62) who use uefi-rs. 14 #[derive(Debug)] 15 #[repr(transparent)] 16 #[unsafe_protocol(TimestampProtocol::GUID)] 17 pub struct Timestamp(TimestampProtocol); 18 19 impl Timestamp { 20 /// Get the current value of the timestamp counter. 21 #[must_use] get_timestamp(&self) -> u6422 pub fn get_timestamp(&self) -> u64 { 23 unsafe { (self.0.get_timestamp)() } 24 } 25 26 /// Get the properties of the timestamp counter. get_properties(&self) -> Result<TimestampProperties>27 pub fn get_properties(&self) -> Result<TimestampProperties> { 28 let mut properties = TimestampProperties::default(); 29 unsafe { (self.0.get_properties)(&mut properties) }.to_result_with_val(|| properties) 30 } 31 } 32 33 /// Protocol to register for a notification when ResetSystem is called. 34 #[derive(Debug)] 35 #[repr(transparent)] 36 #[unsafe_protocol(ResetNotificationProtocol::GUID)] 37 pub struct ResetNotification(ResetNotificationProtocol); 38 39 impl ResetNotification { 40 /// Register a notification function to be called when ResetSystem() is called. 41 /// 42 /// 43 /// # Example 44 /// 45 /// ```rust 46 /// use log::info; 47 /// use uefi::{boot, Handle}; 48 /// use uefi::proto::misc::{ResetNotification}; 49 /// use uefi_raw::Status; 50 /// use uefi_raw::table::runtime; 51 /// 52 /// 53 /// // value efi_reset_fn is the type of ResetSystemFn, a function pointer 54 /// unsafe extern "efiapi" fn efi_reset_fn( 55 /// rt: runtime::ResetType, 56 /// status: Status, 57 /// data_size: usize, 58 /// data: *const u8, 59 /// ){ 60 /// info!("Inside the event callback"); 61 /// info!("do what you want"); 62 /// } 63 /// 64 /// pub fn test(image: Handle) { 65 /// 66 /// let mut rn = boot::open_protocol_exclusive::<ResetNotification>(image) 67 /// .expect("Failed to open Timestamp protocol"); 68 /// 69 /// rn.register_reset_notify(efi_reset_fn) 70 /// .expect("Failed to register a reset notification function!"); 71 /// } 72 /// ``` register_reset_notify(&mut self, reset_function: ResetSystemFn) -> Result73 pub fn register_reset_notify(&mut self, reset_function: ResetSystemFn) -> Result { 74 unsafe { (self.0.register_reset_notify)(&mut self.0, reset_function) }.to_result() 75 } 76 77 /// Remove a reset notification function that was previously registered with [`ResetNotification::register_reset_notify`]. unregister_reset_notify(&mut self, reset_function: ResetSystemFn) -> Result78 pub fn unregister_reset_notify(&mut self, reset_function: ResetSystemFn) -> Result { 79 unsafe { (self.0.unregister_reset_notify)(&mut self.0, reset_function) }.to_result() 80 } 81 } 82