1 //! UEFI services available at runtime, even after the OS boots. 2 3 use crate::capsule::CapsuleHeader; 4 use crate::table::boot::MemoryDescriptor; 5 use crate::table::Header; 6 use crate::time::Time; 7 use crate::{guid, Char16, Guid, PhysicalAddress, Status}; 8 use bitflags::bitflags; 9 use 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)] 17 pub 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 82 newtype_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)] 108 pub 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 121 bitflags! { 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 160 newtype_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 } 172