Skip to content

Commit a6e707d

Browse files
wip: Add uefi::runtime module
1 parent d83db37 commit a6e707d

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed

uefi/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ mod result;
120120
pub use result::{Error, Result, ResultExt, Status, StatusExt};
121121

122122
pub mod boot;
123+
pub mod runtime;
123124
pub mod system;
124125
pub mod table;
125126

uefi/src/runtime.rs

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
//! TODO
2+
3+
// TODO
4+
#![allow(clippy::missing_safety_doc)]
5+
6+
use crate::table::boot::MemoryDescriptor;
7+
use crate::table::runtime::{
8+
ResetType, RuntimeServices, Time, TimeCapabilities, VariableAttributes, VariableStorageInfo,
9+
VariableVendor,
10+
};
11+
use crate::{system, CStr16, Result, Status};
12+
use core::ptr::NonNull;
13+
14+
#[cfg(feature = "alloc")]
15+
use {crate::table::runtime::VariableKey, alloc::boxed::Box, alloc::vec::Vec};
16+
17+
fn runtime_services() -> NonNull<RuntimeServices> {
18+
let st = unsafe { system::system_table().as_mut() };
19+
NonNull::new(st.runtime_services.cast()).expect("runtime services are not active")
20+
}
21+
22+
/// Query the current time and date information
23+
pub fn get_time() -> Result<Time> {
24+
unsafe { runtime_services().as_mut() }.get_time()
25+
}
26+
27+
/// Query the current time and date information and the RTC capabilities
28+
pub fn get_time_and_caps() -> Result<(Time, TimeCapabilities)> {
29+
unsafe { runtime_services().as_mut() }.get_time_and_caps()
30+
}
31+
32+
/// Sets the current local time and date information
33+
///
34+
/// During runtime, if a PC-AT CMOS device is present in the platform, the
35+
/// caller must synchronize access to the device before calling `set_time`.
36+
///
37+
/// # Safety
38+
///
39+
/// Undefined behavior could happen if multiple tasks try to
40+
/// use this function at the same time without synchronisation.
41+
pub unsafe fn set_time(time: &Time) -> Result {
42+
unsafe { runtime_services().as_mut() }.set_time(time)
43+
}
44+
45+
/// Get the size (in bytes) of a variable. This can be used to find out how
46+
/// big of a buffer should be passed in to `get_variable`.
47+
pub fn get_variable_size(name: &CStr16, vendor: &VariableVendor) -> Result<usize> {
48+
unsafe { runtime_services().as_mut() }.get_variable_size(name, vendor)
49+
}
50+
51+
/// Get the contents and attributes of a variable. The size of `buf` must
52+
/// be at least as big as the variable's size, although it can be
53+
/// larger. If it is too small, `BUFFER_TOO_SMALL` is returned.
54+
///
55+
/// On success, a tuple containing the variable's value (a slice of `buf`)
56+
/// and the variable's attributes is returned.
57+
pub fn get_variable<'a>(
58+
name: &CStr16,
59+
vendor: &VariableVendor,
60+
buf: &'a mut [u8],
61+
) -> Result<(&'a [u8], VariableAttributes)> {
62+
unsafe { runtime_services().as_mut() }.get_variable(name, vendor, buf)
63+
}
64+
65+
/// Get the contents and attributes of a variable.
66+
#[cfg(feature = "alloc")]
67+
pub fn get_variable_boxed(
68+
name: &CStr16,
69+
vendor: &VariableVendor,
70+
) -> Result<(Box<[u8]>, VariableAttributes)> {
71+
unsafe { runtime_services().as_mut() }.get_variable_boxed(name, vendor)
72+
}
73+
74+
/// Get the names and vendor GUIDs of all currently-set variables.
75+
#[cfg(feature = "alloc")]
76+
pub fn variable_keys() -> Result<Vec<VariableKey>> {
77+
unsafe { runtime_services().as_mut() }.variable_keys()
78+
}
79+
80+
/// Set the value of a variable. This can be used to create a new variable,
81+
/// update an existing variable, or (when the size of `data` is zero)
82+
/// delete a variable.
83+
///
84+
/// # Warnings
85+
///
86+
/// The [`Status::WARN_RESET_REQUIRED`] warning will be returned when using
87+
/// this function to transition the Secure Boot mode to setup mode or audit
88+
/// mode if the firmware requires a reboot for that operation.
89+
pub fn set_variable(
90+
name: &CStr16,
91+
vendor: &VariableVendor,
92+
attributes: VariableAttributes,
93+
data: &[u8],
94+
) -> Result {
95+
unsafe { runtime_services().as_mut() }.set_variable(name, vendor, attributes, data)
96+
}
97+
98+
/// Deletes a UEFI variable.
99+
pub fn delete_variable(name: &CStr16, vendor: &VariableVendor) -> Result {
100+
unsafe { runtime_services().as_mut() }.delete_variable(name, vendor)
101+
}
102+
103+
/// Get information about UEFI variable storage space for the type
104+
/// of variable specified in `attributes`.
105+
///
106+
/// This operation is only supported starting with UEFI 2.0; earlier
107+
/// versions will fail with [`Status::UNSUPPORTED`].
108+
///
109+
/// See [`VariableStorageInfo`] for details of the information returned.
110+
pub fn query_variable_info(attributes: VariableAttributes) -> Result<VariableStorageInfo> {
111+
unsafe { runtime_services().as_mut() }.query_variable_info(attributes)
112+
}
113+
114+
/// Resets the computer.
115+
pub fn reset(rt: ResetType, status: Status, data: Option<&[u8]>) -> ! {
116+
unsafe { runtime_services().as_mut() }.reset(rt, status, data)
117+
}
118+
119+
/// TODO
120+
pub unsafe fn set_virtual_address_map(
121+
map_size: usize,
122+
desc_size: usize,
123+
desc_version: u32,
124+
virtual_map: *mut MemoryDescriptor,
125+
) -> Status {
126+
unsafe { runtime_services().as_mut() }.set_virtual_address_map(
127+
map_size,
128+
desc_size,
129+
desc_version,
130+
virtual_map,
131+
)
132+
}

0 commit comments

Comments
 (0)