|
| 1 | +//! UEFI-specific extensions to the primitives in `std::env` module |
| 2 | +
|
| 3 | +use crate::ffi::c_void; |
| 4 | +use crate::ptr::NonNull; |
| 5 | +use crate::sync::atomic::{AtomicPtr, Ordering}; |
| 6 | +use crate::sync::OnceLock; |
| 7 | + |
| 8 | +// Position 0 = SystemTable |
| 9 | +// Position 1 = ImageHandle |
| 10 | +static GLOBALS: OnceLock<(AtomicPtr<c_void>, AtomicPtr<c_void>)> = OnceLock::new(); |
| 11 | + |
| 12 | +/// Initializes the global System Table and Image Handle pointers. |
| 13 | +/// |
| 14 | +/// The standard library requires access to the UEFI System Table and the Application Image Handle |
| 15 | +/// to operate. Those are provided to UEFI Applications via their application entry point. By |
| 16 | +/// calling `init_globals()`, those pointers are retained by the standard library for future use. |
| 17 | +/// The pointers are never exposed to any entity outside of this application and it is guaranteed |
| 18 | +/// that, once the application exited, these pointers are never dereferenced again. |
| 19 | +/// |
| 20 | +/// Callers are required to ensure the pointers are valid for the entire lifetime of this |
| 21 | +/// application. In particular, UEFI Boot Services must not be exited while an application with the |
| 22 | +/// standard library is loaded. |
| 23 | +/// |
| 24 | +/// This function must not be called more than once. |
| 25 | +#[unstable(feature = "uefi_std", issue = "100499")] |
| 26 | +pub unsafe fn init_globals(handle: NonNull<c_void>, system_table: NonNull<c_void>) { |
| 27 | + GLOBALS.set((AtomicPtr::new(system_table.as_ptr()), AtomicPtr::new(handle.as_ptr()))).unwrap() |
| 28 | +} |
| 29 | + |
| 30 | +/// Get the SystemTable Pointer. |
| 31 | +/// Note: This function panics if the System Table and Image Handle is Not initialized |
| 32 | +#[unstable(feature = "uefi_std", issue = "100499")] |
| 33 | +pub fn system_table() -> NonNull<c_void> { |
| 34 | + try_system_table().unwrap() |
| 35 | +} |
| 36 | + |
| 37 | +/// Get the SystemHandle Pointer. |
| 38 | +/// Note: This function panics if the System Table and Image Handle is Not initialized |
| 39 | +#[unstable(feature = "uefi_std", issue = "100499")] |
| 40 | +pub fn image_handle() -> NonNull<c_void> { |
| 41 | + try_image_handle().unwrap() |
| 42 | +} |
| 43 | + |
| 44 | +/// Get the SystemTable Pointer. |
| 45 | +/// This function is mostly intended for places where panic is not an option |
| 46 | +pub(crate) fn try_system_table() -> Option<NonNull<crate::ffi::c_void>> { |
| 47 | + NonNull::new(GLOBALS.get()?.0.load(Ordering::Acquire)) |
| 48 | +} |
| 49 | + |
| 50 | +/// Get the SystemHandle Pointer. |
| 51 | +/// This function is mostly intended for places where panic is not an option |
| 52 | +pub(crate) fn try_image_handle() -> Option<NonNull<crate::ffi::c_void>> { |
| 53 | + NonNull::new(GLOBALS.get()?.1.load(Ordering::Acquire)) |
| 54 | +} |
0 commit comments