static void *loaded_fdt;
static void *fdt;
+static grub_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"
sizeof (FDT_ADDR_CELLS_STRING) + \
sizeof (FDT_SIZE_CELLS_STRING))
+static void *
+grub_fdt_fixup (void *blob)
+{
+ 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 blob;
+
+ grub_dprintf ("linux", "EFI_DT_FIXUP_PROTOCOL available\n");
+
+ status = dt_fixup_prot->fixup (dt_fixup_prot, blob, &size,
+ GRUB_EFI_DT_APPLY_FIXUPS
+ | GRUB_EFI_DT_RESERVE_MEMORY);
+ if (status != GRUB_EFI_BUFFER_TOO_SMALL)
+ return blob;
+
+ fixup_fdt = grub_realloc (blob, size);
+ if (!fixup_fdt)
+ return blob;
+ blob = fixup_fdt;
+
+ status = dt_fixup_prot->fixup (dt_fixup_prot, blob, &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 blob;
+}
+
void *
grub_fdt_load (grub_size_t additional_size)
{
if (blob)
{
grub_dprintf ("fdt", "Device-tree %s loaded\n", argv[0]);
+ blob = grub_fdt_fixup (blob);
if (grub_errno == GRUB_ERR_NONE)
loaded_fdt = blob;
else
{ 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 } \
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;
};
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 (__grub_efi_api *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
{
/*