aboutsummaryrefslogtreecommitdiffstats
path: root/sys-boot/grub/files/grub-2.06-010-efi-device-tree-fixup-protocol.patch
diff options
context:
space:
mode:
Diffstat (limited to 'sys-boot/grub/files/grub-2.06-010-efi-device-tree-fixup-protocol.patch')
-rw-r--r--sys-boot/grub/files/grub-2.06-010-efi-device-tree-fixup-protocol.patch135
1 files changed, 135 insertions, 0 deletions
diff --git a/sys-boot/grub/files/grub-2.06-010-efi-device-tree-fixup-protocol.patch b/sys-boot/grub/files/grub-2.06-010-efi-device-tree-fixup-protocol.patch
new file mode 100644
index 0000000..ee7c122
--- /dev/null
+++ b/sys-boot/grub/files/grub-2.06-010-efi-device-tree-fixup-protocol.patch
@@ -0,0 +1,135 @@
+Device-trees are used to convey information about hardware to the operating
+system. Some of the properties are only known at boot time. (One example of
+such a property is the number of the boot hart on RISC-V systems.) Therefore
+the firmware applies fix-ups to the original device-tree. Some nodes and
+properties are added or altered.
+
+When using GRUB's device-tree command the same fix-ups have to be applied.
+The EFI Device Tree Fixup Protocol allows to pass the loaded device tree
+to the firmware for this purpose.
+
+The protocol can
+
+* add nodes and update properties
+* reserve memory according to the /reserved-memory node and the memory
+ reservation block
+* install the device-tree as configuration table
+
+With the patch GRUB checks if the protocol is installed and invokes it if
+available.
+
+Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
+---
+ grub-core/loader/efi/fdt.c | 35 ++++++++++++++++++++++++++++++++++-
+ include/grub/efi/api.h | 22 ++++++++++++++++++++++
+ 2 files changed, 56 insertions(+), 1 deletion(-)
+
+diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
+index 57ee81686..58e95eb05 100644
+--- a/grub-core/loader/efi/fdt.c
++++ b/grub-core/loader/efi/fdt.c
+@@ -29,6 +29,7 @@
+
+ static void *loaded_fdt;
+ static void *fdt;
++static grub_efi_guid_t dt_fixup_guid = GRUB_EFI_DT_FIXUP_PROTOCOL_GUID;
+
+ #define FDT_ADDR_CELLS_STRING "#address-cells"
+ #define FDT_SIZE_CELLS_STRING "#size-cells"
+@@ -36,6 +37,38 @@ static void *fdt;
+ sizeof (FDT_ADDR_CELLS_STRING) + \
+ sizeof (FDT_SIZE_CELLS_STRING))
+
++static void *grub_fdt_fixup (void)
++{
++ grub_efi_dt_fixup_t *dt_fixup_prot;
++ grub_efi_uintn_t size = 0;
++ grub_efi_status_t status;
++ void *fixup_fdt;
++
++ dt_fixup_prot = grub_efi_locate_protocol (&dt_fixup_guid, 0);
++ if (! dt_fixup_prot)
++ return loaded_fdt;
++
++ grub_dprintf ("linux", "EFI_DT_FIXUP_PROTOCOL available\n");
++
++ status = efi_call_4 (dt_fixup_prot->fixup, dt_fixup_prot, loaded_fdt, &size,
++ GRUB_EFI_DT_APPLY_FIXUPS | GRUB_EFI_DT_RESERVE_MEMORY);
++ if (status != GRUB_EFI_BUFFER_TOO_SMALL)
++ return loaded_fdt;
++
++ fixup_fdt = grub_realloc (loaded_fdt, size);
++ if (!fixup_fdt)
++ return loaded_fdt;
++ loaded_fdt = fixup_fdt;
++
++ status = efi_call_4 (dt_fixup_prot->fixup, dt_fixup_prot, loaded_fdt, &size,
++ GRUB_EFI_DT_APPLY_FIXUPS | GRUB_EFI_DT_RESERVE_MEMORY);
++
++ if (status == GRUB_EFI_SUCCESS)
++ grub_dprintf ("linux", "Device tree fixed up via EFI_DT_FIXUP_PROTOCOL\n");
++
++ return loaded_fdt;
++}
++
+ void *
+ grub_fdt_load (grub_size_t additional_size)
+ {
+@@ -49,7 +82,7 @@ grub_fdt_load (grub_size_t additional_size)
+ }
+
+ if (loaded_fdt)
+- raw_fdt = loaded_fdt;
++ raw_fdt = grub_fdt_fixup();
+ else
+ raw_fdt = grub_efi_get_firmware_fdt();
+
+diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
+index 34109861a..8101df0df 100644
+--- a/include/grub/efi/api.h
++++ b/include/grub/efi/api.h
+@@ -334,6 +334,11 @@
+ { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \
+ }
+
++#define GRUB_EFI_DT_FIXUP_PROTOCOL_GUID \
++ { 0xe617d64c, 0xfe08, 0x46da, \
++ { 0xf4, 0xdc, 0xbb, 0xd5, 0x87, 0x0c, 0x73, 0x00 } \
++ }
++
+ #define GRUB_EFI_VENDOR_APPLE_GUID \
+ { 0x2B0585EB, 0xD8B8, 0x49A9, \
+ { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \
+@@ -1641,6 +1646,13 @@ enum
+ GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST = 0x10,
+ };
+
++enum
++ {
++ GRUB_EFI_DT_APPLY_FIXUPS = 0x01,
++ GRUB_EFI_DT_RESERVE_MEMORY = 0x02,
++ GRUB_EFI_EFI_DT_INSTALL_TABLE = 0x04,
++ };
++
+ struct grub_efi_simple_network
+ {
+ grub_uint64_t revision;
+@@ -1704,6 +1716,16 @@ struct grub_efi_block_io
+ };
+ typedef struct grub_efi_block_io grub_efi_block_io_t;
+
++struct grub_efi_dt_fixup
++{
++ grub_efi_uint64_t revision;
++ grub_efi_status_t (*fixup) (struct grub_efi_dt_fixup *this,
++ void *fdt,
++ grub_efi_uintn_t *buffer_size,
++ grub_uint32_t flags);
++};
++typedef struct grub_efi_dt_fixup grub_efi_dt_fixup_t;
++
+ struct grub_efi_shim_lock_protocol
+ {
+ grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
+--
+2.30.0