diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 9b8af65..b213ef1 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -104,12 +104,34 @@ static struct efi_object bootefi_device_obj = { static void *copy_fdt(void *fdt) { u64 fdt_size = fdt_totalsize(fdt); + unsigned long fdt_ram_start = -1L, fdt_pages; + u64 new_fdt_addr; void *new_fdt; + int i; - /* Give us 64kb breathing room */ - fdt_size += 64 * 1024; + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + u64 ram_start = gd->bd->bi_dram[i].start; + u64 ram_size = gd->bd->bi_dram[i].size; - new_fdt = malloc(fdt_size); + if (!ram_size) + continue; + + if (ram_start < fdt_ram_start) + fdt_ram_start = ram_start; + } + + /* Give us at least 4kb breathing room */ + fdt_size = ALIGN(fdt_size + 4096, 4096); + fdt_pages = fdt_size >> EFI_PAGE_SHIFT; + + /* Safe fdt location is at 128MB */ + new_fdt_addr = fdt_ram_start + (128 * 1024 * 1024) + fdt_size; + if (efi_allocate_pages(1, EFI_BOOT_SERVICES_DATA, fdt_pages, + &new_fdt_addr) != EFI_SUCCESS) { + /* If we can't put it there, put it somewhere */ + new_fdt_addr = (ulong)memalign(4096, fdt_size); + } + new_fdt = (void*)(ulong)new_fdt_addr; memcpy(new_fdt, fdt, fdt_totalsize(fdt)); fdt_set_totalsize(new_fdt, fdt_size);