xref: /openbmc/u-boot/lib/efi_loader/efi_memory.c (revision ad97051b)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  EFI application memory management
4  *
5  *  Copyright (c) 2016 Alexander Graf
6  */
7 
8 #include <common.h>
9 #include <efi_loader.h>
10 #include <inttypes.h>
11 #include <malloc.h>
12 #include <watchdog.h>
13 #include <asm/global_data.h>
14 #include <linux/list_sort.h>
15 
16 DECLARE_GLOBAL_DATA_PTR;
17 
18 struct efi_mem_list {
19 	struct list_head link;
20 	struct efi_mem_desc desc;
21 };
22 
23 #define EFI_CARVE_NO_OVERLAP		-1
24 #define EFI_CARVE_LOOP_AGAIN		-2
25 #define EFI_CARVE_OVERLAPS_NONRAM	-3
26 
27 /* This list contains all memory map items */
28 LIST_HEAD(efi_mem);
29 
30 #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
31 void *efi_bounce_buffer;
32 #endif
33 
34 /*
35  * U-Boot services each EFI AllocatePool request as a separate
36  * (multiple) page allocation.  We have to track the number of pages
37  * to be able to free the correct amount later.
38  * EFI requires 8 byte alignment for pool allocations, so we can
39  * prepend each allocation with an 64 bit header tracking the
40  * allocation size, and hand out the remainder to the caller.
41  */
42 struct efi_pool_allocation {
43 	u64 num_pages;
44 	char data[] __aligned(ARCH_DMA_MINALIGN);
45 };
46 
47 /*
48  * Sorts the memory list from highest address to lowest address
49  *
50  * When allocating memory we should always start from the highest
51  * address chunk, so sort the memory list such that the first list
52  * iterator gets the highest address and goes lower from there.
53  */
54 static int efi_mem_cmp(void *priv, struct list_head *a, struct list_head *b)
55 {
56 	struct efi_mem_list *mema = list_entry(a, struct efi_mem_list, link);
57 	struct efi_mem_list *memb = list_entry(b, struct efi_mem_list, link);
58 
59 	if (mema->desc.physical_start == memb->desc.physical_start)
60 		return 0;
61 	else if (mema->desc.physical_start < memb->desc.physical_start)
62 		return 1;
63 	else
64 		return -1;
65 }
66 
67 static void efi_mem_sort(void)
68 {
69 	list_sort(NULL, &efi_mem, efi_mem_cmp);
70 }
71 
72 /*
73  * Unmaps all memory occupied by the carve_desc region from the
74  * list entry pointed to by map.
75  *
76  * Returns EFI_CARVE_NO_OVERLAP if the regions don't overlap.
77  * Returns EFI_CARVE_OVERLAPS_NONRAM if the carve and map overlap,
78  *    and the map contains anything but free ram.
79  *    (only when overlap_only_ram is true)
80  * Returns EFI_CARVE_LOOP_AGAIN if the mapping list should be traversed
81  *    again, as it has been altered
82  * Returns the number of overlapping pages. The pages are removed from
83  *     the mapping list.
84  *
85  * In case of EFI_CARVE_OVERLAPS_NONRAM it is the callers responsibility
86  * to readd the already carved out pages to the mapping.
87  */
88 static int efi_mem_carve_out(struct efi_mem_list *map,
89 			     struct efi_mem_desc *carve_desc,
90 			     bool overlap_only_ram)
91 {
92 	struct efi_mem_list *newmap;
93 	struct efi_mem_desc *map_desc = &map->desc;
94 	uint64_t map_start = map_desc->physical_start;
95 	uint64_t map_end = map_start + (map_desc->num_pages << EFI_PAGE_SHIFT);
96 	uint64_t carve_start = carve_desc->physical_start;
97 	uint64_t carve_end = carve_start +
98 			     (carve_desc->num_pages << EFI_PAGE_SHIFT);
99 
100 	/* check whether we're overlapping */
101 	if ((carve_end <= map_start) || (carve_start >= map_end))
102 		return EFI_CARVE_NO_OVERLAP;
103 
104 	/* We're overlapping with non-RAM, warn the caller if desired */
105 	if (overlap_only_ram && (map_desc->type != EFI_CONVENTIONAL_MEMORY))
106 		return EFI_CARVE_OVERLAPS_NONRAM;
107 
108 	/* Sanitize carve_start and carve_end to lie within our bounds */
109 	carve_start = max(carve_start, map_start);
110 	carve_end = min(carve_end, map_end);
111 
112 	/* Carving at the beginning of our map? Just move it! */
113 	if (carve_start == map_start) {
114 		if (map_end == carve_end) {
115 			/* Full overlap, just remove map */
116 			list_del(&map->link);
117 			free(map);
118 		} else {
119 			map->desc.physical_start = carve_end;
120 			map->desc.num_pages = (map_end - carve_end)
121 					      >> EFI_PAGE_SHIFT;
122 		}
123 
124 		return (carve_end - carve_start) >> EFI_PAGE_SHIFT;
125 	}
126 
127 	/*
128 	 * Overlapping maps, just split the list map at carve_start,
129 	 * it will get moved or removed in the next iteration.
130 	 *
131 	 * [ map_desc |__carve_start__| newmap ]
132 	 */
133 
134 	/* Create a new map from [ carve_start ... map_end ] */
135 	newmap = calloc(1, sizeof(*newmap));
136 	newmap->desc = map->desc;
137 	newmap->desc.physical_start = carve_start;
138 	newmap->desc.num_pages = (map_end - carve_start) >> EFI_PAGE_SHIFT;
139 	/* Insert before current entry (descending address order) */
140 	list_add_tail(&newmap->link, &map->link);
141 
142 	/* Shrink the map to [ map_start ... carve_start ] */
143 	map_desc->num_pages = (carve_start - map_start) >> EFI_PAGE_SHIFT;
144 
145 	return EFI_CARVE_LOOP_AGAIN;
146 }
147 
148 uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
149 			    bool overlap_only_ram)
150 {
151 	struct list_head *lhandle;
152 	struct efi_mem_list *newlist;
153 	bool carve_again;
154 	uint64_t carved_pages = 0;
155 
156 	debug("%s: 0x%" PRIx64 " 0x%" PRIx64 " %d %s\n", __func__,
157 	      start, pages, memory_type, overlap_only_ram ? "yes" : "no");
158 
159 	if (!pages)
160 		return start;
161 
162 	newlist = calloc(1, sizeof(*newlist));
163 	newlist->desc.type = memory_type;
164 	newlist->desc.physical_start = start;
165 	newlist->desc.virtual_start = start;
166 	newlist->desc.num_pages = pages;
167 
168 	switch (memory_type) {
169 	case EFI_RUNTIME_SERVICES_CODE:
170 	case EFI_RUNTIME_SERVICES_DATA:
171 		newlist->desc.attribute = (1 << EFI_MEMORY_WB_SHIFT) |
172 					  (1ULL << EFI_MEMORY_RUNTIME_SHIFT);
173 		break;
174 	case EFI_MMAP_IO:
175 		newlist->desc.attribute = 1ULL << EFI_MEMORY_RUNTIME_SHIFT;
176 		break;
177 	default:
178 		newlist->desc.attribute = 1 << EFI_MEMORY_WB_SHIFT;
179 		break;
180 	}
181 
182 	/* Add our new map */
183 	do {
184 		carve_again = false;
185 		list_for_each(lhandle, &efi_mem) {
186 			struct efi_mem_list *lmem;
187 			int r;
188 
189 			lmem = list_entry(lhandle, struct efi_mem_list, link);
190 			r = efi_mem_carve_out(lmem, &newlist->desc,
191 					      overlap_only_ram);
192 			switch (r) {
193 			case EFI_CARVE_OVERLAPS_NONRAM:
194 				/*
195 				 * The user requested to only have RAM overlaps,
196 				 * but we hit a non-RAM region. Error out.
197 				 */
198 				return 0;
199 			case EFI_CARVE_NO_OVERLAP:
200 				/* Just ignore this list entry */
201 				break;
202 			case EFI_CARVE_LOOP_AGAIN:
203 				/*
204 				 * We split an entry, but need to loop through
205 				 * the list again to actually carve it.
206 				 */
207 				carve_again = true;
208 				break;
209 			default:
210 				/* We carved a number of pages */
211 				carved_pages += r;
212 				carve_again = true;
213 				break;
214 			}
215 
216 			if (carve_again) {
217 				/* The list changed, we need to start over */
218 				break;
219 			}
220 		}
221 	} while (carve_again);
222 
223 	if (overlap_only_ram && (carved_pages != pages)) {
224 		/*
225 		 * The payload wanted to have RAM overlaps, but we overlapped
226 		 * with an unallocated region. Error out.
227 		 */
228 		return 0;
229 	}
230 
231 	/* Add our new map */
232         list_add_tail(&newlist->link, &efi_mem);
233 
234 	/* And make sure memory is listed in descending order */
235 	efi_mem_sort();
236 
237 	return start;
238 }
239 
240 static uint64_t efi_find_free_memory(uint64_t len, uint64_t max_addr)
241 {
242 	struct list_head *lhandle;
243 
244 	list_for_each(lhandle, &efi_mem) {
245 		struct efi_mem_list *lmem = list_entry(lhandle,
246 			struct efi_mem_list, link);
247 		struct efi_mem_desc *desc = &lmem->desc;
248 		uint64_t desc_len = desc->num_pages << EFI_PAGE_SHIFT;
249 		uint64_t desc_end = desc->physical_start + desc_len;
250 		uint64_t curmax = min(max_addr, desc_end);
251 		uint64_t ret = curmax - len;
252 
253 		/* We only take memory from free RAM */
254 		if (desc->type != EFI_CONVENTIONAL_MEMORY)
255 			continue;
256 
257 		/* Out of bounds for max_addr */
258 		if ((ret + len) > max_addr)
259 			continue;
260 
261 		/* Out of bounds for upper map limit */
262 		if ((ret + len) > desc_end)
263 			continue;
264 
265 		/* Out of bounds for lower map limit */
266 		if (ret < desc->physical_start)
267 			continue;
268 
269 		/* Return the highest address in this map within bounds */
270 		return ret;
271 	}
272 
273 	return 0;
274 }
275 
276 /*
277  * Allocate memory pages.
278  *
279  * @type		type of allocation to be performed
280  * @memory_type		usage type of the allocated memory
281  * @pages		number of pages to be allocated
282  * @memory		allocated memory
283  * @return		status code
284  */
285 efi_status_t efi_allocate_pages(int type, int memory_type,
286 				efi_uintn_t pages, uint64_t *memory)
287 {
288 	u64 len = pages << EFI_PAGE_SHIFT;
289 	efi_status_t r = EFI_SUCCESS;
290 	uint64_t addr;
291 
292 	switch (type) {
293 	case EFI_ALLOCATE_ANY_PAGES:
294 		/* Any page */
295 		addr = efi_find_free_memory(len, gd->start_addr_sp);
296 		if (!addr) {
297 			r = EFI_NOT_FOUND;
298 			break;
299 		}
300 		break;
301 	case EFI_ALLOCATE_MAX_ADDRESS:
302 		/* Max address */
303 		addr = efi_find_free_memory(len, *memory);
304 		if (!addr) {
305 			r = EFI_NOT_FOUND;
306 			break;
307 		}
308 		break;
309 	case EFI_ALLOCATE_ADDRESS:
310 		/* Exact address, reserve it. The addr is already in *memory. */
311 		addr = *memory;
312 		break;
313 	default:
314 		/* UEFI doesn't specify other allocation types */
315 		r = EFI_INVALID_PARAMETER;
316 		break;
317 	}
318 
319 	if (r == EFI_SUCCESS) {
320 		uint64_t ret;
321 
322 		/* Reserve that map in our memory maps */
323 		ret = efi_add_memory_map(addr, pages, memory_type, true);
324 		if (ret == addr) {
325 			*memory = addr;
326 		} else {
327 			/* Map would overlap, bail out */
328 			r = EFI_OUT_OF_RESOURCES;
329 		}
330 	}
331 
332 	return r;
333 }
334 
335 void *efi_alloc(uint64_t len, int memory_type)
336 {
337 	uint64_t ret = 0;
338 	uint64_t pages = (len + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
339 	efi_status_t r;
340 
341 	r = efi_allocate_pages(0, memory_type, pages, &ret);
342 	if (r == EFI_SUCCESS)
343 		return (void*)(uintptr_t)ret;
344 
345 	return NULL;
346 }
347 
348 /*
349  * Free memory pages.
350  *
351  * @memory	start of the memory area to be freed
352  * @pages	number of pages to be freed
353  * @return	status code
354  */
355 efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
356 {
357 	uint64_t r = 0;
358 
359 	r = efi_add_memory_map(memory, pages, EFI_CONVENTIONAL_MEMORY, false);
360 	/* Merging of adjacent free regions is missing */
361 
362 	if (r == memory)
363 		return EFI_SUCCESS;
364 
365 	return EFI_NOT_FOUND;
366 }
367 
368 /*
369  * Allocate memory from pool.
370  *
371  * @pool_type	type of the pool from which memory is to be allocated
372  * @size	number of bytes to be allocated
373  * @buffer	allocated memory
374  * @return	status code
375  */
376 efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size, void **buffer)
377 {
378 	efi_status_t r;
379 	efi_physical_addr_t t;
380 	u64 num_pages = (size + sizeof(struct efi_pool_allocation) +
381 			 EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
382 
383 	if (size == 0) {
384 		*buffer = NULL;
385 		return EFI_SUCCESS;
386 	}
387 
388 	r = efi_allocate_pages(0, pool_type, num_pages, &t);
389 
390 	if (r == EFI_SUCCESS) {
391 		struct efi_pool_allocation *alloc = (void *)(uintptr_t)t;
392 		alloc->num_pages = num_pages;
393 		*buffer = alloc->data;
394 	}
395 
396 	return r;
397 }
398 
399 /*
400  * Free memory from pool.
401  *
402  * @buffer	start of memory to be freed
403  * @return	status code
404  */
405 efi_status_t efi_free_pool(void *buffer)
406 {
407 	efi_status_t r;
408 	struct efi_pool_allocation *alloc;
409 
410 	if (buffer == NULL)
411 		return EFI_INVALID_PARAMETER;
412 
413 	alloc = container_of(buffer, struct efi_pool_allocation, data);
414 	/* Sanity check, was the supplied address returned by allocate_pool */
415 	assert(((uintptr_t)alloc & EFI_PAGE_MASK) == 0);
416 
417 	r = efi_free_pages((uintptr_t)alloc, alloc->num_pages);
418 
419 	return r;
420 }
421 
422 /*
423  * Get map describing memory usage.
424  *
425  * @memory_map_size	on entry the size, in bytes, of the memory map buffer,
426  *			on exit the size of the copied memory map
427  * @memory_map		buffer to which the memory map is written
428  * @map_key		key for the memory map
429  * @descriptor_size	size of an individual memory descriptor
430  * @descriptor_version	version number of the memory descriptor structure
431  * @return		status code
432  */
433 efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
434 				struct efi_mem_desc *memory_map,
435 				efi_uintn_t *map_key,
436 				efi_uintn_t *descriptor_size,
437 				uint32_t *descriptor_version)
438 {
439 	efi_uintn_t map_size = 0;
440 	int map_entries = 0;
441 	struct list_head *lhandle;
442 	efi_uintn_t provided_map_size = *memory_map_size;
443 
444 	list_for_each(lhandle, &efi_mem)
445 		map_entries++;
446 
447 	map_size = map_entries * sizeof(struct efi_mem_desc);
448 
449 	*memory_map_size = map_size;
450 
451 	if (provided_map_size < map_size)
452 		return EFI_BUFFER_TOO_SMALL;
453 
454 	if (descriptor_size)
455 		*descriptor_size = sizeof(struct efi_mem_desc);
456 
457 	if (descriptor_version)
458 		*descriptor_version = EFI_MEMORY_DESCRIPTOR_VERSION;
459 
460 	/* Copy list into array */
461 	if (memory_map) {
462 		/* Return the list in ascending order */
463 		memory_map = &memory_map[map_entries - 1];
464 		list_for_each(lhandle, &efi_mem) {
465 			struct efi_mem_list *lmem;
466 
467 			lmem = list_entry(lhandle, struct efi_mem_list, link);
468 			*memory_map = lmem->desc;
469 			memory_map--;
470 		}
471 	}
472 
473 	*map_key = 0;
474 
475 	return EFI_SUCCESS;
476 }
477 
478 __weak void efi_add_known_memory(void)
479 {
480 	int i;
481 
482 	/* Add RAM */
483 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
484 		u64 ram_start = gd->bd->bi_dram[i].start;
485 		u64 ram_size = gd->bd->bi_dram[i].size;
486 		u64 start = (ram_start + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
487 		u64 pages = (ram_size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
488 
489 		efi_add_memory_map(start, pages, EFI_CONVENTIONAL_MEMORY,
490 				   false);
491 	}
492 }
493 
494 int efi_memory_init(void)
495 {
496 	unsigned long runtime_start, runtime_end, runtime_pages;
497 	unsigned long uboot_start, uboot_pages;
498 	unsigned long uboot_stack_size = 16 * 1024 * 1024;
499 
500 	efi_add_known_memory();
501 
502 	/* Add U-Boot */
503 	uboot_start = (gd->start_addr_sp - uboot_stack_size) & ~EFI_PAGE_MASK;
504 	uboot_pages = (gd->ram_top - uboot_start) >> EFI_PAGE_SHIFT;
505 	efi_add_memory_map(uboot_start, uboot_pages, EFI_LOADER_DATA, false);
506 
507 	/* Add Runtime Services */
508 	runtime_start = (ulong)&__efi_runtime_start & ~EFI_PAGE_MASK;
509 	runtime_end = (ulong)&__efi_runtime_stop;
510 	runtime_end = (runtime_end + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
511 	runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT;
512 	efi_add_memory_map(runtime_start, runtime_pages,
513 			   EFI_RUNTIME_SERVICES_CODE, false);
514 
515 #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
516 	/* Request a 32bit 64MB bounce buffer region */
517 	uint64_t efi_bounce_buffer_addr = 0xffffffff;
518 
519 	if (efi_allocate_pages(1, EFI_LOADER_DATA,
520 			       (64 * 1024 * 1024) >> EFI_PAGE_SHIFT,
521 			       &efi_bounce_buffer_addr) != EFI_SUCCESS)
522 		return -1;
523 
524 	efi_bounce_buffer = (void*)(uintptr_t)efi_bounce_buffer_addr;
525 #endif
526 
527 	return 0;
528 }
529