]> git.sur5r.net Git - u-boot/blobdiff - cmd/bootefi.c
ARM: image: Add option for ignoring ep bit 3
[u-boot] / cmd / bootefi.c
index 2a31a914cdb3be29e4d5b411cc5d178958c093f9..f55a40dc84cd05dc2f3cbb39583f9c70f7e5a68c 100644 (file)
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  *  EFI application loader
  *
  *  Copyright (c) 2016 Alexander Graf
- *
- *  SPDX-License-Identifier:     GPL-2.0+
  */
 
 #include <charset.h>
@@ -18,6 +17,7 @@
 #include <memalign.h>
 #include <asm/global_data.h>
 #include <asm-generic/sections.h>
+#include <asm-generic/unaligned.h>
 #include <linux/linkage.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -56,7 +56,7 @@ efi_status_t efi_init_obj_list(void)
        if (ret != EFI_SUCCESS)
                goto out;
 #endif
-#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_NET
        ret = efi_net_register();
        if (ret != EFI_SUCCESS)
                goto out;
@@ -83,6 +83,15 @@ out:
        return ret;
 }
 
+/*
+ * Allow unaligned memory access.
+ *
+ * This routine is overridden by architectures providing this feature.
+ */
+void __weak allow_unaligned(void)
+{
+}
+
 /*
  * Set the load options of an image from an environment variable.
  *
@@ -134,11 +143,13 @@ static void *copy_fdt(void *fdt)
 
        /* Safe fdt location is at 128MB */
        new_fdt_addr = fdt_ram_start + (128 * 1024 * 1024) + fdt_size;
-       if (efi_allocate_pages(1, EFI_RUNTIME_SERVICES_DATA, fdt_pages,
+       if (efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
+                              EFI_RUNTIME_SERVICES_DATA, fdt_pages,
                               &new_fdt_addr) != EFI_SUCCESS) {
                /* If we can't put it there, put it somewhere */
                new_fdt_addr = (ulong)memalign(EFI_PAGE_SIZE, fdt_size);
-               if (efi_allocate_pages(1, EFI_RUNTIME_SERVICES_DATA, fdt_pages,
+               if (efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
+                                      EFI_RUNTIME_SERVICES_DATA, fdt_pages,
                                       &new_fdt_addr) != EFI_SUCCESS) {
                        printf("ERROR: Failed to reserve space for FDT\n");
                        return NULL;
@@ -178,6 +189,27 @@ static efi_status_t efi_run_in_el2(EFIAPI efi_status_t (*entry)(
 }
 #endif
 
+/* Carve out DT reserved memory ranges */
+static efi_status_t efi_carve_out_dt_rsv(void *fdt)
+{
+       int nr_rsv, i;
+       uint64_t addr, size, pages;
+
+       nr_rsv = fdt_num_mem_rsv(fdt);
+
+       /* Look for an existing entry and add it to the efi mem map. */
+       for (i = 0; i < nr_rsv; i++) {
+               if (fdt_get_mem_rsv(fdt, i, &addr, &size) != 0)
+                       continue;
+
+               pages = ALIGN(size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT;
+               efi_add_memory_map(addr, pages, EFI_RESERVED_MEMORY_TYPE,
+                                  false);
+       }
+
+       return EFI_SUCCESS;
+}
+
 static efi_status_t efi_install_fdt(void *fdt)
 {
        bootm_headers_t img = { 0 };
@@ -199,6 +231,11 @@ static efi_status_t efi_install_fdt(void *fdt)
                return EFI_LOAD_ERROR;
        }
 
+       if (efi_carve_out_dt_rsv(fdt) != EFI_SUCCESS) {
+               printf("ERROR: failed to carve out memory\n");
+               return EFI_LOAD_ERROR;
+       }
+
        /* Link to it in the efi tables */
        ret = efi_install_configuration_table(&efi_guid_fdt, fdt);
        if (ret != EFI_SUCCESS)
@@ -226,6 +263,7 @@ static efi_status_t do_bootefi_exec(void *efi,
 {
        struct efi_loaded_image loaded_image_info = {};
        struct efi_object loaded_image_info_obj = {};
+       struct efi_object mem_obj = {};
        struct efi_device_path *memdp = NULL;
        efi_status_t ret;
 
@@ -242,6 +280,12 @@ static efi_status_t do_bootefi_exec(void *efi,
                /* actual addresses filled in after efi_load_pe() */
                memdp = efi_dp_from_mem(0, 0, 0);
                device_path = image_path = memdp;
+               efi_add_handle(&mem_obj);
+
+               ret = efi_add_protocol(mem_obj.handle, &efi_guid_device_path,
+                                      device_path);
+               if (ret != EFI_SUCCESS)
+                       goto exit;
        } else {
                assert(device_path && image_path);
        }
@@ -306,6 +350,8 @@ static efi_status_t do_bootefi_exec(void *efi,
 exit:
        /* image has returned, loaded-image obj goes *poof*: */
        list_del(&loaded_image_info_obj.link);
+       if (mem_obj.handle)
+               list_del(&mem_obj.link);
 
        return ret;
 }
@@ -345,6 +391,9 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        efi_status_t r;
        void *fdt_addr;
 
+       /* Allow unaligned memory access */
+       allow_unaligned();
+
        /* Initialize EFI drivers */
        r = efi_init_obj_list();
        if (r != EFI_SUCCESS) {
@@ -403,8 +452,6 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                 * callback entry
                 */
                efi_save_gd();
-               /* Initialize and populate EFI object list */
-               efi_init_obj_list();
                /* Transfer environment variable efi_selftest as load options */
                set_load_options(&loaded_image_info, "efi_selftest");
                /* Execute the test */
@@ -485,7 +532,7 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path)
 
                bootefi_device_path = efi_dp_from_part(desc, part);
        } else {
-#ifdef CONFIG_CMD_NET
+#ifdef CONFIG_NET
                bootefi_device_path = efi_dp_from_eth();
 #endif
        }