@@ -11,6 +11,68 @@ 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 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
+
14
76
/// Common trait implemented by all standard UEFI tables.
15
77
pub trait Table {
16
78
/// A unique number assigned by the UEFI specification
0 commit comments