2 * EFI application memory management
4 * Copyright (c) 2016 Alexander Graf
6 * SPDX-License-Identifier: GPL-2.0+
10 #include <efi_loader.h>
12 #include <asm/global_data.h>
13 #include <libfdt_env.h>
14 #include <linux/list_sort.h>
18 DECLARE_GLOBAL_DATA_PTR
;
21 struct list_head link
;
22 struct efi_mem_desc desc
;
25 #define EFI_CARVE_NO_OVERLAP -1
26 #define EFI_CARVE_LOOP_AGAIN -2
27 #define EFI_CARVE_OVERLAPS_NONRAM -3
29 /* This list contains all memory map items */
32 #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
33 void *efi_bounce_buffer
;
37 * U-Boot services each EFI AllocatePool request as a separate
38 * (multiple) page allocation. We have to track the number of pages
39 * to be able to free the correct amount later.
40 * EFI requires 8 byte alignment for pool allocations, so we can
41 * prepend each allocation with an 64 bit header tracking the
42 * allocation size, and hand out the remainder to the caller.
44 struct efi_pool_allocation
{
46 char data
[] __aligned(ARCH_DMA_MINALIGN
);
50 * Sorts the memory list from highest address to lowest address
52 * When allocating memory we should always start from the highest
53 * address chunk, so sort the memory list such that the first list
54 * iterator gets the highest address and goes lower from there.
56 static int efi_mem_cmp(void *priv
, struct list_head
*a
, struct list_head
*b
)
58 struct efi_mem_list
*mema
= list_entry(a
, struct efi_mem_list
, link
);
59 struct efi_mem_list
*memb
= list_entry(b
, struct efi_mem_list
, link
);
61 if (mema
->desc
.physical_start
== memb
->desc
.physical_start
)
63 else if (mema
->desc
.physical_start
< memb
->desc
.physical_start
)
69 static void efi_mem_sort(void)
71 list_sort(NULL
, &efi_mem
, efi_mem_cmp
);
75 * Unmaps all memory occupied by the carve_desc region from the
76 * list entry pointed to by map.
78 * Returns EFI_CARVE_NO_OVERLAP if the regions don't overlap.
79 * Returns EFI_CARVE_OVERLAPS_NONRAM if the carve and map overlap,
80 * and the map contains anything but free ram.
81 * (only when overlap_only_ram is true)
82 * Returns EFI_CARVE_LOOP_AGAIN if the mapping list should be traversed
83 * again, as it has been altered
84 * Returns the number of overlapping pages. The pages are removed from
87 * In case of EFI_CARVE_OVERLAPS_NONRAM it is the callers responsibility
88 * to readd the already carved out pages to the mapping.
90 static int efi_mem_carve_out(struct efi_mem_list
*map
,
91 struct efi_mem_desc
*carve_desc
,
92 bool overlap_only_ram
)
94 struct efi_mem_list
*newmap
;
95 struct efi_mem_desc
*map_desc
= &map
->desc
;
96 uint64_t map_start
= map_desc
->physical_start
;
97 uint64_t map_end
= map_start
+ (map_desc
->num_pages
<< EFI_PAGE_SHIFT
);
98 uint64_t carve_start
= carve_desc
->physical_start
;
99 uint64_t carve_end
= carve_start
+
100 (carve_desc
->num_pages
<< EFI_PAGE_SHIFT
);
102 /* check whether we're overlapping */
103 if ((carve_end
<= map_start
) || (carve_start
>= map_end
))
104 return EFI_CARVE_NO_OVERLAP
;
106 /* We're overlapping with non-RAM, warn the caller if desired */
107 if (overlap_only_ram
&& (map_desc
->type
!= EFI_CONVENTIONAL_MEMORY
))
108 return EFI_CARVE_OVERLAPS_NONRAM
;
110 /* Sanitize carve_start and carve_end to lie within our bounds */
111 carve_start
= max(carve_start
, map_start
);
112 carve_end
= min(carve_end
, map_end
);
114 /* Carving at the beginning of our map? Just move it! */
115 if (carve_start
== map_start
) {
116 if (map_end
== carve_end
) {
117 /* Full overlap, just remove map */
118 list_del(&map
->link
);
121 map
->desc
.physical_start
= carve_end
;
122 map
->desc
.num_pages
= (map_end
- carve_end
)
126 return (carve_end
- carve_start
) >> EFI_PAGE_SHIFT
;
130 * Overlapping maps, just split the list map at carve_start,
131 * it will get moved or removed in the next iteration.
133 * [ map_desc |__carve_start__| newmap ]
136 /* Create a new map from [ carve_start ... map_end ] */
137 newmap
= calloc(1, sizeof(*newmap
));
138 newmap
->desc
= map
->desc
;
139 newmap
->desc
.physical_start
= carve_start
;
140 newmap
->desc
.num_pages
= (map_end
- carve_start
) >> EFI_PAGE_SHIFT
;
141 /* Insert before current entry (descending address order) */
142 list_add_tail(&newmap
->link
, &map
->link
);
144 /* Shrink the map to [ map_start ... carve_start ] */
145 map_desc
->num_pages
= (carve_start
- map_start
) >> EFI_PAGE_SHIFT
;
147 return EFI_CARVE_LOOP_AGAIN
;
150 uint64_t efi_add_memory_map(uint64_t start
, uint64_t pages
, int memory_type
,
151 bool overlap_only_ram
)
153 struct list_head
*lhandle
;
154 struct efi_mem_list
*newlist
;
156 uint64_t carved_pages
= 0;
158 debug("%s: 0x%" PRIx64
" 0x%" PRIx64
" %d %s\n", __func__
,
159 start
, pages
, memory_type
, overlap_only_ram
? "yes" : "no");
164 newlist
= calloc(1, sizeof(*newlist
));
165 newlist
->desc
.type
= memory_type
;
166 newlist
->desc
.physical_start
= start
;
167 newlist
->desc
.virtual_start
= start
;
168 newlist
->desc
.num_pages
= pages
;
170 switch (memory_type
) {
171 case EFI_RUNTIME_SERVICES_CODE
:
172 case EFI_RUNTIME_SERVICES_DATA
:
173 newlist
->desc
.attribute
= (1 << EFI_MEMORY_WB_SHIFT
) |
174 (1ULL << EFI_MEMORY_RUNTIME_SHIFT
);
177 newlist
->desc
.attribute
= 1ULL << EFI_MEMORY_RUNTIME_SHIFT
;
180 newlist
->desc
.attribute
= 1 << EFI_MEMORY_WB_SHIFT
;
184 /* Add our new map */
187 list_for_each(lhandle
, &efi_mem
) {
188 struct efi_mem_list
*lmem
;
191 lmem
= list_entry(lhandle
, struct efi_mem_list
, link
);
192 r
= efi_mem_carve_out(lmem
, &newlist
->desc
,
195 case EFI_CARVE_OVERLAPS_NONRAM
:
197 * The user requested to only have RAM overlaps,
198 * but we hit a non-RAM region. Error out.
201 case EFI_CARVE_NO_OVERLAP
:
202 /* Just ignore this list entry */
204 case EFI_CARVE_LOOP_AGAIN
:
206 * We split an entry, but need to loop through
207 * the list again to actually carve it.
212 /* We carved a number of pages */
219 /* The list changed, we need to start over */
223 } while (carve_again
);
225 if (overlap_only_ram
&& (carved_pages
!= pages
)) {
227 * The payload wanted to have RAM overlaps, but we overlapped
228 * with an unallocated region. Error out.
233 /* Add our new map */
234 list_add_tail(&newlist
->link
, &efi_mem
);
236 /* And make sure memory is listed in descending order */
242 static uint64_t efi_find_free_memory(uint64_t len
, uint64_t max_addr
)
244 struct list_head
*lhandle
;
246 list_for_each(lhandle
, &efi_mem
) {
247 struct efi_mem_list
*lmem
= list_entry(lhandle
,
248 struct efi_mem_list
, link
);
249 struct efi_mem_desc
*desc
= &lmem
->desc
;
250 uint64_t desc_len
= desc
->num_pages
<< EFI_PAGE_SHIFT
;
251 uint64_t desc_end
= desc
->physical_start
+ desc_len
;
252 uint64_t curmax
= min(max_addr
, desc_end
);
253 uint64_t ret
= curmax
- len
;
255 /* We only take memory from free RAM */
256 if (desc
->type
!= EFI_CONVENTIONAL_MEMORY
)
259 /* Out of bounds for max_addr */
260 if ((ret
+ len
) > max_addr
)
263 /* Out of bounds for upper map limit */
264 if ((ret
+ len
) > desc_end
)
267 /* Out of bounds for lower map limit */
268 if (ret
< desc
->physical_start
)
271 /* Return the highest address in this map within bounds */
278 efi_status_t
efi_allocate_pages(int type
, int memory_type
,
279 efi_uintn_t pages
, uint64_t *memory
)
281 u64 len
= pages
<< EFI_PAGE_SHIFT
;
282 efi_status_t r
= EFI_SUCCESS
;
288 addr
= efi_find_free_memory(len
, gd
->start_addr_sp
);
296 addr
= efi_find_free_memory(len
, *memory
);
303 /* Exact address, reserve it. The addr is already in *memory. */
307 /* UEFI doesn't specify other allocation types */
308 r
= EFI_INVALID_PARAMETER
;
312 if (r
== EFI_SUCCESS
) {
315 /* Reserve that map in our memory maps */
316 ret
= efi_add_memory_map(addr
, pages
, memory_type
, true);
320 /* Map would overlap, bail out */
321 r
= EFI_OUT_OF_RESOURCES
;
328 void *efi_alloc(uint64_t len
, int memory_type
)
331 uint64_t pages
= (len
+ EFI_PAGE_MASK
) >> EFI_PAGE_SHIFT
;
334 r
= efi_allocate_pages(0, memory_type
, pages
, &ret
);
335 if (r
== EFI_SUCCESS
)
336 return (void*)(uintptr_t)ret
;
341 efi_status_t
efi_free_pages(uint64_t memory
, efi_uintn_t pages
)
345 r
= efi_add_memory_map(memory
, pages
, EFI_CONVENTIONAL_MEMORY
, false);
346 /* Merging of adjacent free regions is missing */
351 return EFI_NOT_FOUND
;
354 efi_status_t
efi_allocate_pool(int pool_type
, efi_uintn_t size
,
358 efi_physical_addr_t t
;
359 u64 num_pages
= (size
+ sizeof(struct efi_pool_allocation
) +
360 EFI_PAGE_MASK
) >> EFI_PAGE_SHIFT
;
367 r
= efi_allocate_pages(0, pool_type
, num_pages
, &t
);
369 if (r
== EFI_SUCCESS
) {
370 struct efi_pool_allocation
*alloc
= (void *)(uintptr_t)t
;
371 alloc
->num_pages
= num_pages
;
372 *buffer
= alloc
->data
;
378 efi_status_t
efi_free_pool(void *buffer
)
381 struct efi_pool_allocation
*alloc
;
384 return EFI_INVALID_PARAMETER
;
386 alloc
= container_of(buffer
, struct efi_pool_allocation
, data
);
387 /* Sanity check, was the supplied address returned by allocate_pool */
388 assert(((uintptr_t)alloc
& EFI_PAGE_MASK
) == 0);
390 r
= efi_free_pages((uintptr_t)alloc
, alloc
->num_pages
);
395 efi_status_t
efi_get_memory_map(efi_uintn_t
*memory_map_size
,
396 struct efi_mem_desc
*memory_map
,
397 efi_uintn_t
*map_key
,
398 efi_uintn_t
*descriptor_size
,
399 uint32_t *descriptor_version
)
401 efi_uintn_t map_size
= 0;
403 struct list_head
*lhandle
;
404 efi_uintn_t provided_map_size
= *memory_map_size
;
406 list_for_each(lhandle
, &efi_mem
)
409 map_size
= map_entries
* sizeof(struct efi_mem_desc
);
411 *memory_map_size
= map_size
;
413 if (provided_map_size
< map_size
)
414 return EFI_BUFFER_TOO_SMALL
;
417 *descriptor_size
= sizeof(struct efi_mem_desc
);
419 if (descriptor_version
)
420 *descriptor_version
= EFI_MEMORY_DESCRIPTOR_VERSION
;
422 /* Copy list into array */
424 /* Return the list in ascending order */
425 memory_map
= &memory_map
[map_entries
- 1];
426 list_for_each(lhandle
, &efi_mem
) {
427 struct efi_mem_list
*lmem
;
429 lmem
= list_entry(lhandle
, struct efi_mem_list
, link
);
430 *memory_map
= lmem
->desc
;
440 __weak
void efi_add_known_memory(void)
445 for (i
= 0; i
< CONFIG_NR_DRAM_BANKS
; i
++) {
446 u64 ram_start
= gd
->bd
->bi_dram
[i
].start
;
447 u64 ram_size
= gd
->bd
->bi_dram
[i
].size
;
448 u64 start
= (ram_start
+ EFI_PAGE_MASK
) & ~EFI_PAGE_MASK
;
449 u64 pages
= (ram_size
+ EFI_PAGE_MASK
) >> EFI_PAGE_SHIFT
;
451 efi_add_memory_map(start
, pages
, EFI_CONVENTIONAL_MEMORY
,
456 int efi_memory_init(void)
458 unsigned long runtime_start
, runtime_end
, runtime_pages
;
459 unsigned long uboot_start
, uboot_pages
;
460 unsigned long uboot_stack_size
= 16 * 1024 * 1024;
462 efi_add_known_memory();
465 uboot_start
= (gd
->start_addr_sp
- uboot_stack_size
) & ~EFI_PAGE_MASK
;
466 uboot_pages
= (gd
->ram_top
- uboot_start
) >> EFI_PAGE_SHIFT
;
467 efi_add_memory_map(uboot_start
, uboot_pages
, EFI_LOADER_DATA
, false);
469 /* Add Runtime Services */
470 runtime_start
= (ulong
)&__efi_runtime_start
& ~EFI_PAGE_MASK
;
471 runtime_end
= (ulong
)&__efi_runtime_stop
;
472 runtime_end
= (runtime_end
+ EFI_PAGE_MASK
) & ~EFI_PAGE_MASK
;
473 runtime_pages
= (runtime_end
- runtime_start
) >> EFI_PAGE_SHIFT
;
474 efi_add_memory_map(runtime_start
, runtime_pages
,
475 EFI_RUNTIME_SERVICES_CODE
, false);
477 #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
478 /* Request a 32bit 64MB bounce buffer region */
479 uint64_t efi_bounce_buffer_addr
= 0xffffffff;
481 if (efi_allocate_pages(1, EFI_LOADER_DATA
,
482 (64 * 1024 * 1024) >> EFI_PAGE_SHIFT
,
483 &efi_bounce_buffer_addr
) != EFI_SUCCESS
)
486 efi_bounce_buffer
= (void*)(uintptr_t)efi_bounce_buffer_addr
;