Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
uefi: Drop duplicate global system table pointer
Now that `uefi::table` has a pointer to the system table, drop the pointer from `uefi::helpers`.
  • Loading branch information
nicholasbishop committed Jun 11, 2024
commit 2a63b9e95689563cd302ae0e1cfd05135ad89ae2
44 changes: 3 additions & 41 deletions uefi/src/helpers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,9 @@
//! [println_macro]: uefi::println!

use crate::prelude::{Boot, SystemTable};
use crate::{Result, StatusExt};
use core::ffi::c_void;
use core::ptr;
use core::sync::atomic::{AtomicPtr, Ordering};
use crate::{table, Result};
#[doc(hidden)]
pub use println::_print;
use uefi_raw::Status;

#[cfg(feature = "global_allocator")]
mod global_allocator;
Expand All @@ -35,25 +31,6 @@ mod logger;
mod panic_handler;
mod println;

/// Reference to the system table.
///
/// This table is only fully safe to use until UEFI boot services have been exited.
/// After that, some fields and methods are unsafe to use, see the documentation of
/// UEFI's ExitBootServices entry point for more details.
static SYSTEM_TABLE: AtomicPtr<c_void> = AtomicPtr::new(core::ptr::null_mut());

#[must_use]
fn system_table_opt() -> Option<SystemTable<Boot>> {
let ptr = SYSTEM_TABLE.load(Ordering::Acquire);
// Safety: the `SYSTEM_TABLE` pointer either be null or a valid system
// table.
//
// Null is the initial value, as well as the value set when exiting boot
// services. Otherwise, the value is set by the call to `init`, which
// requires a valid system table reference as input.
unsafe { SystemTable::from_ptr(ptr) }
}

/// Obtains a pointer to the system table.
///
/// This is meant to be used by higher-level libraries,
Expand All @@ -65,7 +42,7 @@ fn system_table_opt() -> Option<SystemTable<Boot>> {
#[must_use]
// TODO do we want to keep this public?
pub fn system_table() -> SystemTable<Boot> {
system_table_opt().expect("The system table handle is not available")
table::system_table_boot().expect("boot services are not active")
}

/// Initialize all helpers defined in [`uefi::helpers`] whose Cargo features
Expand All @@ -77,15 +54,8 @@ pub fn system_table() -> SystemTable<Boot> {
/// **PLEASE NOTE** that these helpers are meant for the pre exit boot service
/// epoch. Limited functionality might work after exiting them, such as logging
/// to the debugcon device.
#[allow(unused_variables)] // `st` is unused if logger and allocator are disabled
pub fn init(st: &mut SystemTable<Boot>) -> Result<()> {
if system_table_opt().is_some() {
// Avoid double initialization.
return Status::SUCCESS.to_result_with_val(|| ());
}

// Setup the system table singleton
SYSTEM_TABLE.store(st.as_ptr().cast_mut(), Ordering::Release);

// Setup logging and memory allocation

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

pub(crate) fn exit() {
// DEBUG: The UEFI spec does not guarantee that this printout will work, as
// the services used by logging might already have been shut down.
// But it works on current OVMF, and can be used as a handy way to
// check that the callback does get called.
//
// info!("Shutting down the UEFI utility library");
SYSTEM_TABLE.store(ptr::null_mut(), Ordering::Release);

#[cfg(feature = "logger")]
logger::disable();

Expand Down
6 changes: 3 additions & 3 deletions uefi/src/helpers/panic_handler.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::helpers::system_table_opt;
use crate::println;
use crate::table::system_table_boot;
use cfg_if::cfg_if;

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

// Give the user some time to read the message
if let Some(st) = system_table_opt() {
if let Some(st) = system_table_boot() {
st.boot_services().stall(10_000_000);
} else {
let mut dummy = 0u64;
Expand All @@ -28,7 +28,7 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! {
qemu_exit_handle.exit_failure();
} else {
// If the system table is available, use UEFI's standard shutdown mechanism
if let Some(st) = system_table_opt() {
if let Some(st) = system_table_boot() {
use crate::table::runtime::ResetType;
st.runtime_services()
.reset(ResetType::SHUTDOWN, crate::Status::ABORTED, None);
Expand Down
5 changes: 3 additions & 2 deletions uefi/src/helpers/println.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::helpers::system_table;
use crate::table::system_table_boot;
use core::fmt::Write;

/// INTERNAL API! Helper for print macros.
#[doc(hidden)]
pub fn _print(args: core::fmt::Arguments) {
system_table()
system_table_boot()
.expect("boot services are not active")
.stdout()
.write_fmt(args)
.expect("Failed to write to stdout");
Expand Down