get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/813660/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 813660,
    "url": "http://patchwork.ozlabs.org/api/patches/813660/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/20170913220546.19560-16-robdclark@gmail.com/",
    "project": {
        "id": 18,
        "url": "http://patchwork.ozlabs.org/api/projects/18/?format=api",
        "name": "U-Boot",
        "link_name": "uboot",
        "list_id": "u-boot.lists.denx.de",
        "list_email": "u-boot@lists.denx.de",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20170913220546.19560-16-robdclark@gmail.com>",
    "list_archive_url": null,
    "date": "2017-09-13T22:05:38",
    "name": "[U-Boot,v3,15/21] efi_loader: add bootmgr",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "b42e3a69c9ce93cc80854d4db273edd026a0209f",
    "submitter": {
        "id": 18760,
        "url": "http://patchwork.ozlabs.org/api/people/18760/?format=api",
        "name": "Rob Clark",
        "email": "robdclark@gmail.com"
    },
    "delegate": {
        "id": 3400,
        "url": "http://patchwork.ozlabs.org/api/users/3400/?format=api",
        "username": "agraf",
        "first_name": "Alexander",
        "last_name": "Graf",
        "email": "agraf@suse.de"
    },
    "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/20170913220546.19560-16-robdclark@gmail.com/mbox/",
    "series": [
        {
            "id": 2990,
            "url": "http://patchwork.ozlabs.org/api/series/2990/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=2990",
            "date": "2017-09-13T22:05:23",
            "name": "efi_loader: enough UEFI for standard distro boot",
            "version": 3,
            "mbox": "http://patchwork.ozlabs.org/series/2990/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/813660/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/813660/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<u-boot-bounces@lists.denx.de>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org",
        "Authentication-Results": [
            "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=lists.denx.de\n\t(client-ip=81.169.180.215; helo=lists.denx.de;\n\tenvelope-from=u-boot-bounces@lists.denx.de;\n\treceiver=<UNKNOWN>)",
            "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"AuoeOp3V\"; dkim-atps=neutral"
        ],
        "Received": [
            "from lists.denx.de (dione.denx.de [81.169.180.215])\n\tby ozlabs.org (Postfix) with ESMTP id 3xsx3v3W41z9t0F\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 14 Sep 2017 08:22:19 +1000 (AEST)",
            "by lists.denx.de (Postfix, from userid 105)\n\tid 34A5CC22225; Wed, 13 Sep 2017 22:12:29 +0000 (UTC)",
            "from lists.denx.de (localhost [IPv6:::1])\n\tby lists.denx.de (Postfix) with ESMTP id 3ADB0C2260B;\n\tWed, 13 Sep 2017 22:10:52 +0000 (UTC)",
            "by lists.denx.de (Postfix, from userid 105)\n\tid 10941C2258B; Wed, 13 Sep 2017 22:06:43 +0000 (UTC)",
            "from mail-qk0-f170.google.com (mail-qk0-f170.google.com\n\t[209.85.220.170])\n\tby lists.denx.de (Postfix) with ESMTPS id 6BDBDC21F60\n\tfor <u-boot@lists.denx.de>; Wed, 13 Sep 2017 22:06:39 +0000 (UTC)",
            "by mail-qk0-f170.google.com with SMTP id b23so3828005qkg.1\n\tfor <u-boot@lists.denx.de>; Wed, 13 Sep 2017 15:06:39 -0700 (PDT)",
            "from localhost ([2601:184:4780:aac0:25f8:dd96:a084:785a])\n\tby smtp.gmail.com with ESMTPSA id\n\tv17sm10391279qtv.62.2017.09.13.15.06.36\n\t(version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);\n\tWed, 13 Sep 2017 15:06:37 -0700 (PDT)"
        ],
        "X-Spam-Checker-Version": "SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de",
        "X-Spam-Level": "",
        "X-Spam-Status": "No, score=-0.0 required=5.0 tests=FREEMAIL_FROM,\n\tRCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,\n\tT_DKIM_INVALID\n\tautolearn=unavailable autolearn_force=no version=3.4.0",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=rY8MEr4JeuCx8ZpzzWQio3wE30vawbb/Y8pwm0b89rE=;\n\tb=AuoeOp3VTtnRvmY1gVz7Kw84k7sDVGxoKSfQaTkqJatjyPx/LazFztxgIht39JGzpC\n\tZ15cLyMaow9kunWJ2lctz+36vrXMbDMQOKRtob5VGHYB/aamFUtyPrbGGHB5bInVEWWi\n\tE9efqrsHlu7umKj8YKDTxbtC/G7us+yRqYWxktFDtK6jlomVkQK/Dcy1M1kVliNSTBqu\n\tEhgdu4tpQvN0lgIaMrUNo4+BIUckEHqPe5mz2WoAO1Zjxm5RBwMhhDWzfqeeH1adZJu/\n\t7VEIrbRwZ2gd1RPbEIceCd95oHvvuYNkvY6WmcxxpguQIjWu1AoAQajY49Oht5l4+s9U\n\tTXjg==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=rY8MEr4JeuCx8ZpzzWQio3wE30vawbb/Y8pwm0b89rE=;\n\tb=jWffagam3u5ZnNyz3Bmx88IOt4N6zqBa+3CuXbUM4aUTTKQUn8XRr6fwBYCLC9VZ1K\n\tkF2IngKdl8SSoi3LHQ0QVu0fybD2w11M0/SPp1JaxQLghIIFUzuWKrZLK1VeOd5bKPEi\n\tyKBE77JGLZ/XKkEmWeyh15jpI92OA2RpYoxhz4S9bHvUJgU/1uf6NsJJXFy3g/hfIAEk\n\tdpgF6MD/hgRWcmiCxbVDG0Lw90bvf6E9gwD42F4p3ukX4NaLUhVj4n9RtUOiFwr4QnJA\n\t8CMUtviu21YD/IKsEmfgWYO3hBX3DhgmaRql+0uOK3u8klmzQDvIerBIWLl+WqqGX67t\n\tdTUQ==",
        "X-Gm-Message-State": "AHPjjUjLgg9NuINEzHQdksaxkx9Kt9GwuQn7QF2FfwelOtaQBwy8gTVr\n\tXReGChlLWvnWTwsNUXk=",
        "X-Google-Smtp-Source": "AOwi7QBbla5X2VSg0tuF5f4z3Mm+5qMOinkRBNOWRiNv2WwM2NtoDz7AvoJF2khwFdjSOac6/SiaiQ==",
        "X-Received": "by 10.55.155.203 with SMTP id d194mr1638qke.288.1505340397955;\n\tWed, 13 Sep 2017 15:06:37 -0700 (PDT)",
        "From": "Rob Clark <robdclark@gmail.com>",
        "To": "U-Boot Mailing List <u-boot@lists.denx.de>",
        "Date": "Wed, 13 Sep 2017 18:05:38 -0400",
        "Message-Id": "<20170913220546.19560-16-robdclark@gmail.com>",
        "X-Mailer": "git-send-email 2.13.5",
        "In-Reply-To": "<20170913220546.19560-1-robdclark@gmail.com>",
        "References": "<20170913220546.19560-1-robdclark@gmail.com>",
        "Cc": "Heinrich Schuchardt <xypron.glpk@gmx.de>, Peter Jones <pjones@redhat.com>",
        "Subject": "[U-Boot] [PATCH v3 15/21] efi_loader: add bootmgr",
        "X-BeenThere": "u-boot@lists.denx.de",
        "X-Mailman-Version": "2.1.18",
        "Precedence": "list",
        "List-Id": "U-Boot discussion <u-boot.lists.denx.de>",
        "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n\t<mailto:u-boot-request@lists.denx.de?subject=unsubscribe>",
        "List-Archive": "<http://lists.denx.de/pipermail/u-boot/>",
        "List-Post": "<mailto:u-boot@lists.denx.de>",
        "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>",
        "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n\t<mailto:u-boot-request@lists.denx.de?subject=subscribe>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "base64",
        "Errors-To": "u-boot-bounces@lists.denx.de",
        "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>"
    },
    "content": "Similar to a \"real\" UEFI implementation, the bootmgr looks at the\nBootOrder and BootXXXX variables to try to find an EFI payload to load\nand boot.  This is added as a sub-command of bootefi.\n\nThe idea is that the distro bootcmd would first try loading a payload\nvia the bootmgr, and then if that fails (ie. first boot or corrupted\nEFI variables) it would fallback to loading bootaa64.efi.  (Which\nwould then load fallback.efi which would look for \\EFI\\*\\boot.csv and\npopulate BootOrder and BootXXXX based on what it found.)\n\nSigned-off-by: Rob Clark <robdclark@gmail.com>\n---\n cmd/bootefi.c                     |  48 +++++++++-\n include/config_distro_bootcmd.h   |   5 ++\n include/efi_api.h                 |   4 +\n include/efi_loader.h              |   6 ++\n lib/efi_loader/Makefile           |   2 +-\n lib/efi_loader/efi_bootmgr.c      | 180 ++++++++++++++++++++++++++++++++++++++\n lib/efi_loader/efi_boottime.c     |   6 +-\n lib/efi_loader/efi_image_loader.c |   1 +\n 8 files changed, 246 insertions(+), 6 deletions(-)\n create mode 100644 lib/efi_loader/efi_bootmgr.c",
    "diff": "diff --git a/cmd/bootefi.c b/cmd/bootefi.c\nindex d3ae33e25b..fcd8dbafc1 100644\n--- a/cmd/bootefi.c\n+++ b/cmd/bootefi.c\n@@ -219,6 +219,36 @@ exit:\n \treturn ret;\n }\n \n+static int do_bootefi_bootmgr_exec(unsigned long fdt_addr)\n+{\n+\tstruct efi_device_path *device_path, *file_path;\n+\tvoid *addr;\n+\tefi_status_t r;\n+\n+\t/* Initialize and populate EFI object list */\n+\tif (!efi_obj_list_initalized)\n+\t\tefi_init_obj_list();\n+\n+\t/*\n+\t * gd lives in a fixed register which may get clobbered while we execute\n+\t * the payload. So save it here and restore it on every callback entry\n+\t */\n+\tefi_save_gd();\n+\n+\taddr = efi_bootmgr_load(&device_path, &file_path);\n+\tif (!addr)\n+\t\treturn 1;\n+\n+\tprintf(\"## Starting EFI application at %p ...\\n\", addr);\n+\tr = do_bootefi_exec(addr, (void *)fdt_addr, device_path, file_path);\n+\tprintf(\"## Application terminated, r = %lu\\n\",\n+\t       r & ~EFI_ERROR_MASK);\n+\n+\tif (r != EFI_SUCCESS)\n+\t\treturn 1;\n+\n+\treturn 0;\n+}\n \n /* Interpreter command to boot an arbitrary EFI image from memory */\n static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])\n@@ -237,7 +267,14 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])\n \t\tmemcpy((char *)addr, __efi_hello_world_begin, size);\n \t} else\n #endif\n-\t{\n+\tif (!strcmp(argv[1], \"bootmgr\")) {\n+\t\tunsigned long fdt_addr = 0;\n+\n+\t\tif (argc > 2)\n+\t\t\tfdt_addr = simple_strtoul(argv[2], NULL, 16);\n+\n+\t\treturn do_bootefi_bootmgr_exec(fdt_addr);\n+\t} else {\n \t\tsaddr = argv[1];\n \n \t\taddr = simple_strtoul(saddr, NULL, 16);\n@@ -270,7 +307,11 @@ static char bootefi_help_text[] =\n \t\"hello\\n\"\n \t\"  - boot a sample Hello World application stored within U-Boot\"\n #endif\n-\t;\n+\t\"bootmgr [fdt addr]\\n\"\n+\t\"  - load and boot EFI payload based on BootOrder/BootXXXX variables.\\n\"\n+\t\"\\n\"\n+\t\"    If specified, the device tree located at <fdt address> gets\\n\"\n+\t\"    exposed as EFI configuration table.\\n\";\n #endif\n \n U_BOOT_CMD(\n@@ -308,6 +349,9 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path)\n #endif\n \t}\n \n+\tif (!path)\n+\t\treturn;\n+\n \tif (strcmp(dev, \"Net\")) {\n \t\t/* Add leading / to fs paths, because they're absolute */\n \t\tsnprintf(filename, sizeof(filename), \"/%s\", path);\ndiff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h\nindex 9ed6b9892c..e0d0034ed3 100644\n--- a/include/config_distro_bootcmd.h\n+++ b/include/config_distro_bootcmd.h\n@@ -112,6 +112,11 @@\n \n #define BOOTENV_SHARED_EFI                                                \\\n \t\"boot_efi_binary=\"                                                \\\n+\t\t\"if fdt addr ${fdt_addr_r}; then \"                        \\\n+\t\t\t\"bootefi bootmgr ${fdt_addr_r};\"                  \\\n+\t\t\"else \"                                                   \\\n+\t\t\t\"bootefi bootmgr ${fdtcontroladdr};\"              \\\n+\t\t\"fi;\"                                                     \\\n \t\t\"load ${devtype} ${devnum}:${distro_bootpart} \"           \\\n \t\t\t\"${kernel_addr_r} efi/boot/\"BOOTEFI_NAME\"; \"      \\\n \t\t\"if fdt addr ${fdt_addr_r}; then \"                        \\\ndiff --git a/include/efi_api.h b/include/efi_api.h\nindex 1aae96355f..d0aefa8221 100644\n--- a/include/efi_api.h\n+++ b/include/efi_api.h\n@@ -211,6 +211,10 @@ struct efi_runtime_services {\n \tEFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, \\\n \t\t 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)\n \n+#define EFI_GLOBAL_VARIABLE_GUID \\\n+\tEFI_GUID(0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, \\\n+\t\t 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c)\n+\n #define LOADED_IMAGE_PROTOCOL_GUID \\\n \tEFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, \\\n \t\t 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)\ndiff --git a/include/efi_loader.h b/include/efi_loader.h\nindex 9eee62dc9c..adc0bcf609 100644\n--- a/include/efi_loader.h\n+++ b/include/efi_loader.h\n@@ -61,6 +61,7 @@ extern const struct efi_device_path_to_text_protocol efi_device_path_to_text;\n \n uint16_t *efi_dp_str(struct efi_device_path *dp);\n \n+extern const efi_guid_t efi_global_variable_guid;\n extern const efi_guid_t efi_guid_console_control;\n extern const efi_guid_t efi_guid_device_path;\n extern const efi_guid_t efi_guid_loaded_image;\n@@ -209,6 +210,8 @@ efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table\n void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *obj,\n \t\t\t    struct efi_device_path *device_path,\n \t\t\t    struct efi_device_path *file_path);\n+efi_status_t efi_load_image_from_path(struct efi_device_path *file_path,\n+\t\t\t\t      void **buffer);\n \n #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER\n extern void *efi_bounce_buffer;\n@@ -287,6 +290,9 @@ efi_status_t EFIAPI efi_set_variable(s16 *variable_name,\n \t\tefi_guid_t *vendor, u32 attributes,\n \t\tunsigned long data_size, void *data);\n \n+void *efi_bootmgr_load(struct efi_device_path **device_path,\n+\t\t       struct efi_device_path **file_path);\n+\n #else /* defined(EFI_LOADER) && !defined(CONFIG_SPL_BUILD) */\n \n /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */\ndiff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile\nindex f58cb13337..930c0e218e 100644\n--- a/lib/efi_loader/Makefile\n+++ b/lib/efi_loader/Makefile\n@@ -16,7 +16,7 @@ always := $(efiprogs-y)\n obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o\n obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o\n obj-y += efi_memory.o efi_device_path_to_text.o efi_device_path.o\n-obj-y += efi_file.o efi_variable.o\n+obj-y += efi_file.o efi_variable.o efi_bootmgr.o\n obj-$(CONFIG_LCD) += efi_gop.o\n obj-$(CONFIG_DM_VIDEO) += efi_gop.o\n obj-$(CONFIG_PARTITIONS) += efi_disk.o\ndiff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c\nnew file mode 100644\nindex 0000000000..857d88a879\n--- /dev/null\n+++ b/lib/efi_loader/efi_bootmgr.c\n@@ -0,0 +1,180 @@\n+/*\n+ *  EFI utils\n+ *\n+ *  Copyright (c) 2017 Rob Clark\n+ *\n+ *  SPDX-License-Identifier:     GPL-2.0+\n+ */\n+\n+#include <common.h>\n+#include <charset.h>\n+#include <malloc.h>\n+#include <efi_loader.h>\n+\n+static const struct efi_boot_services *bs;\n+static const struct efi_runtime_services *rs;\n+\n+#define LOAD_OPTION_ACTIVE\t\t0x00000001\n+#define LOAD_OPTION_FORCE_RECONNECT\t0x00000002\n+#define LOAD_OPTION_HIDDEN\t\t0x00000008\n+\n+/*\n+ * bootmgr implements the logic of trying to find a payload to boot\n+ * based on the BootOrder + BootXXXX variables, and then loading it.\n+ *\n+ * TODO detecting a special key held (f9?) and displaying a boot menu\n+ * like you would get on a PC would be clever.\n+ *\n+ * TODO if we had a way to write and persist variables after the OS\n+ * has started, we'd also want to check OsIndications to see if we\n+ * should do normal or recovery boot.\n+ */\n+\n+\n+/*\n+ * See section 3.1.3 in the v2.7 UEFI spec for more details on\n+ * the layout of EFI_LOAD_OPTION.  In short it is:\n+ *\n+ *    typedef struct _EFI_LOAD_OPTION {\n+ *        UINT32 Attributes;\n+ *        UINT16 FilePathListLength;\n+ *        // CHAR16 Description[];   <-- variable length, NULL terminated\n+ *        // EFI_DEVICE_PATH_PROTOCOL FilePathList[];  <-- FilePathListLength bytes\n+ *        // UINT8 OptionalData[];\n+ *    } EFI_LOAD_OPTION;\n+ */\n+struct load_option {\n+\tu32 attributes;\n+\tu16 file_path_length;\n+\tu16 *label;\n+\tstruct efi_device_path *file_path;\n+\tu8 *optional_data;\n+};\n+\n+/* parse an EFI_LOAD_OPTION, as described above */\n+static void parse_load_option(struct load_option *lo, void *ptr)\n+{\n+\tlo->attributes = *(u32 *)ptr;\n+\tptr += sizeof(u32);\n+\n+\tlo->file_path_length = *(u16 *)ptr;\n+\tptr += sizeof(u16);\n+\n+\tlo->label = ptr;\n+\tptr += (utf16_strlen(lo->label) + 1) * 2;\n+\n+\tlo->file_path = ptr;\n+\tptr += lo->file_path_length;\n+\n+\tlo->optional_data = ptr;\n+}\n+\n+/* free() the result */\n+static void *get_var(u16 *name, const efi_guid_t *vendor,\n+\t\t     unsigned long *size)\n+{\n+\tefi_guid_t *v = (efi_guid_t *)vendor;\n+\tefi_status_t ret;\n+\tvoid *buf = NULL;\n+\n+\t*size = 0;\n+\tEFI_CALL(ret = rs->get_variable((s16 *)name, v, NULL, size, buf));\n+\tif (ret == EFI_BUFFER_TOO_SMALL) {\n+\t\tbuf = malloc(*size);\n+\t\tEFI_CALL(ret = rs->get_variable((s16 *)name, v, NULL, size, buf));\n+\t}\n+\n+\tif (ret != EFI_SUCCESS) {\n+\t\tfree(buf);\n+\t\t*size = 0;\n+\t\treturn NULL;\n+\t}\n+\n+\treturn buf;\n+}\n+\n+/*\n+ * Attempt to load load-option number 'n', returning device_path and file_path\n+ * if successful.  This checks that the EFI_LOAD_OPTION is active (enabled)\n+ * and that the specified file to boot exists.\n+ */\n+static void *try_load_entry(uint16_t n, struct efi_device_path **device_path,\n+\t\t\t    struct efi_device_path **file_path)\n+{\n+\tstruct load_option lo;\n+\tu16 varname[] = L\"Boot0000\";\n+\tu16 hexmap[] = L\"0123456789ABCDEF\";\n+\tvoid *load_option, *image = NULL;\n+\tunsigned long size;\n+\n+\tvarname[4] = hexmap[(n & 0xf000) >> 12];\n+\tvarname[5] = hexmap[(n & 0x0f00) >> 8];\n+\tvarname[6] = hexmap[(n & 0x00f0) >> 4];\n+\tvarname[7] = hexmap[(n & 0x000f) >> 0];\n+\n+\tload_option = get_var(varname, &efi_global_variable_guid, &size);\n+\tif (!load_option)\n+\t\treturn NULL;\n+\n+\tparse_load_option(&lo, load_option);\n+\n+\tif (lo.attributes & LOAD_OPTION_ACTIVE) {\n+\t\tefi_status_t ret;\n+\t\tu16 *str = NULL;\n+\n+\t\tdebug(\"%s: trying to load \\\"%ls\\\" from: %ls\\n\", __func__,\n+\t\t      lo.label, (str = efi_dp_str(lo.file_path)));\n+\t\tefi_free_pool(str);\n+\n+\t\tret = efi_load_image_from_path(lo.file_path, &image);\n+\n+\t\tif (ret != EFI_SUCCESS)\n+\t\t\tgoto error;\n+\n+\t\tprintf(\"Booting: %ls\\n\", lo.label);\n+\t\tefi_dp_split_file_path(lo.file_path, device_path, file_path);\n+\t}\n+\n+error:\n+\tfree(load_option);\n+\n+\treturn image;\n+}\n+\n+/*\n+ * Attempt to load, in the order specified by BootOrder EFI variable, the\n+ * available load-options, finding and returning the first one that can\n+ * be loaded successfully.\n+ */\n+void *efi_bootmgr_load(struct efi_device_path **device_path,\n+\t\t       struct efi_device_path **file_path)\n+{\n+\tuint16_t *bootorder;\n+\tunsigned long size;\n+\tvoid *image = NULL;\n+\tint i, num;\n+\n+\t__efi_entry_check();\n+\n+\tbs = systab.boottime;\n+\trs = systab.runtime;\n+\n+\tbootorder = get_var(L\"BootOrder\", &efi_global_variable_guid, &size);\n+\tif (!bootorder)\n+\t\tgoto error;\n+\n+\tnum = size / sizeof(uint16_t);\n+\tfor (i = 0; i < num; i++) {\n+\t\tdebug(\"%s: trying to load Boot%04X\\n\", __func__, bootorder[i]);\n+\t\timage = try_load_entry(bootorder[i], device_path, file_path);\n+\t\tif (image)\n+\t\t\tbreak;\n+\t}\n+\n+\tfree(bootorder);\n+\n+error:\n+\t__efi_exit_check();\n+\n+\treturn image;\n+}\ndiff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c\nindex c406ff82ff..cea242cd49 100644\n--- a/lib/efi_loader/efi_boottime.c\n+++ b/lib/efi_loader/efi_boottime.c\n@@ -763,8 +763,8 @@ void efi_setup_loaded_image(struct efi_loaded_image *info, struct efi_object *ob\n \tlist_add_tail(&obj->link, &efi_obj_list);\n }\n \n-static efi_status_t load_image_from_path(struct efi_device_path *file_path,\n-\t\t\t\t\t void **buffer)\n+efi_status_t efi_load_image_from_path(struct efi_device_path *file_path,\n+\t\t\t\t      void **buffer)\n {\n \tstruct efi_file_info *info = NULL;\n \tstruct efi_file_handle *f;\n@@ -824,7 +824,7 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy,\n \t\tstruct efi_device_path *dp, *fp;\n \t\tefi_status_t ret;\n \n-\t\tret = load_image_from_path(file_path, &source_buffer);\n+\t\tret = efi_load_image_from_path(file_path, &source_buffer);\n \t\tif (ret != EFI_SUCCESS) {\n \t\t\tfree(info);\n \t\t\tfree(obj);\ndiff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c\nindex 469acae082..242e6a504b 100644\n--- a/lib/efi_loader/efi_image_loader.c\n+++ b/lib/efi_loader/efi_image_loader.c\n@@ -15,6 +15,7 @@\n \n DECLARE_GLOBAL_DATA_PTR;\n \n+const efi_guid_t efi_global_variable_guid = EFI_GLOBAL_VARIABLE_GUID;\n const efi_guid_t efi_guid_device_path = DEVICE_PATH_GUID;\n const efi_guid_t efi_guid_loaded_image = LOADED_IMAGE_GUID;\n const efi_guid_t efi_simple_file_system_protocol_guid =\n",
    "prefixes": [
        "U-Boot",
        "v3",
        "15/21"
    ]
}