Skip to content

Commit 9da5b55

Browse files
authored
Merge pull request #1249 from nicholasbishop/bishop-runtime-mod-time
Add uefi::runtime module
2 parents 1fa9408 + 233a33a commit 9da5b55

File tree

4 files changed

+91
-1
lines changed

4 files changed

+91
-1
lines changed

uefi-test-runner/src/runtime/mod.rs

+31-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,38 @@
1+
mod vars;
2+
3+
use uefi::runtime::{self, Daylight, Time, TimeParams};
14
use uefi::table::runtime::RuntimeServices;
25

36
pub fn test(rt: &RuntimeServices) {
47
info!("Testing runtime services");
58
vars::test(rt);
9+
test_time();
610
}
711

8-
mod vars;
12+
fn test_time() {
13+
// Print the current time and time capabilities.
14+
info!(
15+
"Time with caps: {:?}",
16+
runtime::get_time_and_caps().unwrap()
17+
);
18+
19+
// Set the time.
20+
let time = Time::new(TimeParams {
21+
year: 2020,
22+
month: 1,
23+
day: 2,
24+
hour: 3,
25+
minute: 4,
26+
second: 5,
27+
nanosecond: 6,
28+
time_zone: None,
29+
daylight: Daylight::ADJUST_DAYLIGHT,
30+
})
31+
.unwrap();
32+
unsafe { runtime::set_time(&time).unwrap() };
33+
34+
// Print the new time and check that the year was successfully changed.
35+
let now = runtime::get_time().unwrap();
36+
info!("After setting time: {}", now);
37+
assert_eq!(now.year(), 2020);
38+
}

uefi/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
## Added
44
- `uefi::system` is a new module that provides freestanding functions for
55
accessing fields of the global system table.
6+
- `uefi::runtime` is a new module that provides freestanding functions for
7+
runtime services using the global system table.
68
- Add standard derives for `ConfigTableEntry`.
79
- `PcrEvent`/`PcrEventInputs` impl `Align`, `Eq`, and `PartialEq`.
810
- Added `PcrEvent::new_in_box` and `PcrEventInputs::new_in_box`.

uefi/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ pub use uguid::guid;
119119
mod result;
120120
pub use result::{Error, Result, ResultExt, Status, StatusExt};
121121

122+
pub mod runtime;
122123
pub mod system;
123124
pub mod table;
124125

uefi/src/runtime.rs

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//! UEFI runtime services.
2+
//!
3+
//! These services are available both before and after exiting boot
4+
//! services. Note that various restrictions apply when calling runtime services
5+
//! functions after exiting boot services; see the "Calling Convention" section
6+
//! of the UEFI specification for details.
7+
8+
use crate::table::{self};
9+
use crate::{Result, StatusExt};
10+
use core::ptr::{self, NonNull};
11+
12+
pub use crate::table::runtime::{Daylight, Time, TimeCapabilities, TimeError, TimeParams};
13+
14+
fn runtime_services_raw_panicking() -> NonNull<uefi_raw::table::runtime::RuntimeServices> {
15+
let st = table::system_table_raw_panicking();
16+
// SAFETY: valid per requirements of `set_system_table`.
17+
let st = unsafe { st.as_ref() };
18+
NonNull::new(st.runtime_services).expect("runtime services are not active")
19+
}
20+
21+
/// Query the current time and date information.
22+
pub fn get_time() -> Result<Time> {
23+
let rt = runtime_services_raw_panicking();
24+
let rt = unsafe { rt.as_ref() };
25+
26+
let mut time = Time::invalid();
27+
let time_ptr: *mut Time = &mut time;
28+
unsafe { (rt.get_time)(time_ptr.cast(), ptr::null_mut()) }.to_result_with_val(|| time)
29+
}
30+
31+
/// Query the current time and date information and the RTC capabilities.
32+
pub fn get_time_and_caps() -> Result<(Time, TimeCapabilities)> {
33+
let rt = runtime_services_raw_panicking();
34+
let rt = unsafe { rt.as_ref() };
35+
36+
let mut time = Time::invalid();
37+
let time_ptr: *mut Time = &mut time;
38+
let mut caps = TimeCapabilities::default();
39+
unsafe { (rt.get_time)(time_ptr.cast(), &mut caps) }.to_result_with_val(|| (time, caps))
40+
}
41+
42+
/// Sets the current local time and date information
43+
///
44+
/// During runtime, if a PC-AT CMOS device is present in the platform, the
45+
/// caller must synchronize access to the device before calling `set_time`.
46+
///
47+
/// # Safety
48+
///
49+
/// Undefined behavior could happen if multiple tasks try to
50+
/// use this function at the same time without synchronisation.
51+
pub unsafe fn set_time(time: &Time) -> Result {
52+
let rt = runtime_services_raw_panicking();
53+
let rt = unsafe { rt.as_ref() };
54+
55+
let time: *const Time = time;
56+
(rt.set_time)(time.cast()).to_result()
57+
}

0 commit comments

Comments
 (0)