[2/2] efi/fdt: set address/size cells to 2 for empty tree

Message ID 20180611162459.9178-3-leif.lindholm@linaro.org
State Accepted
Commit 347210a5d5ce655b95315f320faa515afb723c11
Headers show
Series
  • efi/fdt: set #address-cells/#size-cells on empty tree
Related show

Commit Message

Leif Lindholm June 11, 2018, 4:24 p.m.
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 <leif.lindholm@linaro.org>

---
 grub-core/loader/efi/fdt.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

-- 
2.11.0


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Patch

diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
index c0c6800f7..477ef7485 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,14 @@  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 +75,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;
 }