@@ -114,7 +114,7 @@ static void __init relocate_trampoline(unsigned long phys)
static void __init place_string(u32 *addr, const char *s)
{
- static char *__initdata alloc = start;
+ char *alloc = NULL;
if ( s && *s )
{
@@ -122,7 +122,7 @@ static void __init place_string(u32 *addr, const char *s)
const char *old = (char *)(long)*addr;
size_t len2 = *addr ? strlen(old) + 1 : 0;
- alloc -= len1 + len2;
+ alloc = ebmalloc(len1 + len2);
/*
* Insert new string before already existing one. This is needed
* for options passed on the command line to override options from
@@ -205,12 +205,7 @@ static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *SystemTable,
static void *__init efi_arch_allocate_mmap_buffer(UINTN map_size)
{
- place_string(&mbi.mem_upper, NULL);
- mbi.mem_upper -= map_size;
- mbi.mem_upper &= -__alignof__(EFI_MEMORY_DESCRIPTOR);
- if ( mbi.mem_upper < xen_phys_start )
- return NULL;
- return (void *)(long)mbi.mem_upper;
+ return ebmalloc(map_size);
}
static void __init efi_arch_pre_exit_boot(void)
@@ -1123,8 +1123,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
if ( !xen_phys_start )
panic("Not enough memory to relocate Xen.");
- reserve_e820_ram(&boot_e820, efi_enabled(EFI_LOADER) ? mbi->mem_upper : __pa(&_start),
- __pa(&_end));
+ reserve_e820_ram(&boot_e820, __pa(&_start), __pa(&_end));
/* Late kexec reservation (dynamic start address). */
kexec_reserve_area(&boot_e820);
@@ -98,6 +98,54 @@ static CHAR16 __initdata newline[] = L"\r\n";
#define PrintStr(s) StdOut->OutputString(StdOut, s)
#define PrintErr(s) StdErr->OutputString(StdErr, s)
+#ifdef CONFIG_ARM
+/*
+ * TODO: Enable EFI boot allocator on ARM.
+ * This code can be common for x86 and ARM.
+ * Things TODO on ARM before enabling ebmalloc:
+ * - estimate required EBMALLOC_SIZE value,
+ * - where (in which section) ebmalloc_mem[] should live; if in
+ * .bss.page_aligned, as it is right now, then whole BSS zeroing
+ * have to be disabled in xen/arch/arm/arm64/head.S; though BSS
+ * should be initialized somehow before use of variables living there,
+ * - use ebmalloc() in ARM/common EFI boot code,
+ * - call free_ebmalloc_unused_mem() somewhere in init code.
+ */
+#define EBMALLOC_SIZE MB(0)
+#else
+#define EBMALLOC_SIZE MB(1)
+#endif
+
+static char __section(".bss.page_aligned") __aligned(PAGE_SIZE)
+ ebmalloc_mem[EBMALLOC_SIZE];
+static unsigned long __initdata ebmalloc_allocated;
+
+/* EFI boot allocator. */
+static void __init __maybe_unused *ebmalloc(size_t size)
+{
+ void *ptr = ebmalloc_mem + ebmalloc_allocated;
+
+ ebmalloc_allocated += (size + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
+
+ if ( ebmalloc_allocated > sizeof(ebmalloc_mem) )
+ blexit(L"Out of static memory\r\n");
+
+ return ptr;
+}
+
+static void __init __maybe_unused free_ebmalloc_unused_mem(void)
+{
+ unsigned long start, end;
+
+ start = (unsigned long)ebmalloc_mem + PAGE_ALIGN(ebmalloc_allocated);
+ end = (unsigned long)ebmalloc_mem + sizeof(ebmalloc_mem);
+
+ destroy_xen_mappings(start, end);
+ init_xenheap_pages(__pa(start), __pa(end));
+
+ printk(XENLOG_INFO "Freed %lukB unused BSS memory\n", (end - start) >> 10);
+}
+
/*
* Include architecture specific implementation here, which references the
* static globals defined above.
@@ -1251,6 +1299,8 @@ void __init efi_init_memory(void)
} *extra, *extra_head = NULL;
#endif
+ free_ebmalloc_unused_mem();
+
if ( !efi_enabled(EFI_BOOT) )
return;