Skip to content

Commit 2c361a8

Browse files
committedJul 19, 2024
wip: Implement more of the uefi::runtime module
1 parent b9cf954 commit 2c361a8

File tree

1 file changed

+105
-2
lines changed

1 file changed

+105
-2
lines changed
 

‎uefi/src/runtime.rs

+105-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@
55
//! functions after exiting boot services; see the "Calling Convention" section
66
//! of the UEFI specification for details.
77
8-
use crate::table::{self};
9-
use crate::{Result, StatusExt};
8+
use crate::table::boot::MemoryDescriptor;
9+
use crate::table::runtime::{
10+
ResetType, RuntimeServices, VariableAttributes, VariableStorageInfo, VariableVendor,
11+
};
12+
use crate::{table, CStr16, Result, Status, StatusExt};
1013
use core::ptr::{self, NonNull};
1114

15+
#[cfg(feature = "alloc")]
16+
use {crate::table::runtime::VariableKey, alloc::boxed::Box, alloc::vec::Vec};
17+
1218
pub use crate::table::runtime::{Daylight, Time, TimeCapabilities, TimeError, TimeParams};
1319

1420
fn runtime_services_raw_panicking() -> NonNull<uefi_raw::table::runtime::RuntimeServices> {
@@ -18,6 +24,14 @@ fn runtime_services_raw_panicking() -> NonNull<uefi_raw::table::runtime::Runtime
1824
NonNull::new(st.runtime_services).expect("runtime services are not active")
1925
}
2026

27+
// TODO
28+
#[track_caller]
29+
fn runtime_services() -> NonNull<RuntimeServices> {
30+
let st = table::system_table_runtime().expect("runtime services are not available");
31+
let ptr: *const _ = unsafe { st.runtime_services() };
32+
NonNull::new(ptr.cast_mut()).unwrap()
33+
}
34+
2135
/// Query the current time and date information.
2236
pub fn get_time() -> Result<Time> {
2337
let rt = runtime_services_raw_panicking();
@@ -55,3 +69,92 @@ pub unsafe fn set_time(time: &Time) -> Result {
5569
let time: *const Time = time;
5670
(rt.set_time)(time.cast()).to_result()
5771
}
72+
73+
/// Get the size (in bytes) of a variable. This can be used to find out how
74+
/// big of a buffer should be passed in to `get_variable`.
75+
pub fn get_variable_size(name: &CStr16, vendor: &VariableVendor) -> Result<usize> {
76+
unsafe { runtime_services().as_mut() }.get_variable_size(name, vendor)
77+
}
78+
79+
/// Get the contents and attributes of a variable. The size of `buf` must
80+
/// be at least as big as the variable's size, although it can be
81+
/// larger. If it is too small, `BUFFER_TOO_SMALL` is returned.
82+
///
83+
/// On success, a tuple containing the variable's value (a slice of `buf`)
84+
/// and the variable's attributes is returned.
85+
pub fn get_variable<'a>(
86+
name: &CStr16,
87+
vendor: &VariableVendor,
88+
buf: &'a mut [u8],
89+
) -> Result<(&'a [u8], VariableAttributes)> {
90+
unsafe { runtime_services().as_mut() }.get_variable(name, vendor, buf)
91+
}
92+
93+
/// Get the contents and attributes of a variable.
94+
#[cfg(feature = "alloc")]
95+
pub fn get_variable_boxed(
96+
name: &CStr16,
97+
vendor: &VariableVendor,
98+
) -> Result<(Box<[u8]>, VariableAttributes)> {
99+
unsafe { runtime_services().as_mut() }.get_variable_boxed(name, vendor)
100+
}
101+
102+
/// Get the names and vendor GUIDs of all currently-set variables.
103+
#[cfg(feature = "alloc")]
104+
pub fn variable_keys() -> Result<Vec<VariableKey>> {
105+
unsafe { runtime_services().as_mut() }.variable_keys()
106+
}
107+
108+
/// Set the value of a variable. This can be used to create a new variable,
109+
/// update an existing variable, or (when the size of `data` is zero)
110+
/// delete a variable.
111+
///
112+
/// # Warnings
113+
///
114+
/// The [`Status::WARN_RESET_REQUIRED`] warning will be returned when using
115+
/// this function to transition the Secure Boot mode to setup mode or audit
116+
/// mode if the firmware requires a reboot for that operation.
117+
pub fn set_variable(
118+
name: &CStr16,
119+
vendor: &VariableVendor,
120+
attributes: VariableAttributes,
121+
data: &[u8],
122+
) -> Result {
123+
unsafe { runtime_services().as_mut() }.set_variable(name, vendor, attributes, data)
124+
}
125+
126+
/// Deletes a UEFI variable.
127+
pub fn delete_variable(name: &CStr16, vendor: &VariableVendor) -> Result {
128+
unsafe { runtime_services().as_mut() }.delete_variable(name, vendor)
129+
}
130+
131+
/// Get information about UEFI variable storage space for the type
132+
/// of variable specified in `attributes`.
133+
///
134+
/// This operation is only supported starting with UEFI 2.0; earlier
135+
/// versions will fail with [`Status::UNSUPPORTED`].
136+
///
137+
/// See [`VariableStorageInfo`] for details of the information returned.
138+
pub fn query_variable_info(attributes: VariableAttributes) -> Result<VariableStorageInfo> {
139+
unsafe { runtime_services().as_mut() }.query_variable_info(attributes)
140+
}
141+
142+
/// Resets the computer.
143+
pub fn reset(rt: ResetType, status: Status, data: Option<&[u8]>) -> ! {
144+
unsafe { runtime_services().as_mut() }.reset(rt, status, data)
145+
}
146+
147+
/// TODO
148+
pub unsafe fn set_virtual_address_map(
149+
map_size: usize,
150+
desc_size: usize,
151+
desc_version: u32,
152+
virtual_map: *mut MemoryDescriptor,
153+
) -> Status {
154+
unsafe { runtime_services().as_mut() }.set_virtual_address_map(
155+
map_size,
156+
desc_size,
157+
desc_version,
158+
virtual_map,
159+
)
160+
}

0 commit comments

Comments
 (0)