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