Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions uefi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
works on x86. It is activated by default (only on x86) and can be deactivated
by removing the `log-debugcon` cargo feature. The major benefit is that one
can get log messages even after one exited the boot services.
- Added `table::{set_system_table, system_table_boot, system_table_runtime}`.
This provides an initial API for global tables that do not require passing
around a reference.

## Removed
- Removed the `panic-on-logger-errors` feature of the `uefi` crate. Logger
Expand Down
87 changes: 75 additions & 12 deletions uefi/src/table/mod.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,84 @@
//! Standard UEFI tables.

/// Common trait implemented by all standard UEFI tables.
pub trait Table {
/// A unique number assigned by the UEFI specification
/// to the standard tables.
const SIGNATURE: u64;
}
pub mod boot;
pub mod cfg;
pub mod runtime;

mod header;
pub use header::Header;

mod system;

pub use header::Header;
pub use system::{Boot, Runtime, SystemTable};
pub use uefi_raw::table::Revision;

pub mod boot;
pub mod runtime;
use core::ptr;
use core::sync::atomic::{AtomicPtr, Ordering};

pub mod cfg;
/// Global system table pointer. This is only modified by [`set_system_table`].
static SYSTEM_TABLE: AtomicPtr<uefi_raw::table::system::SystemTable> =
AtomicPtr::new(ptr::null_mut());

pub use uefi_raw::table::Revision;
/// Update the global system table pointer.
///
/// This is called automatically in the `main` entry point as part of
/// [`uefi::entry`]. It should not be called at any other point in time, unless
/// the executable does not use [`uefi::entry`], in which case it should be
/// called once before calling any other API in this crate.
///
/// # Safety
///
/// This function should only be called as described above, and the
/// `ptr` must be a valid [`SystemTable`].
pub unsafe fn set_system_table(ptr: *const uefi_raw::table::system::SystemTable) {
SYSTEM_TABLE.store(ptr.cast_mut(), Ordering::Release);
}

/// Get the system table while boot services are active.
///
/// # Panics
///
/// Panics if the system table has not been set with `set_system_table`, or if
/// boot services are not available (e.g. if [`exit_boot_services`] has been
/// called).
///
/// [`exit_boot_services`]: SystemTable::exit_boot_services
pub fn system_table_boot() -> SystemTable<Boot> {
let st = SYSTEM_TABLE.load(Ordering::Acquire);
assert!(!st.is_null());

// SAFETY: the system table is valid per the requirements of `set_system_table`.
unsafe {
if (*st).boot_services.is_null() {
panic!("boot services are not active");
}

SystemTable::<Boot>::from_ptr(st.cast()).unwrap()
}
}

/// Get the system table while runtime services are active.
///
/// # Panics
///
/// Panics if the system table has not been set with `set_system_table`, or if
/// runtime services are not available.
pub fn system_table_runtime() -> SystemTable<Runtime> {
let st = SYSTEM_TABLE.load(Ordering::Acquire);
assert!(!st.is_null());

// SAFETY: the system table is valid per the requirements of `set_system_table`.
unsafe {
if (*st).runtime_services.is_null() {
panic!("runtime services are not active");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strictly speaking, they are also active, but not exclusively, right?

}

SystemTable::<Runtime>::from_ptr(st.cast()).unwrap()
}
}

/// Common trait implemented by all standard UEFI tables.
pub trait Table {
/// A unique number assigned by the UEFI specification
/// to the standard tables.
const SIGNATURE: u64;
}