@@ -11,6 +11,71 @@ pub use header::Header;
1111pub use system:: { Boot , Runtime , SystemTable } ;
1212pub use uefi_raw:: table:: Revision ;
1313
14+ use core:: ptr;
15+ use core:: sync:: atomic:: { AtomicPtr , Ordering } ;
16+
17+ /// Global system table pointer. This is only modified by [`set_system_table`].
18+ static SYSTEM_TABLE : AtomicPtr < uefi_raw:: table:: system:: SystemTable > =
19+ AtomicPtr :: new ( ptr:: null_mut ( ) ) ;
20+
21+ /// Update the global system table pointer.
22+ ///
23+ /// This is called automatically in the `main` entry point as part of
24+ /// [`uefi::entry`]. It should not be called at any other point in time, unless
25+ /// the executable does not use [`uefi::entry`], in which case it should be
26+ /// called once before calling any other API in this crate.
27+ ///
28+ /// # Safety
29+ ///
30+ /// This function should only be called as described above, and the
31+ /// `ptr` must be a valid [`SystemTable`].
32+ pub unsafe fn set_system_table ( ptr : * const uefi_raw:: table:: system:: SystemTable ) {
33+ SYSTEM_TABLE . store ( ptr. cast_mut ( ) , Ordering :: Release ) ;
34+ }
35+
36+ /// 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 > {
46+ let st = SYSTEM_TABLE . load ( Ordering :: Acquire ) ;
47+ assert ! ( !st. is_null( ) ) ;
48+
49+ // SAFETY: the system table is valid per the requirements of `set_system_table`.
50+ unsafe {
51+ if ( * st) . boot_services . is_null ( ) {
52+ panic ! ( "boot services are not active" ) ;
53+ }
54+
55+ SystemTable :: < Boot > :: from_ptr ( st. cast ( ) ) . unwrap ( )
56+ }
57+ }
58+
59+ /// 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 > {
66+ let st = SYSTEM_TABLE . load ( Ordering :: Acquire ) ;
67+ assert ! ( !st. is_null( ) ) ;
68+
69+ // SAFETY: the system table is valid per the requirements of `set_system_table`.
70+ unsafe {
71+ if ( * st) . runtime_services . is_null ( ) {
72+ panic ! ( "runtime services are not active" ) ;
73+ }
74+
75+ SystemTable :: < Runtime > :: from_ptr ( st. cast ( ) ) . unwrap ( )
76+ }
77+ }
78+
1479/// Common trait implemented by all standard UEFI tables.
1580pub trait Table {
1681 /// A unique number assigned by the UEFI specification
0 commit comments