From 347210a5d5ce655b95315f320faa515afb723c11 Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Mon, 11 Jun 2018 17:24:59 +0100 Subject: [PATCH] efi/fdt: Set address/size cells to 2 for empty tree When booting an arm* system on UEFI with an empty device tree (currently only when hardware description comes from ACPI), we don't currently set default to 1 cell (32 bits). Set both of these properties, to 2 cells (64 bits), to resolve issues with kexec on some platforms. This change corresponds with linux kernel commit ae8a442dfdc4 ("efi/libstub/arm*: Set default address and size cells values for an empty dtb") and ensures booting through grub does not behave differently from booting the stub loader directly. See also https://patchwork.kernel.org/patch/9561201/ Signed-off-by: Leif Lindholm Reviewed-by: Daniel Kiper --- grub-core/loader/efi/fdt.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c index c0c6800f79e..a4c6e803645 100644 --- a/grub-core/loader/efi/fdt.c +++ b/grub-core/loader/efi/fdt.c @@ -29,6 +29,12 @@ static void *loaded_fdt; static void *fdt; +#define FDT_ADDR_CELLS_STRING "#address-cells" +#define FDT_SIZE_CELLS_STRING "#size-cells" +#define FDT_ADDR_SIZE_EXTRA ((2 * grub_fdt_prop_entry_size (sizeof(grub_uint32_t))) + \ + sizeof (FDT_ADDR_CELLS_STRING) + \ + sizeof (FDT_SIZE_CELLS_STRING)) + void * grub_fdt_load (grub_size_t additional_size) { @@ -46,8 +52,11 @@ grub_fdt_load (grub_size_t additional_size) else raw_fdt = grub_efi_get_firmware_fdt(); - size = - raw_fdt ? grub_fdt_get_totalsize (raw_fdt) : GRUB_FDT_EMPTY_TREE_SZ; + if (raw_fdt) + size = grub_fdt_get_totalsize (raw_fdt); + else + size = GRUB_FDT_EMPTY_TREE_SZ + FDT_ADDR_SIZE_EXTRA; + size += additional_size; grub_dprintf ("linux", "allocating %d bytes for fdt\n", size); @@ -63,6 +72,8 @@ grub_fdt_load (grub_size_t additional_size) else { grub_fdt_create_empty_tree (fdt, size); + grub_fdt_set_prop32 (fdt, 0, FDT_ADDR_CELLS_STRING, 2); + grub_fdt_set_prop32 (fdt, 0, FDT_SIZE_CELLS_STRING, 2); } return fdt; }