@@ -55,6 +55,32 @@ pub fn exit_boot_services() {
55
55
SYSTEM_TABLE . store ( ptr:: null_mut ( ) , Ordering :: Release ) ;
56
56
}
57
57
58
+ /// Get the memory type to use for allocation.
59
+ ///
60
+ /// The first time this is called, the data type of the loaded image will be
61
+ /// retrieved. That value is cached in a static and reused on subsequent
62
+ /// calls. If the memory type of the loaded image cannot be retrieved for some
63
+ /// reason, a default of `LOADER_DATA` is used.
64
+ fn get_memory_type ( ) -> MemoryType {
65
+ // Initialize to a `RESERVED` to indicate the actual value hasn't been set yet.
66
+ static MEMORY_TYPE : AtomicU32 = AtomicU32 :: new ( MemoryType :: RESERVED . 0 ) ;
67
+
68
+ let memory_type = MEMORY_TYPE . load ( Ordering :: Acquire ) ;
69
+ if memory_type == MemoryType :: RESERVED . 0 {
70
+ let memory_type = if let Ok ( loaded_image) =
71
+ boot:: open_protocol_exclusive :: < LoadedImage > ( boot:: image_handle ( ) )
72
+ {
73
+ loaded_image. data_type ( )
74
+ } else {
75
+ MemoryType :: LOADER_DATA
76
+ } ;
77
+ MEMORY_TYPE . store ( memory_type. 0 , Ordering :: Release ) ;
78
+ memory_type
79
+ } else {
80
+ MemoryType ( memory_type)
81
+ }
82
+ }
83
+
58
84
/// Allocator which uses the UEFI pool allocation functions.
59
85
///
60
86
/// Only valid for as long as the UEFI boot services are available.
@@ -72,7 +98,7 @@ unsafe impl GlobalAlloc for Allocator {
72
98
73
99
let size = layout. size ( ) ;
74
100
let align = layout. align ( ) ;
75
- let memory_type = MemoryType ( MEMORY_TYPE . load ( Ordering :: Acquire ) ) ;
101
+ let memory_type = get_memory_type ( ) ;
76
102
77
103
if align > 8 {
78
104
// The requested alignment is greater than 8, but `allocate_pool` is
0 commit comments