--- grub-core/loader/arm64/linux.c | 70 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-)
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c index 75ad871..17938ba 100644 --- a/grub-core/loader/arm64/linux.c +++ b/grub-core/loader/arm64/linux.c @@ -54,6 +54,8 @@ static grub_addr_t initrd_end; static void *loaded_fdt; static void *fdt;
+static void *apei_data; + static void * get_firmware_fdt (void) { @@ -241,6 +243,69 @@ out: }
static grub_err_t +grub_cmd_apei (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_efi_physical_address_t apei_phy_addr; + grub_efi_boot_services_t *b; + grub_efi_status_t status; + grub_file_t apei; + void *blob = NULL; + int size; + + if (!loaded) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("you need to load the kernel first")); + return GRUB_ERR_BAD_OS; + } + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + + apei = grub_file_open (argv[0]); + if (!apei) + goto out; + + size = grub_file_size (apei); + if (size == 0) + goto out; + + blob = grub_malloc (size); + if (!blob) + goto out; + + if (grub_file_read (apei, blob, size) < size) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); + goto out; + } + + grub_dprintf ("linux", "allocating %ld bytes for APEI blob\n", size); + apei_phy_addr = 0x80000000 + 0x2000000 - 0x200000; + apei_data = grub_efi_allocate_pages (apei_phy_addr, BYTES_TO_PAGES(size)); + if (!apei_data) { + grub_error (GRUB_ERR_OUT_OF_MEMORY, + N_("can not allocate at 0x%lx"), apei_phy_addr); + goto out; + } + + grub_memmove (apei_data, blob, size); + + grub_dprintf ("linux", "Installed APEI blob @ %p\n", apei_data); + +out: + if (apei) + grub_file_close (apei); + + if (blob) + grub_free (blob); + + return grub_errno; +} + +static grub_err_t grub_linux_boot (void) { grub_efi_memory_mapped_device_path_t *mempath; @@ -465,7 +530,7 @@ fail: }
-static grub_command_t cmd_linux, cmd_initrd, cmd_devicetree; +static grub_command_t cmd_linux, cmd_initrd, cmd_devicetree, cmd_apei;
GRUB_MOD_INIT (linux) { @@ -476,6 +541,9 @@ GRUB_MOD_INIT (linux) cmd_devicetree = grub_register_command ("devicetree", grub_cmd_devicetree, 0, N_("Load DTB file.")); + + cmd_apei = grub_register_command ("apei", grub_cmd_apei, 0, + N_("Load APEI blob.")); my_mod = mod; }