@@ -11,6 +11,68 @@ 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 image [`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 active.
42+ pub fn system_table_boot ( ) -> SystemTable < Boot > {
43+ let st = SYSTEM_TABLE . load ( Ordering :: Acquire ) ;
44+ assert ! ( !st. is_null( ) ) ;
45+
46+ // SAFETY: the system table is valid per the requirements of `set_system_table`.
47+ unsafe {
48+ if ( * st) . boot_services . is_null ( ) {
49+ panic ! ( "boot services are not active" ) ;
50+ }
51+
52+ SystemTable :: < Boot > :: from_ptr ( st. cast ( ) ) . unwrap ( )
53+ }
54+ }
55+
56+ /// Get the system table while runtime services are active.
57+ ///
58+ /// # Panics
59+ ///
60+ /// Panics if the system table has not been set with `set_system_table`, or if
61+ /// runtime services are not active.
62+ pub fn system_table_runtime ( ) -> SystemTable < Runtime > {
63+ let st = SYSTEM_TABLE . load ( Ordering :: Acquire ) ;
64+ assert ! ( !st. is_null( ) ) ;
65+
66+ // SAFETY: the system table is valid per the requirements of `set_system_table`.
67+ unsafe {
68+ if ( * st) . runtime_services . is_null ( ) {
69+ panic ! ( "boot services are not active" ) ;
70+ }
71+
72+ SystemTable :: < Runtime > :: from_ptr ( st. cast ( ) ) . unwrap ( )
73+ }
74+ }
75+
1476/// Common trait implemented by all standard UEFI tables.
1577pub trait Table {
1678 /// A unique number assigned by the UEFI specification
0 commit comments