1 #include "efi.h"
2 #include <xen/init.h>
3 #include <xen/mm.h>
4 
5 #ifdef CONFIG_ARM
6 /*
7  * TODO: Enable EFI boot allocator on ARM.
8  * This code can be common for x86 and ARM.
9  * Things TODO on ARM before enabling ebmalloc:
10  *   - estimate required EBMALLOC_SIZE value,
11  *   - where (in which section) ebmalloc_mem[] should live; if in
12  *     .bss.page_aligned, as it is right now, then whole BSS zeroing
13  *     have to be disabled in xen/arch/arm/arm64/head.S; though BSS
14  *     should be initialized somehow before use of variables living there,
15  *   - use ebmalloc() in ARM/common EFI boot code,
16  *   - call free_ebmalloc_unused_mem() somewhere in init code.
17  */
18 #define EBMALLOC_SIZE	MB(0)
19 #else
20 #define EBMALLOC_SIZE	MB(1)
21 #endif
22 
23 static char __section(".bss.page_aligned") __aligned(PAGE_SIZE)
24     ebmalloc_mem[EBMALLOC_SIZE];
25 static unsigned long __read_mostly ebmalloc_allocated;
26 
27 /* EFI boot allocator. */
ebmalloc(size_t size)28 void __init *ebmalloc(size_t size)
29 {
30     void *ptr = ebmalloc_mem + ebmalloc_allocated;
31 
32     ebmalloc_allocated += ROUNDUP(size, sizeof(void *));
33 
34     if ( ebmalloc_allocated > sizeof(ebmalloc_mem) )
35         blexit(L"Out of static memory\r\n");
36 
37     return ptr;
38 }
39 
efi_boot_mem_unused(unsigned long * start,unsigned long * end)40 bool efi_boot_mem_unused(unsigned long *start, unsigned long *end)
41 {
42     /* FIXME: Drop once the call here with two NULLs goes away. */
43     if ( !start && !end )
44     {
45         ebmalloc_allocated = sizeof(ebmalloc_mem);
46         return false;
47     }
48 
49     *start = (unsigned long)ebmalloc_mem + PAGE_ALIGN(ebmalloc_allocated);
50     *end = (unsigned long)ebmalloc_mem + sizeof(ebmalloc_mem);
51 
52     return *start < *end;
53 }
54 
free_ebmalloc_unused_mem(void)55 void __init free_ebmalloc_unused_mem(void)
56 {
57     unsigned long start, end;
58 
59     if ( !efi_boot_mem_unused(&start, &end) )
60         return;
61 
62     destroy_xen_mappings(start, end);
63 
64 #ifdef CONFIG_X86
65     /*
66      * By reserving the space early in the E820 map, it gets freed way before
67      * we make it here. Don't free the range a 2nd time.
68      */
69 #else
70     init_xenheap_pages(__pa(start), __pa(end));
71 #endif
72 
73     printk(XENLOG_INFO "Freed %lukB unused BSS memory\n", (end - start) >> 10);
74 }
75