14
14
use core:: alloc:: { GlobalAlloc , Layout } ;
15
15
use core:: ptr:: { self , NonNull } ;
16
16
17
+ use crate :: proto:: loaded_image:: LoadedImage ;
17
18
use crate :: table:: boot:: { BootServices , MemoryType } ;
18
19
19
20
/// Reference to the boot services table, used to call the pool memory allocation functions.
@@ -22,6 +23,10 @@ use crate::table::boot::{BootServices, MemoryType};
22
23
/// exited by the host application yet.
23
24
static mut BOOT_SERVICES : Option < NonNull < BootServices > > = None ;
24
25
26
+ /// The memory type used for pool memory allocations.
27
+ /// TODO: Use OnceCell when stablilized.
28
+ static mut MEMORY_TYPE : MemoryType = MemoryType :: LOADER_DATA ;
29
+
25
30
/// Initializes the allocator.
26
31
///
27
32
/// # Safety
@@ -30,6 +35,12 @@ static mut BOOT_SERVICES: Option<NonNull<BootServices>> = None;
30
35
/// will be called when UEFI boot services will be exited.
31
36
pub unsafe fn init ( boot_services : & BootServices ) {
32
37
BOOT_SERVICES = NonNull :: new ( boot_services as * const _ as * mut _ ) ;
38
+
39
+ if let Ok ( loaded_image) =
40
+ boot_services. open_protocol_exclusive :: < LoadedImage > ( boot_services. image_handle ( ) )
41
+ {
42
+ MEMORY_TYPE = loaded_image. data_type ( )
43
+ }
33
44
}
34
45
35
46
/// Access the boot services
@@ -54,9 +65,9 @@ pub struct Allocator;
54
65
55
66
unsafe impl GlobalAlloc for Allocator {
56
67
/// Allocate memory using [`BootServices::allocate_pool`]. The allocation is
57
- /// of type [`MemoryType::LOADER_DATA`].
68
+ /// of type [`MemoryType::LOADER_DATA`] for UEFI applications, [`MemoryType::BOOT_SERVICES_DATA`]
69
+ /// for UEFI boot drivers and [`MemoryType::RUNTIME_SERVICES_DATA`] for UEFI runtime drivers.
58
70
unsafe fn alloc ( & self , layout : Layout ) -> * mut u8 {
59
- let mem_ty = MemoryType :: LOADER_DATA ;
60
71
let size = layout. size ( ) ;
61
72
let align = layout. align ( ) ;
62
73
@@ -65,12 +76,14 @@ unsafe impl GlobalAlloc for Allocator {
65
76
// only guaranteed to provide eight-byte alignment. Allocate extra
66
77
// space so that we can return an appropriately-aligned pointer
67
78
// within the allocation.
68
- let full_alloc_ptr =
69
- if let Ok ( ptr) = boot_services ( ) . as_ref ( ) . allocate_pool ( mem_ty, size + align) {
70
- ptr
71
- } else {
72
- return ptr:: null_mut ( ) ;
73
- } ;
79
+ let full_alloc_ptr = if let Ok ( ptr) = boot_services ( )
80
+ . as_ref ( )
81
+ . allocate_pool ( MEMORY_TYPE , size + align)
82
+ {
83
+ ptr
84
+ } else {
85
+ return ptr:: null_mut ( ) ;
86
+ } ;
74
87
75
88
// Calculate the offset needed to get an aligned pointer within the
76
89
// full allocation. If that offset is zero, increase it to `align`
@@ -97,7 +110,7 @@ unsafe impl GlobalAlloc for Allocator {
97
110
// use `allocate_pool` directly.
98
111
boot_services ( )
99
112
. as_ref ( )
100
- . allocate_pool ( mem_ty , size)
113
+ . allocate_pool ( MEMORY_TYPE , size)
101
114
. unwrap_or ( ptr:: null_mut ( ) )
102
115
}
103
116
}
0 commit comments