summaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_memory.c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-10-22 08:56:45 -0400
committerTom Rini <trini@konsulko.com>2021-10-22 12:43:30 -0400
commitf055f2e5a2038002519e5b9affbf259345f4ade9 (patch)
tree2388e5ea59e1e246d8f51b680d04861178f9608f /lib/efi_loader/efi_memory.c
parent06685f9de2c1ae37cd015848d245f8a59cbc93dc (diff)
parentaf484011f12e2aa37bcf4f9cbb4258dea4ef14ac (diff)
Merge tag 'efi-2022-01-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efi
Pull request for efi-2022-01-rc1 Documentation: Use Sphinx 3.43. Move system reset documentation to HTML UEFI: Fix linking EFI apps with LLVM Fix alignment of loaded image Correct simple network protocol test Code cleanup
Diffstat (limited to 'lib/efi_loader/efi_memory.c')
-rw-r--r--lib/efi_loader/efi_memory.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index f4acbee4f9b..7f0b5072819 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -550,6 +550,58 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
}
/**
+ * efi_alloc_aligned_pages - allocate
+ *
+ * @len: len in bytes
+ * @memory_type: usage type of the allocated memory
+ * @align: alignment in bytes
+ * Return: aligned memory or NULL
+ */
+void *efi_alloc_aligned_pages(u64 len, int memory_type, size_t align)
+{
+ u64 req_pages = efi_size_in_pages(len);
+ u64 true_pages = req_pages + efi_size_in_pages(align) - 1;
+ u64 free_pages;
+ u64 aligned_mem;
+ efi_status_t r;
+ u64 mem;
+
+ /* align must be zero or a power of two */
+ if (align & (align - 1))
+ return NULL;
+
+ /* Check for overflow */
+ if (true_pages < req_pages)
+ return NULL;
+
+ if (align < EFI_PAGE_SIZE) {
+ r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, memory_type,
+ req_pages, &mem);
+ return (r == EFI_SUCCESS) ? (void *)(uintptr_t)mem : NULL;
+ }
+
+ r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, memory_type,
+ true_pages, &mem);
+ if (r != EFI_SUCCESS)
+ return NULL;
+
+ aligned_mem = ALIGN(mem, align);
+ /* Free pages before alignment */
+ free_pages = efi_size_in_pages(aligned_mem - mem);
+ if (free_pages)
+ efi_free_pages(mem, free_pages);
+
+ /* Free trailing pages */
+ free_pages = true_pages - (req_pages + free_pages);
+ if (free_pages) {
+ mem = aligned_mem + req_pages * EFI_PAGE_SIZE;
+ efi_free_pages(mem, free_pages);
+ }
+
+ return (void *)(uintptr_t)aligned_mem;
+}
+
+/**
* efi_allocate_pool - allocate memory from pool
*
* @pool_type: type of the pool from which memory is to be allocated