@@ -120,42 +120,70 @@ pub unsafe fn raise_tpl(tpl: Tpl) -> TplGuard {
120120 }
121121}
122122
123- /// Allocates memory pages from the system.
123+ /// Allocates a consecutive set of memory pages using the UEFI allocator.
124+ ///
125+ /// The caller is responsible to free the memory using [`free_pages`].
124126///
125127/// UEFI OS loaders should allocate memory of the type `LoaderData`.
126128///
129+ /// # Example
130+ ///```rust,no_run
131+ /// use uefi::boot::{self, AllocateType};
132+ /// use uefi_raw::table::boot::MemoryType;
133+ ///
134+ /// let num_pages = 3;
135+ /// let mut ptr = boot::allocate_pages(
136+ /// AllocateType::AnyPages,
137+ /// MemoryType::LOADER_DATA,
138+ /// num_pages
139+ /// ).unwrap();
140+ ///
141+ /// let buffer: &mut [u8] = unsafe { ptr.as_mut() };
142+ /// // now do something with your buffer
143+ ///
144+ /// // free the allocation
145+ /// unsafe { boot::free_pages(ptr.cast(), num_pages) }.unwrap();
146+ /// ```
147+ ///
127148/// # Errors
128149///
129150/// * [`Status::OUT_OF_RESOURCES`]: allocation failed.
130151/// * [`Status::INVALID_PARAMETER`]: `mem_ty` is [`MemoryType::PERSISTENT_MEMORY`],
131152/// [`MemoryType::UNACCEPTED`], or in the range [`MemoryType::MAX`]`..=0x6fff_ffff`.
132153/// * [`Status::NOT_FOUND`]: the requested pages could not be found.
133- pub fn allocate_pages ( ty : AllocateType , mem_ty : MemoryType , count : usize ) -> Result < NonNull < u8 > > {
154+ pub fn allocate_pages (
155+ allocation_type : AllocateType ,
156+ memory_type : MemoryType ,
157+ count : usize ,
158+ ) -> Result < NonNull < [ u8 ] > > {
134159 let bt = boot_services_raw_panicking ( ) ;
135160 let bt = unsafe { bt. as_ref ( ) } ;
136161
137- let ( ty , initial_addr ) = match ty {
162+ let ( allocation_type_efi , start_address ) = match allocation_type {
138163 AllocateType :: AnyPages => ( 0 , 0 ) ,
139164 AllocateType :: MaxAddress ( addr) => ( 1 , addr) ,
140165 AllocateType :: Address ( addr) => ( 2 , addr) ,
141166 } ;
142167
143- let mut addr1 = initial_addr;
144- unsafe { ( bt. allocate_pages ) ( ty, mem_ty, count, & mut addr1) } . to_result ( ) ?;
168+ let mut addr1 = start_address;
169+ unsafe { ( bt. allocate_pages ) ( allocation_type_efi, memory_type, count, & mut addr1) }
170+ . to_result ( ) ?;
145171
146172 // The UEFI spec allows `allocate_pages` to return a valid allocation at
147173 // address zero. Rust does not allow writes through a null pointer (which
148174 // Rust defines as address zero), so this is not very useful. Only return
149175 // the allocation if the address is non-null.
150176 if let Some ( ptr) = NonNull :: new ( addr1 as * mut u8 ) {
151- return Ok ( ptr) ;
177+ let slice = NonNull :: slice_from_raw_parts ( ptr, count * PAGE_SIZE ) ;
178+ return Ok ( slice) ;
152179 }
153180
154181 // Attempt a second allocation. The first allocation (at address zero) has
155182 // not yet been freed, so if this allocation succeeds it should be at a
156183 // non-zero address.
157- let mut addr2 = initial_addr;
158- let r = unsafe { ( bt. allocate_pages ) ( ty, mem_ty, count, & mut addr2) } . to_result ( ) ;
184+ let mut addr2 = start_address;
185+ let r = unsafe { ( bt. allocate_pages ) ( allocation_type_efi, memory_type, count, & mut addr2) }
186+ . to_result ( ) ;
159187
160188 // Free the original allocation (ignoring errors).
161189 let _unused = unsafe { ( bt. free_pages ) ( addr1, count) } ;
@@ -164,7 +192,8 @@ pub fn allocate_pages(ty: AllocateType, mem_ty: MemoryType, count: usize) -> Res
164192 // address zero. Otherwise, return a pointer to the second allocation.
165193 r?;
166194 if let Some ( ptr) = NonNull :: new ( addr2 as * mut u8 ) {
167- Ok ( ptr)
195+ let slice = NonNull :: slice_from_raw_parts ( ptr, count * PAGE_SIZE ) ;
196+ Ok ( slice)
168197 } else {
169198 Err ( Status :: OUT_OF_RESOURCES . into ( ) )
170199 }
@@ -191,6 +220,31 @@ pub unsafe fn free_pages(ptr: NonNull<u8>, count: usize) -> Result {
191220
192221/// Allocates from a memory pool. The pointer will be 8-byte aligned.
193222///
223+ /// The caller is responsible to free the memory using [`free_pool`].
224+ ///
225+ /// # Arguments
226+ /// - `memory_type`: The [`MemoryType`] used to persist the allocation in the
227+ /// UEFI memory map. Typically, UEFI OS loaders should allocate memory of
228+ /// type [`MemoryType::LOADER_DATA`].
229+ ///- `size`: Amount of bytes to allocate.
230+ ///
231+ /// # Example
232+ ///```rust,no_run
233+ /// use uefi::boot::{self, AllocateType};
234+ /// use uefi_raw::table::boot::MemoryType;
235+ ///
236+ /// let mut ptr = boot::allocate_pool(
237+ /// MemoryType::LOADER_DATA,
238+ /// 42
239+ /// ).unwrap();
240+ ///
241+ /// let buffer: &mut [u8] = unsafe { ptr.as_mut() };
242+ /// // now do something with your buffer
243+ ///
244+ /// // free the allocation
245+ /// unsafe { boot::free_pool(ptr.cast()) }.unwrap();
246+ /// ```
247+ ///
194248/// # Errors
195249///
196250/// * [`Status::OUT_OF_RESOURCES`]: allocation failed.
0 commit comments