@@ -11,6 +11,71 @@ pub use header::Header;
11
11
pub use system:: { Boot , Runtime , SystemTable } ;
12
12
pub use uefi_raw:: table:: Revision ;
13
13
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
+
14
79
/// Common trait implemented by all standard UEFI tables.
15
80
pub trait Table {
16
81
/// A unique number assigned by the UEFI specification
0 commit comments