uefi_raw/table/
runtime.rs

1//! UEFI services available at runtime, even after the OS boots.
2
3use crate::capsule::CapsuleHeader;
4use crate::table::boot::MemoryDescriptor;
5use crate::table::Header;
6use crate::time::Time;
7use crate::{guid, Char16, Guid, PhysicalAddress, Status};
8use bitflags::bitflags;
9use core::ffi::c_void;
10
11/// Table of pointers to all the runtime services.
12///
13/// This table, and the function pointers it contains are valid even after the
14/// UEFI OS loader and OS have taken control of the platform.
15#[derive(Debug)]
16#[repr(C)]
17pub struct RuntimeServices {
18    pub header: Header,
19    pub get_time:
20        unsafe extern "efiapi" fn(time: *mut Time, capabilities: *mut TimeCapabilities) -> Status,
21    pub set_time: unsafe extern "efiapi" fn(time: *const Time) -> Status,
22    pub get_wakeup_time:
23        unsafe extern "efiapi" fn(enabled: *mut u8, pending: *mut u8, time: *mut Time) -> Status,
24    pub set_wakeup_time: unsafe extern "efiapi" fn(enable: u8, time: *const Time) -> Status,
25    pub set_virtual_address_map: unsafe extern "efiapi" fn(
26        map_size: usize,
27        desc_size: usize,
28        desc_version: u32,
29        virtual_map: *mut MemoryDescriptor,
30    ) -> Status,
31    pub convert_pointer:
32        unsafe extern "efiapi" fn(debug_disposition: usize, address: *mut *const c_void) -> Status,
33    pub get_variable: unsafe extern "efiapi" fn(
34        variable_name: *const Char16,
35        vendor_guid: *const Guid,
36        attributes: *mut VariableAttributes,
37        data_size: *mut usize,
38        data: *mut u8,
39    ) -> Status,
40    pub get_next_variable_name: unsafe extern "efiapi" fn(
41        variable_name_size: *mut usize,
42        variable_name: *mut u16,
43        vendor_guid: *mut Guid,
44    ) -> Status,
45    pub set_variable: unsafe extern "efiapi" fn(
46        variable_name: *const Char16,
47        vendor_guid: *const Guid,
48        attributes: VariableAttributes,
49        data_size: usize,
50        data: *const u8,
51    ) -> Status,
52    pub get_next_high_monotonic_count: unsafe extern "efiapi" fn(high_count: *mut u32) -> Status,
53    pub reset_system: unsafe extern "efiapi" fn(
54        rt: ResetType,
55        status: Status,
56        data_size: usize,
57        data: *const u8,
58    ) -> !,
59
60    // UEFI 2.0 Capsule Services.
61    pub update_capsule: unsafe extern "efiapi" fn(
62        capsule_header_array: *const *const CapsuleHeader,
63        capsule_count: usize,
64        scatter_gather_list: PhysicalAddress,
65    ) -> Status,
66    pub query_capsule_capabilities: unsafe extern "efiapi" fn(
67        capsule_header_array: *const *const CapsuleHeader,
68        capsule_count: usize,
69        maximum_capsule_size: *mut u64,
70        reset_type: *mut ResetType,
71    ) -> Status,
72
73    // Miscellaneous UEFI 2.0 Service.
74    pub query_variable_info: unsafe extern "efiapi" fn(
75        attributes: VariableAttributes,
76        maximum_variable_storage_size: *mut u64,
77        remaining_variable_storage_size: *mut u64,
78        maximum_variable_size: *mut u64,
79    ) -> Status,
80}
81
82newtype_enum! {
83    #[derive(Default)]
84    /// The type of system reset.
85    pub enum ResetType: u32 => {
86        /// System-wide reset.
87        ///
88        /// This is analogous to power cycling the device.
89        COLD = 0,
90
91        /// System-wide re-initialization.
92        ///
93        /// If the system doesn't support a warm reset, this will trigger a cold
94        /// reset.
95        WARM = 1,
96
97        /// The system is powered off.
98        SHUTDOWN = 2,
99
100        /// A platform-specific reset type.
101        PLATFORM_SPECIFIC = 3,
102    }
103}
104
105/// Real time clock capabilities.
106#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
107#[repr(C)]
108pub struct TimeCapabilities {
109    /// Reporting resolution of the clock in counts per second. 1 for a normal
110    /// PC-AT CMOS RTC device, which reports the time with 1-second resolution.
111    pub resolution: u32,
112
113    /// Timekeeping accuracy in units of 1e-6 parts per million.
114    pub accuracy: u32,
115
116    /// Whether a time set operation clears the device's time below the
117    /// "resolution" reporting level. False for normal PC-AT CMOS RTC devices.
118    pub sets_to_zero: bool,
119}
120
121bitflags! {
122    /// Flags describing the attributes of a variable.
123    #[repr(transparent)]
124    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
125    pub struct VariableAttributes: u32 {
126        /// Variable is maintained across a power cycle.
127        const NON_VOLATILE = 0x01;
128
129        /// Variable is accessible during the time that boot services are
130        /// accessible.
131        const BOOTSERVICE_ACCESS = 0x02;
132
133        /// Variable is accessible during the time that runtime services are
134        /// accessible.
135        const RUNTIME_ACCESS = 0x04;
136
137        /// Variable is stored in the portion of NVR allocated for error
138        /// records.
139        const HARDWARE_ERROR_RECORD = 0x08;
140
141        /// Deprecated.
142        const AUTHENTICATED_WRITE_ACCESS = 0x10;
143
144        /// Variable payload begins with an EFI_VARIABLE_AUTHENTICATION_2
145        /// structure.
146        const TIME_BASED_AUTHENTICATED_WRITE_ACCESS = 0x20;
147
148        /// This is never set in the attributes returned by
149        /// `get_variable`. When passed to `set_variable`, the variable payload
150        /// will be appended to the current value of the variable if supported
151        /// by the firmware.
152        const APPEND_WRITE = 0x40;
153
154        /// Variable payload begins with an EFI_VARIABLE_AUTHENTICATION_3
155        /// structure.
156        const ENHANCED_AUTHENTICATED_ACCESS = 0x80;
157    }
158}
159
160newtype_enum! {
161    /// Variable vendor GUID. This serves as a namespace for variables to
162    /// avoid naming conflicts between vendors. The UEFI specification
163    /// defines some special values, and vendors will define their own.
164    pub enum VariableVendor: Guid => {
165        /// Used to access global variables.
166        GLOBAL_VARIABLE = guid!("8be4df61-93ca-11d2-aa0d-00e098032b8c"),
167
168        /// Used to access EFI signature database variables.
169        IMAGE_SECURITY_DATABASE = guid!("d719b2cb-3d3a-4596-a3bc-dad00e67656f"),
170    }
171}