| //! UEFI services available at runtime, even after the OS boots. |
| |
| use crate::capsule::CapsuleHeader; |
| use crate::table::boot::MemoryDescriptor; |
| use crate::table::Header; |
| use crate::time::Time; |
| use crate::{guid, Char16, Guid, PhysicalAddress, Status}; |
| use bitflags::bitflags; |
| use core::ffi::c_void; |
| |
| /// Table of pointers to all the runtime services. |
| /// |
| /// This table, and the function pointers it contains are valid even after the |
| /// UEFI OS loader and OS have taken control of the platform. |
| #[derive(Debug)] |
| #[repr(C)] |
| pub struct RuntimeServices { |
| pub header: Header, |
| pub get_time: |
| unsafe extern "efiapi" fn(time: *mut Time, capabilities: *mut TimeCapabilities) -> Status, |
| pub set_time: unsafe extern "efiapi" fn(time: *const Time) -> Status, |
| pub get_wakeup_time: |
| unsafe extern "efiapi" fn(enabled: *mut u8, pending: *mut u8, time: *mut Time) -> Status, |
| pub set_wakeup_time: unsafe extern "efiapi" fn(enable: u8, time: *const Time) -> Status, |
| pub set_virtual_address_map: unsafe extern "efiapi" fn( |
| map_size: usize, |
| desc_size: usize, |
| desc_version: u32, |
| virtual_map: *mut MemoryDescriptor, |
| ) -> Status, |
| pub convert_pointer: |
| unsafe extern "efiapi" fn(debug_disposition: usize, address: *mut *const c_void) -> Status, |
| pub get_variable: unsafe extern "efiapi" fn( |
| variable_name: *const Char16, |
| vendor_guid: *const Guid, |
| attributes: *mut VariableAttributes, |
| data_size: *mut usize, |
| data: *mut u8, |
| ) -> Status, |
| pub get_next_variable_name: unsafe extern "efiapi" fn( |
| variable_name_size: *mut usize, |
| variable_name: *mut u16, |
| vendor_guid: *mut Guid, |
| ) -> Status, |
| pub set_variable: unsafe extern "efiapi" fn( |
| variable_name: *const Char16, |
| vendor_guid: *const Guid, |
| attributes: VariableAttributes, |
| data_size: usize, |
| data: *const u8, |
| ) -> Status, |
| pub get_next_high_monotonic_count: unsafe extern "efiapi" fn(high_count: *mut u32) -> Status, |
| pub reset_system: unsafe extern "efiapi" fn( |
| rt: ResetType, |
| status: Status, |
| data_size: usize, |
| data: *const u8, |
| ) -> !, |
| |
| // UEFI 2.0 Capsule Services. |
| pub update_capsule: unsafe extern "efiapi" fn( |
| capsule_header_array: *const *const CapsuleHeader, |
| capsule_count: usize, |
| scatter_gather_list: PhysicalAddress, |
| ) -> Status, |
| pub query_capsule_capabilities: unsafe extern "efiapi" fn( |
| capsule_header_array: *const *const CapsuleHeader, |
| capsule_count: usize, |
| maximum_capsule_size: *mut u64, |
| reset_type: *mut ResetType, |
| ) -> Status, |
| |
| // Miscellaneous UEFI 2.0 Service. |
| pub query_variable_info: unsafe extern "efiapi" fn( |
| attributes: VariableAttributes, |
| maximum_variable_storage_size: *mut u64, |
| remaining_variable_storage_size: *mut u64, |
| maximum_variable_size: *mut u64, |
| ) -> Status, |
| } |
| |
| newtype_enum! { |
| #[derive(Default)] |
| /// The type of system reset. |
| pub enum ResetType: u32 => { |
| /// System-wide reset. |
| /// |
| /// This is analogous to power cycling the device. |
| COLD = 0, |
| |
| /// System-wide re-initialization. |
| /// |
| /// If the system doesn't support a warm reset, this will trigger a cold |
| /// reset. |
| WARM = 1, |
| |
| /// The system is powered off. |
| SHUTDOWN = 2, |
| |
| /// A platform-specific reset type. |
| PLATFORM_SPECIFIC = 3, |
| } |
| } |
| |
| /// Real time clock capabilities. |
| #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[repr(C)] |
| pub struct TimeCapabilities { |
| /// Reporting resolution of the clock in counts per second. 1 for a normal |
| /// PC-AT CMOS RTC device, which reports the time with 1-second resolution. |
| pub resolution: u32, |
| |
| /// Timekeeping accuracy in units of 1e-6 parts per million. |
| pub accuracy: u32, |
| |
| /// Whether a time set operation clears the device's time below the |
| /// "resolution" reporting level. False for normal PC-AT CMOS RTC devices. |
| pub sets_to_zero: bool, |
| } |
| |
| bitflags! { |
| /// Flags describing the attributes of a variable. |
| #[repr(transparent)] |
| #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| pub struct VariableAttributes: u32 { |
| /// Variable is maintained across a power cycle. |
| const NON_VOLATILE = 0x01; |
| |
| /// Variable is accessible during the time that boot services are |
| /// accessible. |
| const BOOTSERVICE_ACCESS = 0x02; |
| |
| /// Variable is accessible during the time that runtime services are |
| /// accessible. |
| const RUNTIME_ACCESS = 0x04; |
| |
| /// Variable is stored in the portion of NVR allocated for error |
| /// records. |
| const HARDWARE_ERROR_RECORD = 0x08; |
| |
| /// Deprecated. |
| const AUTHENTICATED_WRITE_ACCESS = 0x10; |
| |
| /// Variable payload begins with an EFI_VARIABLE_AUTHENTICATION_2 |
| /// structure. |
| const TIME_BASED_AUTHENTICATED_WRITE_ACCESS = 0x20; |
| |
| /// This is never set in the attributes returned by |
| /// `get_variable`. When passed to `set_variable`, the variable payload |
| /// will be appended to the current value of the variable if supported |
| /// by the firmware. |
| const APPEND_WRITE = 0x40; |
| |
| /// Variable payload begins with an EFI_VARIABLE_AUTHENTICATION_3 |
| /// structure. |
| const ENHANCED_AUTHENTICATED_ACCESS = 0x80; |
| } |
| } |
| |
| newtype_enum! { |
| /// Variable vendor GUID. This serves as a namespace for variables to |
| /// avoid naming conflicts between vendors. The UEFI specification |
| /// defines some special values, and vendors will define their own. |
| pub enum VariableVendor: Guid => { |
| /// Used to access global variables. |
| GLOBAL_VARIABLE = guid!("8be4df61-93ca-11d2-aa0d-00e098032b8c"), |
| |
| /// Used to access EFI signature database variables. |
| IMAGE_SECURITY_DATABASE = guid!("d719b2cb-3d3a-4596-a3bc-dad00e67656f"), |
| } |
| } |