Skip to content

Commit ed28e51

Browse files
authored
Merge pull request #1188 from rust-osdev/bishop-clean-up-globals
Clean up duplicate global system table pointer in `uefi::helpers`
2 parents 9d01724 + 1970c81 commit ed28e51

File tree

5 files changed

+25
-70
lines changed

5 files changed

+25
-70
lines changed

uefi/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
documentation for details of obligations for callers.
2020
- `BootServices::allocate_pool` now returns `NonZero<u8>` instead of
2121
`*mut u8`.
22+
- `helpers::system_table` is deprecated, use `table::system_table_boot` instead.
2223

2324
## Removed
2425
- Removed the `panic-on-logger-errors` feature of the `uefi` crate. Logger

uefi/src/helpers/mod.rs

+4-42
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,9 @@
1919
//! [println_macro]: uefi::println!
2020
2121
use crate::prelude::{Boot, SystemTable};
22-
use crate::{Result, StatusExt};
23-
use core::ffi::c_void;
24-
use core::ptr;
25-
use core::sync::atomic::{AtomicPtr, Ordering};
22+
use crate::{table, Result};
2623
#[doc(hidden)]
2724
pub use println::_print;
28-
use uefi_raw::Status;
2925

3026
#[cfg(feature = "global_allocator")]
3127
mod global_allocator;
@@ -35,25 +31,6 @@ mod logger;
3531
mod panic_handler;
3632
mod println;
3733

38-
/// Reference to the system table.
39-
///
40-
/// This table is only fully safe to use until UEFI boot services have been exited.
41-
/// After that, some fields and methods are unsafe to use, see the documentation of
42-
/// UEFI's ExitBootServices entry point for more details.
43-
static SYSTEM_TABLE: AtomicPtr<c_void> = AtomicPtr::new(core::ptr::null_mut());
44-
45-
#[must_use]
46-
fn system_table_opt() -> Option<SystemTable<Boot>> {
47-
let ptr = SYSTEM_TABLE.load(Ordering::Acquire);
48-
// Safety: the `SYSTEM_TABLE` pointer either be null or a valid system
49-
// table.
50-
//
51-
// Null is the initial value, as well as the value set when exiting boot
52-
// services. Otherwise, the value is set by the call to `init`, which
53-
// requires a valid system table reference as input.
54-
unsafe { SystemTable::from_ptr(ptr) }
55-
}
56-
5734
/// Obtains a pointer to the system table.
5835
///
5936
/// This is meant to be used by higher-level libraries,
@@ -63,9 +40,9 @@ fn system_table_opt() -> Option<SystemTable<Boot>> {
6340
///
6441
/// The returned pointer is only valid until boot services are exited.
6542
#[must_use]
66-
// TODO do we want to keep this public?
43+
#[deprecated(note = "use uefi::table::system_table_boot instead")]
6744
pub fn system_table() -> SystemTable<Boot> {
68-
system_table_opt().expect("The system table handle is not available")
45+
table::system_table_boot().expect("boot services are not active")
6946
}
7047

7148
/// Initialize all helpers defined in [`uefi::helpers`] whose Cargo features
@@ -77,15 +54,8 @@ pub fn system_table() -> SystemTable<Boot> {
7754
/// **PLEASE NOTE** that these helpers are meant for the pre exit boot service
7855
/// epoch. Limited functionality might work after exiting them, such as logging
7956
/// to the debugcon device.
57+
#[allow(unused_variables)] // `st` is unused if logger and allocator are disabled
8058
pub fn init(st: &mut SystemTable<Boot>) -> Result<()> {
81-
if system_table_opt().is_some() {
82-
// Avoid double initialization.
83-
return Status::SUCCESS.to_result_with_val(|| ());
84-
}
85-
86-
// Setup the system table singleton
87-
SYSTEM_TABLE.store(st.as_ptr().cast_mut(), Ordering::Release);
88-
8959
// Setup logging and memory allocation
9060

9161
#[cfg(feature = "logger")]
@@ -102,14 +72,6 @@ pub fn init(st: &mut SystemTable<Boot>) -> Result<()> {
10272
}
10373

10474
pub(crate) fn exit() {
105-
// DEBUG: The UEFI spec does not guarantee that this printout will work, as
106-
// the services used by logging might already have been shut down.
107-
// But it works on current OVMF, and can be used as a handy way to
108-
// check that the callback does get called.
109-
//
110-
// info!("Shutting down the UEFI utility library");
111-
SYSTEM_TABLE.store(ptr::null_mut(), Ordering::Release);
112-
11375
#[cfg(feature = "logger")]
11476
logger::disable();
11577

uefi/src/helpers/panic_handler.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
use crate::helpers::system_table_opt;
21
use crate::println;
2+
use crate::table::system_table_boot;
33
use cfg_if::cfg_if;
44

55
#[panic_handler]
66
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
77
println!("[PANIC]: {}", info);
88

99
// Give the user some time to read the message
10-
if let Some(st) = system_table_opt() {
10+
if let Some(st) = system_table_boot() {
1111
st.boot_services().stall(10_000_000);
1212
} else {
1313
let mut dummy = 0u64;
@@ -28,7 +28,7 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! {
2828
qemu_exit_handle.exit_failure();
2929
} else {
3030
// If the system table is available, use UEFI's standard shutdown mechanism
31-
if let Some(st) = system_table_opt() {
31+
if let Some(st) = system_table_boot() {
3232
use crate::table::runtime::ResetType;
3333
st.runtime_services()
3434
.reset(ResetType::SHUTDOWN, crate::Status::ABORTED, None);

uefi/src/helpers/println.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
use crate::helpers::system_table;
1+
use crate::table::system_table_boot;
22
use core::fmt::Write;
33

44
/// INTERNAL API! Helper for print macros.
55
#[doc(hidden)]
66
pub fn _print(args: core::fmt::Arguments) {
7-
system_table()
7+
system_table_boot()
8+
.expect("boot services are not active")
89
.stdout()
910
.write_fmt(args)
1011
.expect("Failed to write to stdout");

uefi/src/table/mod.rs

+14-23
Original file line numberDiff line numberDiff line change
@@ -34,45 +34,36 @@ pub unsafe fn set_system_table(ptr: *const uefi_raw::table::system::SystemTable)
3434
}
3535

3636
/// Get the system table while boot services are active.
37-
///
38-
/// # Panics
39-
///
40-
/// Panics if the system table has not been set with `set_system_table`, or if
41-
/// boot services are not available (e.g. if [`exit_boot_services`] has been
42-
/// called).
43-
///
44-
/// [`exit_boot_services`]: SystemTable::exit_boot_services
45-
pub fn system_table_boot() -> SystemTable<Boot> {
37+
pub fn system_table_boot() -> Option<SystemTable<Boot>> {
4638
let st = SYSTEM_TABLE.load(Ordering::Acquire);
47-
assert!(!st.is_null());
39+
if st.is_null() {
40+
return None;
41+
}
4842

4943
// SAFETY: the system table is valid per the requirements of `set_system_table`.
5044
unsafe {
5145
if (*st).boot_services.is_null() {
52-
panic!("boot services are not active");
46+
None
47+
} else {
48+
Some(SystemTable::<Boot>::from_ptr(st.cast()).unwrap())
5349
}
54-
55-
SystemTable::<Boot>::from_ptr(st.cast()).unwrap()
5650
}
5751
}
5852

5953
/// Get the system table while runtime services are active.
60-
///
61-
/// # Panics
62-
///
63-
/// Panics if the system table has not been set with `set_system_table`, or if
64-
/// runtime services are not available.
65-
pub fn system_table_runtime() -> SystemTable<Runtime> {
54+
pub fn system_table_runtime() -> Option<SystemTable<Runtime>> {
6655
let st = SYSTEM_TABLE.load(Ordering::Acquire);
67-
assert!(!st.is_null());
56+
if st.is_null() {
57+
return None;
58+
}
6859

6960
// SAFETY: the system table is valid per the requirements of `set_system_table`.
7061
unsafe {
7162
if (*st).runtime_services.is_null() {
72-
panic!("runtime services are not active");
63+
None
64+
} else {
65+
Some(SystemTable::<Runtime>::from_ptr(st.cast()).unwrap())
7366
}
74-
75-
SystemTable::<Runtime>::from_ptr(st.cast()).unwrap()
7667
}
7768
}
7869

0 commit comments

Comments
 (0)