forked from rust-osdev/uefi-rs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The initial version here just provides functions for getting and setting the system time. Later commits will add functions to get/set variables, handle update capsules, etc. Also added some tests for the new code in the test runner (note that there were no existing tests for the time-related functions of `RuntimeServices`).
- Loading branch information
1 parent
1fa9408
commit 233a33a
Showing
4 changed files
with
91 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,38 @@ | ||
mod vars; | ||
|
||
use uefi::runtime::{self, Daylight, Time, TimeParams}; | ||
use uefi::table::runtime::RuntimeServices; | ||
|
||
pub fn test(rt: &RuntimeServices) { | ||
info!("Testing runtime services"); | ||
vars::test(rt); | ||
test_time(); | ||
} | ||
|
||
mod vars; | ||
fn test_time() { | ||
// Print the current time and time capabilities. | ||
info!( | ||
"Time with caps: {:?}", | ||
runtime::get_time_and_caps().unwrap() | ||
); | ||
|
||
// Set the time. | ||
let time = Time::new(TimeParams { | ||
year: 2020, | ||
month: 1, | ||
day: 2, | ||
hour: 3, | ||
minute: 4, | ||
second: 5, | ||
nanosecond: 6, | ||
time_zone: None, | ||
daylight: Daylight::ADJUST_DAYLIGHT, | ||
}) | ||
.unwrap(); | ||
unsafe { runtime::set_time(&time).unwrap() }; | ||
|
||
// Print the new time and check that the year was successfully changed. | ||
let now = runtime::get_time().unwrap(); | ||
info!("After setting time: {}", now); | ||
assert_eq!(now.year(), 2020); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
//! UEFI runtime services. | ||
//! | ||
//! These services are available both before and after exiting boot | ||
//! services. Note that various restrictions apply when calling runtime services | ||
//! functions after exiting boot services; see the "Calling Convention" section | ||
//! of the UEFI specification for details. | ||
|
||
use crate::table::{self}; | ||
use crate::{Result, StatusExt}; | ||
use core::ptr::{self, NonNull}; | ||
|
||
pub use crate::table::runtime::{Daylight, Time, TimeCapabilities, TimeError, TimeParams}; | ||
|
||
fn runtime_services_raw_panicking() -> NonNull<uefi_raw::table::runtime::RuntimeServices> { | ||
let st = table::system_table_raw_panicking(); | ||
// SAFETY: valid per requirements of `set_system_table`. | ||
let st = unsafe { st.as_ref() }; | ||
NonNull::new(st.runtime_services).expect("runtime services are not active") | ||
} | ||
|
||
/// Query the current time and date information. | ||
pub fn get_time() -> Result<Time> { | ||
let rt = runtime_services_raw_panicking(); | ||
let rt = unsafe { rt.as_ref() }; | ||
|
||
let mut time = Time::invalid(); | ||
let time_ptr: *mut Time = &mut time; | ||
unsafe { (rt.get_time)(time_ptr.cast(), ptr::null_mut()) }.to_result_with_val(|| time) | ||
} | ||
|
||
/// Query the current time and date information and the RTC capabilities. | ||
pub fn get_time_and_caps() -> Result<(Time, TimeCapabilities)> { | ||
let rt = runtime_services_raw_panicking(); | ||
let rt = unsafe { rt.as_ref() }; | ||
|
||
let mut time = Time::invalid(); | ||
let time_ptr: *mut Time = &mut time; | ||
let mut caps = TimeCapabilities::default(); | ||
unsafe { (rt.get_time)(time_ptr.cast(), &mut caps) }.to_result_with_val(|| (time, caps)) | ||
} | ||
|
||
/// Sets the current local time and date information | ||
/// | ||
/// During runtime, if a PC-AT CMOS device is present in the platform, the | ||
/// caller must synchronize access to the device before calling `set_time`. | ||
/// | ||
/// # Safety | ||
/// | ||
/// Undefined behavior could happen if multiple tasks try to | ||
/// use this function at the same time without synchronisation. | ||
pub unsafe fn set_time(time: &Time) -> Result { | ||
let rt = runtime_services_raw_panicking(); | ||
let rt = unsafe { rt.as_ref() }; | ||
|
||
let time: *const Time = time; | ||
(rt.set_time)(time.cast()).to_result() | ||
} |