From patchwork Fri Jul 15 14:27:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 590835 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:5817:0:0:0:0 with SMTP id j23csp551353max; Fri, 15 Jul 2022 07:25:19 -0700 (PDT) X-Google-Smtp-Source: AGRyM1vyXFNBTB70F+Ht2ubdhHF5Dz2+lo7tK7T7vq39BxP+gvuHKb2++l8ZuuriAHSQmRqTHPQb X-Received: by 2002:a05:6638:12c8:b0:33f:c6f4:4680 with SMTP id v8-20020a05663812c800b0033fc6f44680mr5588173jas.267.1657895119805; Fri, 15 Jul 2022 07:25:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657895119; cv=none; d=google.com; s=arc-20160816; b=T4n+qs918pkHQHZj27gOmjY1RV6RZ/2Ox9ytchZAJ6HuY1+4Lvn7wSitL7EtpmdzJh eYx3YSv2pdooJsstMDm2y9e3O3aiyMRRuZXSRuKXW35s7K1acEzo73c8BCKb++Zu0yrG PBgXIwAskDfKSmPXMEhy324CwONEmL9+3lgTImAMFdgLP/25TTqYr7h5F2VYpBBYWqLV zCTfwIY4qwdUyN/DRXYo9fMFJTJz1Z0tF55z6qJBJNsEL/vojFBrSldqWMH6weoOr/Mj nH1yzF8to29axDXN+GmuJ0Q4a8X1DXDVvxXz1y+bzQK9Q5ZwkNg9sDjZfHBJ3QXZDIIE +BRA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=XDIyGQEMuuWcA12ZFBDN6dJBAyexu/pWj0+yvfXHVJI=; b=bADVhoMyeg7g3e6y9XKn45gdUJP16VkHXi+d4V8CDetf6N1N1mhCijzz5Lqpm5WVKn Rcik8FiaJv1kxUd9KUNcvZ/yUWXBMP+7rn4sSleNwlcMbfHOtSM3udS61Ay946e0qxwD f5nG7RLvJDLQnOVkdO3czR2Fm52/xapMAjoas03N9Gkry4eANCoFPk/vPhc+uQqXkDfb UCpTn6K93yw3zHUqFxZCuiIC8DTIL+7LPH7bCmKagfxscMlwtAyep+odqIVtVZ+pxmBw E6qxnB9uaciTQKhyuNfGiFzbiqmMJA1fnFHIl8mkvQO5aHip1/uQEYZ1hgvzw52aGcdV g3nA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Nif7paM1; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id x11-20020a056602160b00b0067ba8c5c434si5409913iow.50.2022.07.15.07.25.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:25:19 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Nif7paM1; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5C47981100; Fri, 15 Jul 2022 16:25:05 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Nif7paM1"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 670DB80909; Fri, 15 Jul 2022 16:25:02 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x433.google.com (mail-pf1-x433.google.com [IPv6:2607:f8b0:4864:20::433]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 0903E80C75 for ; Fri, 15 Jul 2022 16:24:58 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pf1-x433.google.com with SMTP id d10so4782213pfd.9 for ; Fri, 15 Jul 2022 07:24:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=XDIyGQEMuuWcA12ZFBDN6dJBAyexu/pWj0+yvfXHVJI=; b=Nif7paM1bEczt4ctYamDgueoG3+vEtnMBqoJd7iq0blyNY2Mpjt7/bx9rqGgmZNbFc X3XQjtc6fnYF+2TreKFtgPlYLk4f1jk6s2vopv3PlASXSURvpNkCCzeoEjNLktfMowKs ilkeKkv4oSc03Lziq6JSwcZjCikGUUjKaGw5AcFbQ5lT+pKsPBVdmwYe4CipQXo9fBFm BVLGWobUUvARCKgNriKEkSpk9Ps6+KhKYZDAPoqFNKjzORuJhoRKTl7vJDbwM/LOsFTO LixHLrjBW7k1RDI8GjgiCgZ7TTRhYg61GwcYfSZgpeUpJt99JCtIz5lx3KmQguv5XPu3 6kHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=XDIyGQEMuuWcA12ZFBDN6dJBAyexu/pWj0+yvfXHVJI=; b=PGPjwRn5itv+5A2nizQD1Laccm9UayUAzRfapEUW9sZFpe7IVXCs9r5/KJaQq2Mz+y FhTpJ13LAMAF//Ny9yoXhc6P3TyRuY1g9lmez18dHLiZlDo8870VZg0NXx5DZlL33MST OPJTlXEHTAmybcVWcn4wRrLgmI8JSK4UcT17KiZt7bKDRiRis4rWE51qNhJRbRW+wH6W xe1bc3AGU/Co3Bn4T0PLZKe32VMxKKAW36zEK9P8NuZRy062xqBT/tTYEdDvlAJ8bepC Fcgfits2X35vlGXK0p6DDehPwt4oTu3pL3w2iNAhB1CPqBwGoCELlm4BhdSH3CdtvQzZ bewg== X-Gm-Message-State: AJIora+XvhJG1smUiGxMx4Zj3OWcK8D+xcnqmVEiE7sp8L69rHpE6ieR FsDQH2aUFGYbQNPSgazwCIaLi8kIaPum2g== X-Received: by 2002:a62:6506:0:b0:52b:15cb:8ea9 with SMTP id z6-20020a626506000000b0052b15cb8ea9mr11826538pfb.57.1657895096124; Fri, 15 Jul 2022 07:24:56 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id d22-20020aa797b6000000b0051c49fb62b7sm3891174pfq.165.2022.07.15.07.24.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:24:55 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Mark Kettenis , Masahisa Kojima Subject: [PATCH 1/9] efi_loader: move udevice pointer into struct efi_object Date: Fri, 15 Jul 2022 23:27:35 +0900 Message-Id: <20220715142743.30137-2-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220715142743.30137-1-masahisa.kojima@linaro.org> References: <20220715142743.30137-1-masahisa.kojima@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean This is a preparation patch to provide the unified method to access udevice pointer associated with the block io device. The EFI handles of both EFI block io driver implemented in lib/efi_loader/efi_disk.c and EFI block io driver implemented as EFI payload can posess the udevice pointer in the struct efi_object. We can use this udevice pointer to get the U-Boot friendly block device name(e.g. mmc 0:1, nvme 0:1) through efi_handle_t. Signed-off-by: Masahisa Kojima --- Newly created in v9 include/efi_loader.h | 8 ++++++++ lib/efi_loader/efi_disk.c | 20 +++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index 3a63a1f75f..bba5ffd482 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -226,6 +226,12 @@ const char *__efi_nesting_dec(void); #define EFI_CACHELINE_SIZE 128 #endif +/** + * efi_handle_to_udev - accessor to the DM device associated to the EFI handle + * @handle: pointer to the EFI handle + */ +#define efi_handle_to_udev(handle) (((struct efi_object *)handle)->dev) + /* Key identifying current memory map */ extern efi_uintn_t efi_memory_map_key; @@ -375,6 +381,7 @@ enum efi_object_type { * @protocols: linked list with the protocol interfaces installed on this * handle * @type: image type if the handle relates to an image + * @dev: pointer to the DM device which is associated with this EFI handle * * UEFI offers a flexible and expandable object model. The objects in the UEFI * API are devices, drivers, and loaded images. struct efi_object is our storage @@ -392,6 +399,7 @@ struct efi_object { /* The list of protocols */ struct list_head protocols; enum efi_object_type type; + struct udevice *dev; }; enum efi_image_auth_status { diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 1d700b2a6b..a8e8521e3e 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -46,7 +46,6 @@ struct efi_disk_obj { struct efi_device_path *dp; unsigned int part; struct efi_simple_file_system_protocol *volume; - struct udevice *dev; /* TODO: move it to efi_object */ }; /** @@ -124,16 +123,16 @@ static efi_status_t efi_disk_rw_blocks(struct efi_block_io *this, return EFI_BAD_BUFFER_SIZE; if (CONFIG_IS_ENABLED(PARTITIONS) && - device_get_uclass_id(diskobj->dev) == UCLASS_PARTITION) { + device_get_uclass_id(efi_handle_to_udev(diskobj)) == UCLASS_PARTITION) { if (direction == EFI_DISK_READ) - n = dev_read(diskobj->dev, lba, blocks, buffer); + n = dev_read(efi_handle_to_udev(diskobj), lba, blocks, buffer); else - n = dev_write(diskobj->dev, lba, blocks, buffer); + n = dev_write(efi_handle_to_udev(diskobj), lba, blocks, buffer); } else { /* dev is a block device (UCLASS_BLK) */ struct blk_desc *desc; - desc = dev_get_uclass_plat(diskobj->dev); + desc = dev_get_uclass_plat(efi_handle_to_udev(diskobj)); if (direction == EFI_DISK_READ) n = blk_dread(desc, lba, blocks, buffer); else @@ -552,7 +551,7 @@ static int efi_disk_create_raw(struct udevice *dev) return -1; } - disk->dev = dev; + efi_handle_to_udev(disk) = dev; if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) { efi_free_pool(disk->dp); efi_delete_handle(&disk->header); @@ -609,7 +608,7 @@ static int efi_disk_create_part(struct udevice *dev) log_err("Adding partition for %s failed\n", dev->name); return -1; } - disk->dev = dev; + efi_handle_to_udev(disk) = dev; if (dev_tag_set_ptr(dev, DM_TAG_EFI, &disk->header)) { efi_free_pool(disk->dp); efi_delete_handle(&disk->header); @@ -656,6 +655,13 @@ static int efi_disk_probe(void *ctx, struct event *event) ret = efi_disk_create_raw(dev); if (ret) return -1; + } else { + efi_handle_t handle; + + if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)&handle)) + return -1; + + efi_handle_to_udev(handle) = dev; } device_foreach_child(child, dev) { From patchwork Fri Jul 15 14:27:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 590839 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:5817:0:0:0:0 with SMTP id j23csp552095max; Fri, 15 Jul 2022 07:26:09 -0700 (PDT) X-Google-Smtp-Source: AGRyM1sF8v2Ci3wmPzw77i1BTVLkTr4EA1c5n5L+FcnMN9WYPQ1gfowhIhJhlvP6g2ISO1PNjYGu X-Received: by 2002:a05:6e02:1cab:b0:2dc:9e83:6a1 with SMTP id x11-20020a056e021cab00b002dc9e8306a1mr7579602ill.31.1657895169814; Fri, 15 Jul 2022 07:26:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657895169; cv=none; d=google.com; s=arc-20160816; b=mMe0S84PmMyTO1YIHcLraxqk2QxVNzNLIDq2COGPuiMT/27EwoARgc4/hVRktn+E2O L7bmdZv4TBmL6yx6kBG/jyrha992kK77XNxW7a6MCNy3R/XF2uiQClqVrQe+/iGHCZei JggQk1280PkIlVCyvAM+8fkgzcOX+DCadXQS2MN7mSCIJ8SyMyDPJPNl0i/1QCUVvTMU rFURH8U/IvhFGFuivb67ADs4rUmrJuAB9z9n92sRnNj6QqwKlaI/hX+frDQrYu7pa/fb Tsl2tSxnrGJY8e4iLJ0KlVhcW+7oaJ9bO5e0bwSJ9ukwbjl2e7VrDoPxZLMhDbeCUEtH APpQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=fzrOpJIqSuJ6kjPceRcazRx9VKTkQZD5jq71D6RPg+g=; b=RWSxPDG3spCL2mDCb+N1Oz1rjXW2PWMt/ooGhNI9uHV3fHc4Yc4Mpo6EDo9h/as+ig Nm2/fqkzm5J+nSE6oBv7XtQMraCzuHUVwjXZF/gs2jkGe0SQSgsyVHyqQZVdc8NLKU6C DFMmod32qN7Yum70prtuoXhCRab4IKFKIlxVt04+UO+BhmesshfBCjLDZEXxXVCFAsGX wysQ5qvKFrgOre2ptjWN3VGNK13h5Z9TI6Y9kF3+zdQ3Y89dWjyNcPBG1Mamh9uEzuZB peAWGqddG8g1nhXsIE5rXYGgm0I79BC04C290s6tkkI5jlvKSYLe76yaGPl2y3Z6iZhO M47A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=A14LnCD2; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id h15-20020a92d08f000000b002dc941cd504si4261454ilh.176.2022.07.15.07.26.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:26:09 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=A14LnCD2; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 250DE820AA; Fri, 15 Jul 2022 16:25:31 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="A14LnCD2"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id F330781E51; Fri, 15 Jul 2022 16:25:23 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id E137D8118A for ; Fri, 15 Jul 2022 16:25:08 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pj1-x1034.google.com with SMTP id t5-20020a17090a6a0500b001ef965b262eso6215154pjj.5 for ; Fri, 15 Jul 2022 07:25:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=fzrOpJIqSuJ6kjPceRcazRx9VKTkQZD5jq71D6RPg+g=; b=A14LnCD2wCNgzjPed2xx8RnQBZGB4cpgHpSqDrBUA0ATvGO0e3dbyQtp5AS956K86A 6z+8a+aAwYo3h5NMSRfekKgiYzZQ9y2Dw0j4A9yT+WYdo0ZKKiIIJBwtLnyc0m/q9ITJ RAk35DjEae8A6x/m4SP5zMWiSp9Xoa868DaOyCK6/QX4A11+ib84UrZlkHTTLjp4avNM MFlxPBQHmWq0YLFBPMWLB8dZZgd4thiMObyLgQB3lDN9g5Hgq2ts9ySXZRmE4r1QOxY/ esqVS+U8wxroRNqk1Au2LuFEDkUEMNdLu7HTpO0UG5Z8s+CirE5dbuiTmepwCuw4ZPE6 52xQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=fzrOpJIqSuJ6kjPceRcazRx9VKTkQZD5jq71D6RPg+g=; b=UkDdcChSWLVfrFJ2WexJ1ul+y3B2hbKZz2R29AddYznwEZnlgH9kLXMf0zo4g26LM6 u82a5UgDJ01QaPPGRHCWQbs3kxW1lOzrKG0fDJ5Hq68n9uD2qWi7lDn8t6DgEEOcs/RO iDjttrg523hb9gXQHvKlIf4TbTCZE/RvJQhS16b6RWzUWNf4z4roKe3JqFJDNSzc6ts0 +cCAQY1pJAHm3GRsdD4KZbKYHbYYwktg8zZbmWl3+HFGU/iHldGcs7jCRq7JqMR3Ghlu gBcL6q5qUvv/NAmom6LshJZdB5dlRdkf6IZztXuDuGIOEwJ5JzysSTPVwfsk0Ck5gBzo Y5MQ== X-Gm-Message-State: AJIora8wzm2fG9fNsiGx7Ur3vN3LLPYfRNz9wUjgN3/aRyw+pc9HQG1t s7k7cmIQfE3Jk40i5GgCEKcJ6fU2CRNw9w== X-Received: by 2002:a17:902:e552:b0:16c:571d:fc08 with SMTP id n18-20020a170902e55200b0016c571dfc08mr13820931plf.151.1657895101244; Fri, 15 Jul 2022 07:25:01 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id d22-20020aa797b6000000b0051c49fb62b7sm3891174pfq.165.2022.07.15.07.24.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:25:00 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Mark Kettenis , Masahisa Kojima , Michal Simek , Ovidiu Panait , Ashok Reddy Soma , Thomas Huth , Chris Morgan , Huang Jianan , Roland Gaudig Subject: [PATCH 2/9] eficonfig: menu-driven addition of UEFI boot option Date: Fri, 15 Jul 2022 23:27:36 +0900 Message-Id: <20220715142743.30137-3-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220715142743.30137-1-masahisa.kojima@linaro.org> References: <20220715142743.30137-1-masahisa.kojima@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean This commit add the "eficonfig" command. The "eficonfig" command implements the menu-driven UEFI boot option maintenance feature. This commit implements the addition of new boot option. User can select the block device volume having efi_simple_file_system_protocol and select the file corresponding to the Boot#### variable. User can also enter the description and optional_data of the BOOT#### variable in utf8. This commit adds "include/efi_config.h", it contains the common definition to be used from other menus such as UEFI Secure Boot key management. Signed-off-by: Masahisa Kojima --- Changes in v9: - move "efi_guid_bootmenu_auto_generated definition" into efi_bootmgr.c to address build error when CMD_EFICONFIG is disabled - fix typos and comment - remove file system information from error message - remove unreachable code in eficonfig_choice_entry() - single printf() call as much as possible - call only getchar() in eficonfig_print_msg() - filter out '.' entry from file selection - update the efi_disk_get_device_name() implementation - add function comment Changes in v8: - command name is change from "efimenu" to "eficonfig" - function and struct prefixes is changed to "eficonfig" - fix menu header string Changes in v7: - add "efimenu" command and uefi variable maintenance code moved into cmd/efimenu.c - create include/efimenu.h to define the common definition for the other menu such as UEFI Secure Boot key management - update boot option edit UI, user can select description, file, and optional_data to edit in the same menu like following. ** Edit Boot Option ** Description: debian File: virtio 0:1/EFI\debian\grubaa64.efi Optional Data: test Save Quit - remove exit parameter from efimenu_process_common() - menu title type is changed from u16 to char - efimenu_process_common() add menu title string - reduce printf/puts function call for displaying the menu - efi_console_get_u16_string() accept 0 length to allow optional_data is empty - efi_console_get_u16_string() the "size" parameter name is changes to "count" - efimenu is now designed to maintain the UEFI variables, remove autoboot related code - remove one empty line before "Quit" entry - efimenu_init() processes only the first time Changes in v6: - fix typos - modify volume name to match U-Boot syntax - compile in CONFIG_EFI_LOADER=n and CONFIG_CMD_BOOTEFI_BOOTMGR=n - simplify u16_strncmp() usage - support "a\b.efi" file path, use link list to handle filepath - modify length check condition - UEFI related menu items only appears with CONFIG_AUTOBOOT_MENU_SHOW=y Changes in v5: - remove forward declarations - add const qualifier for menu items - fix the possible unaligned access for directory info access - split into three commit 1)add boot option 2) delete boot option 3)change boot order This commit is 1)add boot option. - fix file name buffer allocation size, it should be EFI_BOOTMENU_FILE_PATH_MAX * sizeof(u16) - fix wrong size checking for file selection Chanes in v4: - UEFI boot option maintenance menu is integrated into bootmenu - display the simplified volume name(e.g. usb0:1, nvme1:2) for the volume selection - instead of extending lib/efi_loader/efi_bootmgr.c, newly create lib/efi_loader/efi_bootmenu_maintenance.c and implement boot variable maintenance into it. Changes in RFC v3: not included in v3 series Changes in RFC v2: - enable utf8 user input for boot option name - create lib/efi_loader/efi_console.c::efi_console_get_u16_string() for utf8 user input handling - use u16_strlcat instead of u16_strcat - remove the EFI_CALLs, and newly create or expose the following xxx_int() functions. efi_locate_handle_buffer_int(), efi_open_volume_int(), efi_file_open_int(), efi_file_close_int(), efi_file_read_int() and efi_file_setpos_int(). Note that EFI_CALLs still exist for EFI_DEVICE_PATH_TO_TEXT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT/OUTPUT_PROTOCOL - use efi_search_protocol() instead of calling locate_protocol() to get the device_path_to_text_protocol interface. - remove unnecessary puts(ANSI_CLEAR_LINE), this patch is still depends on puts(ANSI_CLEAR_CONSOLE) - skip SetVariable() if the bootorder is not changed cmd/Kconfig | 7 + cmd/Makefile | 1 + cmd/eficonfig.c | 1324 +++++++++++++++++++++++++++++++++ include/efi_config.h | 91 +++ include/efi_loader.h | 43 ++ lib/efi_loader/efi_bootmgr.c | 3 + lib/efi_loader/efi_boottime.c | 52 +- lib/efi_loader/efi_console.c | 70 ++ lib/efi_loader/efi_disk.c | 46 ++ lib/efi_loader/efi_file.c | 75 +- 10 files changed, 1665 insertions(+), 47 deletions(-) create mode 100644 cmd/eficonfig.c create mode 100644 include/efi_config.h diff --git a/cmd/Kconfig b/cmd/Kconfig index d5f842136c..f1ff39a08c 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1915,6 +1915,13 @@ config CMD_EFIDEBUG particularly for managing boot parameters as well as examining various EFI status for debugging. +config CMD_EFICONFIG + bool "eficonfig - provide menu-driven uefi variables maintenance interface" + depends on CMD_BOOTEFI_BOOTMGR + help + Enable the 'eficonfig' command which provides the menu-driven UEFI + variable maintenance interface. + config CMD_EXCEPTION bool "exception - raise exception" depends on ARM || RISCV || SANDBOX || X86 diff --git a/cmd/Makefile b/cmd/Makefile index 5e43a1e022..0afa687e94 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -63,6 +63,7 @@ obj-$(CONFIG_ENV_IS_IN_EEPROM) += eeprom.o obj-$(CONFIG_CMD_EEPROM) += eeprom.o obj-$(CONFIG_EFI) += efi.o obj-$(CONFIG_CMD_EFIDEBUG) += efidebug.o +obj-$(CONFIG_CMD_EFICONFIG) += eficonfig.o obj-$(CONFIG_CMD_ELF) += elf.o obj-$(CONFIG_CMD_EROFS) += erofs.o obj-$(CONFIG_HUSH_PARSER) += exit.o diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c new file mode 100644 index 0000000000..235d5014c7 --- /dev/null +++ b/cmd/eficonfig.c @@ -0,0 +1,1324 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Menu-driven UEFI Variable maintenance + * + * Copyright (c) 2022 Masahisa Kojima, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct efi_simple_text_input_protocol *cin; + +#define EFICONFIG_DESCRIPTION_MAX 32 +#define EFICONFIG_OPTIONAL_DATA_MAX 64 +#define EFICONFIG_EDIT_BOOT_OPTION_MENU_ENTRY 5 + +/** + * struct eficonfig_filepath_info - structure to be used to store file path + * + * @name: file or directry name + * @list: list structure + */ +struct eficonfig_filepath_info { + u16 *name; + struct list_head list; +}; + +/** + * struct eficonfig_boot_option - structure to be used for updating UEFI boot option + * + * @file_info: user selected file info + * @boot_index: index of the UEFI BootOrder variable + * @description: pointer to the description string + * @optional_data: pointer to the optional_data + * @edit_completed: flag indicates edit complete + */ +struct eficonfig_boot_option { + struct eficonfig_select_file_info file_info; + unsigned int boot_index; + u16 *description; + u16 *optional_data; + bool edit_completed; +}; + +/** + * struct eficonfig_volume_entry_data - structure to be used to store volume info + * + * @file_info: pointer to file info structure + * @v: pointer to the protocol interface + * @dp: pointer to the device path + */ +struct eficonfig_volume_entry_data { + struct eficonfig_select_file_info *file_info; + struct efi_simple_file_system_protocol *v; + struct efi_device_path *dp; +}; + +/** + * struct eficonfig_file_entry_data - structure to be used to store file info + * + * @file_info: pointer to file info structure + * @is_directory: flag to indentify the directory or file + * @file_name: name of directory or file + */ +struct eficonfig_file_entry_data { + struct eficonfig_select_file_info *file_info; + bool is_directory; + u16 *file_name; +}; + +/** + * eficonfig_print_msg() - print message + * + * display the message to the user, user proceeds the screen + * with any key press. + * + * @items: pointer to the structure of each menu entry + * @count: the number of menu entry + * @menu_header: pointer to the menu header string + * Return: status code + */ +void eficonfig_print_msg(char *msg) +{ + /* Flush input */ + while (tstc()) + getchar(); + + printf(ANSI_CURSOR_HIDE + ANSI_CLEAR_CONSOLE + ANSI_CURSOR_POSITION + "%s\n\n Press any key to continue", 3, 4, msg); + + getchar(); +} + +/** + * eficonfig_print_entry() - print each menu entry + * + * @data: pointer to the data associated with each menu entry + */ +static void eficonfig_print_entry(void *data) +{ + struct eficonfig_entry *entry = data; + int reverse = (entry->efi_menu->active == entry->num); + + /* TODO: support scroll or page for many entries */ + + /* + * Move cursor to line where the entry will be drawn (entry->count) + * First 3 lines(menu header) + one empty line + */ + printf(ANSI_CURSOR_POSITION " ", entry->num + 4, 1); + + if (reverse) + puts(ANSI_COLOR_REVERSE); + + printf("%s", entry->title); + + if (reverse) + puts(ANSI_COLOR_RESET); +} + +/** + * eficonfig_display_statusline() - print status line + * + * @m: pointer to the menu structure + */ +static void eficonfig_display_statusline(struct menu *m) +{ + struct eficonfig_entry *entry; + + if (menu_default_choice(m, (void *)&entry) < 0) + return; + + printf(ANSI_CURSOR_POSITION + "\n%s\n" + ANSI_CURSOR_POSITION + "\n" + " Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit", + 0, 1, entry->efi_menu->menu_header, entry->efi_menu->count + 5, 1); +} + +/** + * eficonfig_choice_entry() - user key input handler + * + * @data: pointer to the efimenu structure + * Return: key string to identify the selected entry + */ +static char *eficonfig_choice_entry(void *data) +{ + int i; + int esc = 0; + struct eficonfig_entry *iter; + enum bootmenu_key key = KEY_NONE; + struct efimenu *efi_menu = data; + + while (1) { + bootmenu_loop((struct bootmenu_data *)efi_menu, &key, &esc); + + switch (key) { + case KEY_UP: + if (efi_menu->active > 0) + --efi_menu->active; + /* no menu key selected, regenerate menu */ + return NULL; + case KEY_DOWN: + if (efi_menu->active < efi_menu->count - 1) + ++efi_menu->active; + /* no menu key selected, regenerate menu */ + return NULL; + case KEY_SELECT: + iter = efi_menu->first; + for (i = 0; i < efi_menu->active; ++i) + iter = iter->next; + return iter->key; + case KEY_QUIT: + /* Quit by choosing the last entry */ + iter = efi_menu->first; + while (iter->next) + iter = iter->next; + return iter->key; + default: + break; + } + } +} + +/** + * eficonfig_destroy() - destroy efimenu + * + * @efi_menu: pointer to the efimenu structure + */ +static void eficonfig_destroy(struct efimenu *efi_menu) +{ + struct eficonfig_entry *next; + struct eficonfig_entry *iter = efi_menu->first; + + while (iter) { + next = iter->next; + free(iter); + iter = next; + } + free(efi_menu->menu_header); + free(efi_menu); +} + +/** + * eficonfig_process_quit() - callback function for "Quit" entry + * + * @data: pointer to the data + * Return: status code + */ +efi_status_t eficonfig_process_quit(void *data) +{ + return EFI_ABORTED; +} + +/** + * eficonfig_process_common() - main handler for UEFI menu + * + * Construct the structures required to show the menu, then handle + * the user input interacting with u-boot menu functions. + * + * @items: pointer to the structure of each menu entry + * @count: the number of menu entry + * @menu_header: pointer to the menu header string + * Return: status code + */ +efi_status_t eficonfig_process_common(const struct eficonfig_item *items, int count, + char *menu_header) +{ + u32 i; + efi_status_t ret; + struct menu *menu; + void *choice = NULL; + struct eficonfig_entry *entry; + struct efimenu *efi_menu; + struct eficonfig_entry *iter = NULL; + + if (count > EFICONFIG_ENTRY_NUM_MAX) + return EFI_OUT_OF_RESOURCES; + + efi_menu = calloc(1, sizeof(struct efimenu)); + if (!efi_menu) + return EFI_OUT_OF_RESOURCES; + + efi_menu->delay = -1; + efi_menu->active = 0; + efi_menu->first = NULL; + + if (menu_header) { + efi_menu->menu_header = strdup(menu_header); + if (!efi_menu->menu_header) { + free(efi_menu); + return EFI_OUT_OF_RESOURCES; + } + } + + for (i = 0; i < count; i++) { + entry = calloc(1, sizeof(struct eficonfig_entry)); + if (!entry) { + ret = EFI_LOAD_ERROR; + goto out; + } + + entry->num = i; + entry->title = items->title; + sprintf(entry->key, "%d", i); + entry->efi_menu = efi_menu; + entry->func = items->func; + entry->data = items->data; + entry->next = NULL; + + if (!iter) + efi_menu->first = entry; + else + iter->next = entry; + + iter = entry; + items++; + } + efi_menu->count = count; + + menu = menu_create(NULL, 0, 1, eficonfig_display_statusline, + eficonfig_print_entry, eficonfig_choice_entry, + efi_menu); + if (!menu) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + + for (entry = efi_menu->first; entry; entry = entry->next) { + if (!menu_item_add(menu, entry->key, entry)) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + } + + menu_default_set(menu, efi_menu->first->key); + + printf(ANSI_CURSOR_HIDE + ANSI_CLEAR_CONSOLE + ANSI_CURSOR_POSITION, 1, 1); + + if (menu_get_choice(menu, &choice)) { + entry = choice; + if (entry->func) + ret = entry->func(entry->data); + } + +out: + menu_destroy(menu); + eficonfig_destroy(efi_menu); + + printf(ANSI_CLEAR_CONSOLE + ANSI_CURSOR_POSITION + ANSI_CURSOR_SHOW, 1, 1); + + return ret; +} + +/** + * eficonfig_volume_selected() - handler of volume selection + * + * @data: pointer to the data of selected entry + * Return: status code + */ +static efi_status_t eficonfig_volume_selected(void *data) +{ + struct eficonfig_volume_entry_data *info = data; + + if (info) { + info->file_info->current_volume = info->v; + info->file_info->dp_volume = info->dp; + } + + return EFI_SUCCESS; +} + +/** + * eficonfig_file_selected() - handler of file selection + * + * @data: pointer to the data of selected entry + * Return: status code + */ +static efi_status_t eficonfig_file_selected(void *data) +{ + struct eficonfig_file_entry_data *info = data; + + if (!info) + return EFI_INVALID_PARAMETER; + + if (u16_strcmp(info->file_name, u".") == 0 && + u16_strlen(info->file_name) == 1) { + /* stay current path */ + } else if (u16_strcmp(info->file_name, u"..") == 0 && + u16_strlen(info->file_name) == 2) { + struct eficonfig_filepath_info *iter; + struct list_head *pos, *n; + int is_last; + + memset(info->file_info->current_path, 0, EFICONFIG_FILE_PATH_BUF_SIZE); + list_for_each_safe(pos, n, &info->file_info->filepath_list) { + iter = list_entry(pos, struct eficonfig_filepath_info, list); + + is_last = list_is_last(&iter->list, &info->file_info->filepath_list); + if (is_last) { + list_del(&iter->list); + free(iter->name); + free(iter); + break; + } + u16_strlcat(info->file_info->current_path, iter->name, + EFICONFIG_FILE_PATH_MAX); + u16_strlcat(info->file_info->current_path, u"\\", + EFICONFIG_FILE_PATH_MAX); + } + } else { + size_t new_len; + struct eficonfig_filepath_info *filepath; + + new_len = u16_strlen(info->file_info->current_path) + + u16_strlen(info->file_name); + if (new_len >= EFICONFIG_FILE_PATH_MAX) { + eficonfig_print_msg("File path is too long!"); + return EFI_INVALID_PARAMETER; + } + u16_strlcat(info->file_info->current_path, info->file_name, + EFICONFIG_FILE_PATH_MAX); + + filepath = calloc(1, sizeof(struct eficonfig_filepath_info)); + if (!filepath) + return EFI_OUT_OF_RESOURCES; + + filepath->name = u16_strdup(info->file_name); + if (!filepath->name) { + free(filepath); + return EFI_OUT_OF_RESOURCES; + } + list_add_tail(&filepath->list, &info->file_info->filepath_list); + + if (info->is_directory) { + /* + * Remainig buffer should have enough space to contain u"\\" and + * at least one character for file name + */ + if (new_len + 2 >= EFICONFIG_FILE_PATH_MAX) { + eficonfig_print_msg("Directory path is too long!"); + return EFI_INVALID_PARAMETER; + } + u16_strlcat(info->file_info->current_path, u"\\", + EFICONFIG_FILE_PATH_MAX); + } else { + info->file_info->file_selected = true; + } + } + return EFI_SUCCESS; +} + +/** + * eficonfig_select_volume() - construct the volume selection menu + * + * @file_info: pointer to the file selection structure + * Return: status code + */ +static efi_status_t eficonfig_select_volume(struct eficonfig_select_file_info *file_info) +{ + u32 i; + efi_status_t ret; + efi_uintn_t count; + struct efi_handler *handler; + struct efi_device_path *device_path; + efi_handle_t *volume_handles = NULL; + struct eficonfig_item *menu_item, *iter; + struct efi_simple_file_system_protocol *v; + + ret = efi_locate_handle_buffer_int(BY_PROTOCOL, &efi_simple_file_system_protocol_guid, + NULL, &count, (efi_handle_t **)&volume_handles); + if (ret != EFI_SUCCESS) { + eficonfig_print_msg("No block device found!"); + return ret; + } + + menu_item = calloc(count + 1, sizeof(struct eficonfig_item)); + if (!menu_item) { + efi_free_pool(volume_handles); + return EFI_OUT_OF_RESOURCES; + } + + iter = menu_item; + for (i = 0; i < count; i++) { + char *devname; + struct efi_block_io *block_io; + struct eficonfig_volume_entry_data *info; + + ret = efi_search_protocol(volume_handles[i], + &efi_simple_file_system_protocol_guid, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&v, efi_root, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + ret = efi_search_protocol(volume_handles[i], &efi_guid_device_path, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&device_path, + efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + ret = efi_search_protocol(volume_handles[i], &efi_block_io_guid, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&block_io, + efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + info = calloc(1, sizeof(struct eficonfig_volume_entry_data)); + if (!info) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + devname = calloc(1, BOOTMENU_DEVICE_NAME_MAX); + if (!devname) { + free(info); + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + ret = efi_disk_get_device_name(volume_handles[i], devname, + BOOTMENU_DEVICE_NAME_MAX); + if (ret != EFI_SUCCESS) { + free(info); + goto out; + } + + info->v = v; + info->dp = device_path; + info->file_info = file_info; + iter->title = devname; + iter->func = eficonfig_volume_selected; + iter->data = info; + iter++; + } + + iter->title = strdup("Quit"); + iter->func = eficonfig_process_quit; + iter->data = NULL; + count++; + + ret = eficonfig_process_common(menu_item, count, " ** Select Volume **"); + +out: + iter = menu_item; + for (i = 0; i < count; i++, iter++) { + free(iter->data); + free(iter->title); + } + + free(menu_item); + + efi_free_pool(volume_handles); + + return ret; +} + +/** + * eficonfig_select_file() - construct the file selection menu + * + * @file_info: pointer to the file selection structure + * @root: pointer to the file handle + * Return: status code + */ +static efi_status_t eficonfig_select_file(struct eficonfig_select_file_info *file_info, + struct efi_file_handle *root) +{ + u32 i; + u32 count; + efi_uintn_t len; + efi_status_t ret; + struct efi_file_handle *f; + struct efi_file_info *buf; + struct eficonfig_item *menu_item, *iter; + + buf = calloc(1, sizeof(struct efi_file_info) + EFICONFIG_FILE_PATH_BUF_SIZE); + if (!buf) + return EFI_OUT_OF_RESOURCES; + + while (!file_info->file_selected) { + count = 1; /* for Quit entry */ + + ret = efi_file_open_int(root, &f, file_info->current_path, EFI_FILE_MODE_READ, 0); + if (ret != EFI_SUCCESS) { + eficonfig_print_msg("Reading volume failed!"); + ret = EFI_ABORTED; + goto out; + } + + /* Count the number of directory entries */ + for (;;) { + len = sizeof(struct efi_file_info) + EFICONFIG_FILE_PATH_BUF_SIZE; + ret = efi_file_read_int(f, &len, buf); + if (ret != EFI_SUCCESS || len == 0) + break; + + count++; + } + + menu_item = calloc(count, sizeof(struct eficonfig_item)); + if (!menu_item) { + efi_file_close_int(f); + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + /* Read directory and construct menu structure */ + efi_file_setpos_int(f, 0); + iter = menu_item; + for (i = 0; i < count - 1;) { + char *name, *p; + int name_len; + struct eficonfig_file_entry_data *info; + + len = sizeof(struct efi_file_info) + EFICONFIG_FILE_PATH_BUF_SIZE; + ret = efi_file_read_int(f, &len, buf); + if (ret != EFI_SUCCESS || len == 0) + goto err; + + info = calloc(1, sizeof(struct eficonfig_file_entry_data)); + if (!info) { + ret = EFI_OUT_OF_RESOURCES; + goto err; + } + + if (buf->attribute & EFI_FILE_DIRECTORY) { + /* append u'/' at the end of directory name */ + name_len = utf16_utf8_strlen(buf->file_name) + 2; + + /* filter out u'.' */ + if (name_len == 3 && buf->file_name[0] == u'.') { + free(info); + count--; + continue; + } + + name = calloc(1, name_len); + if (!name) { + ret = EFI_OUT_OF_RESOURCES; + goto err; + } + p = name; + utf16_utf8_strcpy(&p, buf->file_name); + name[u16_strlen(buf->file_name)] = u'/'; + + info->is_directory = true; + } else { + name_len = utf16_utf8_strlen(buf->file_name) + 1; + name = calloc(1, name_len); + if (!name) { + ret = EFI_OUT_OF_RESOURCES; + goto err; + } + p = name; + utf16_utf8_strcpy(&p, buf->file_name); + } + + info->file_name = u16_strdup(buf->file_name); + info->file_info = file_info; + iter->title = name; + iter->func = eficonfig_file_selected; + iter->data = info; + iter++; + i++; + } + + /* add "Quit" entry */ + iter->title = "Quit"; + iter->func = eficonfig_process_quit; + iter->data = NULL; + + ret = eficonfig_process_common(menu_item, count, " ** Select File **"); +err: + efi_file_close_int(f); + iter = menu_item; + for (i = 0; i < count - 1; i++, iter++) { + free(((struct eficonfig_file_entry_data *)(iter->data))->file_name); + free(iter->title); + free(iter->data); + } + + free(menu_item); + + if (ret != EFI_SUCCESS) + break; + } + +out: + free(buf); + return ret; +} + +/** + * eficonfig_boot_add_enter_description() - handle user input for description + * + * @data: pinter to the internal boot option structure + * Return: status code + */ +static efi_status_t eficonfig_boot_add_enter_description(void *data) +{ + u16 *tmp; + efi_status_t ret; + struct eficonfig_boot_option *bo = data; + + printf(ANSI_CLEAR_CONSOLE + ANSI_CURSOR_POSITION + "\n ** Edit Description **\n" + "\n" + " enter description: " + ANSI_CURSOR_POSITION + " Press ENTER to complete, ESC/CTRL+C to quit", + 0, 1, 8, 1); + + tmp = calloc(1, EFICONFIG_DESCRIPTION_MAX * sizeof(u16)); + if (!tmp) + return EFI_OUT_OF_RESOURCES; + + ret = efi_console_get_u16_string(cin, tmp, EFICONFIG_DESCRIPTION_MAX, NULL, 4, 22); + if (ret == EFI_SUCCESS) + u16_strcpy(bo->description, tmp); + + free(tmp); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + +/** + * eficonfig_boot_add_optional_data() - handle user input for optional data + * + * @data: pinter to the internal boot option structure + * Return: status code + */ +static efi_status_t eficonfig_boot_add_optional_data(void *data) +{ + u16 *tmp; + efi_status_t ret; + struct eficonfig_boot_option *bo = data; + + printf(ANSI_CLEAR_CONSOLE + ANSI_CURSOR_POSITION + "\n ** Edit Optional Data **\n" + "\n" + " enter optional data:" + ANSI_CURSOR_POSITION + " Press ENTER to complete, ESC/CTRL+C to quit", + 0, 1, 8, 1); + + tmp = calloc(1, EFICONFIG_OPTIONAL_DATA_MAX * sizeof(u16)); + ret = efi_console_get_u16_string(cin, tmp, EFICONFIG_OPTIONAL_DATA_MAX, NULL, 4, 24); + + if (ret == EFI_SUCCESS) + u16_strcpy(bo->optional_data, tmp); + + free(tmp); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + +/** + * eficonfig_boot_edit_save() - handler to save the boot option + * + * @data: pinter to the internal boot option structure + * Return: status code + */ +static efi_status_t eficonfig_boot_edit_save(void *data) +{ + struct eficonfig_boot_option *bo = data; + + if (u16_strlen(bo->description) == 0) { + eficonfig_print_msg("Boot Description is empty!"); + bo->edit_completed = false; + return EFI_NOT_READY; + } + if (u16_strlen(bo->file_info.current_path) == 0) { + eficonfig_print_msg("File is not selected!"); + bo->edit_completed = false; + return EFI_NOT_READY; + } + + bo->edit_completed = true; + + return EFI_SUCCESS; +} + +/** + * eficonfig_select_file_handler() - handle user file selection + * + * @data: pointer to the data + * Return: status code + */ +efi_status_t eficonfig_select_file_handler(void *data) +{ + size_t len; + efi_status_t ret; + struct list_head *pos, *n; + struct efi_file_handle *root; + struct eficonfig_filepath_info *item; + struct eficonfig_select_file_info *file_info = data; + struct eficonfig_select_file_info *tmp = NULL; + + tmp = calloc(1, sizeof(struct eficonfig_select_file_info)); + if (!tmp) + return EFI_OUT_OF_RESOURCES; + + tmp->current_path = calloc(1, EFICONFIG_FILE_PATH_BUF_SIZE); + if (!tmp->current_path) { + free(tmp); + return EFI_OUT_OF_RESOURCES; + } + INIT_LIST_HEAD(&tmp->filepath_list); + + while (!tmp->file_selected) { + tmp->current_volume = NULL; + memset(tmp->current_path, 0, EFICONFIG_FILE_PATH_BUF_SIZE); + + ret = eficonfig_select_volume(tmp); + if (ret != EFI_SUCCESS) + goto out; + + if (!tmp->current_volume) + return EFI_INVALID_PARAMETER; + + ret = efi_open_volume_int(tmp->current_volume, &root); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_select_file(tmp, root); + if (ret == EFI_ABORTED) + continue; + if (ret != EFI_SUCCESS) + goto out; + } + +out: + if (ret == EFI_SUCCESS) { + len = u16_strlen(tmp->current_path); + len = (len >= EFICONFIG_FILE_PATH_MAX) ? (EFICONFIG_FILE_PATH_MAX - 1) : len; + memcpy(file_info->current_path, tmp->current_path, len * sizeof(u16)); + file_info->current_path[len] = u'\0'; + file_info->current_volume = tmp->current_volume; + file_info->dp_volume = tmp->dp_volume; + } + + list_for_each_safe(pos, n, &tmp->filepath_list) { + item = list_entry(pos, struct eficonfig_filepath_info, list); + list_del(&item->list); + free(item->name); + free(item); + } + free(tmp->current_path); + free(tmp); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + +/** + * eficonfig_get_unused_bootoption() - get unused "Boot####" index + * + * @buf: pointer to the buffer to store boot option variable name + * @buf_size: buffer size + * @index: pointer to store the index in the BootOrder variable + * Return: status code + */ +efi_status_t eficonfig_get_unused_bootoption(u16 *buf, efi_uintn_t buf_size, + unsigned int *index) +{ + u32 i; + efi_status_t ret; + efi_uintn_t size; + + if (buf_size < u16_strsize(u"Boot####")) + return EFI_BUFFER_TOO_SMALL; + + for (i = 0; i <= 0xFFFF; i++) { + size = 0; + efi_create_indexed_name(buf, buf_size, "Boot", i); + ret = efi_get_variable_int(buf, &efi_global_variable_guid, + NULL, &size, NULL, NULL); + if (ret == EFI_BUFFER_TOO_SMALL) + continue; + else + break; + } + + if (i > 0xFFFF) + return EFI_OUT_OF_RESOURCES; + + *index = i; + + return EFI_SUCCESS; +} + +/** + * eficonfig_set_boot_option() - set boot option + * + * @varname: pointer to variable name + * @dp: pointer to device path + * @label: pointer to label string + * @optional_data: pointer to optional data + * Return: status code + */ +static efi_status_t eficonfig_set_boot_option(u16 *varname, struct efi_device_path *dp, + u16 *label, char *optional_data) +{ + void *p = NULL; + efi_status_t ret; + efi_uintn_t size; + struct efi_load_option lo; + + lo.file_path = dp; + lo.file_path_length = efi_dp_size(dp) + sizeof(END); + lo.attributes = LOAD_OPTION_ACTIVE; + lo.optional_data = optional_data; + lo.label = label; + + size = efi_serialize_load_option(&lo, (u8 **)&p); + if (!size) + return EFI_INVALID_PARAMETER; + + ret = efi_set_variable_int(varname, &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, p, false); + free(p); + + return ret; +} + +/** + * eficonfig_append_bootorder() - append new boot option in BootOrder variable + * + * @index: "Boot####" index to append to BootOrder variable + * Return: status code + */ +efi_status_t eficonfig_append_bootorder(u16 index) +{ + u16 *bootorder; + efi_status_t ret; + u16 *new_bootorder = NULL; + efi_uintn_t last, size, new_size; + + /* append new boot option */ + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + last = size / sizeof(u16); + new_size = size + sizeof(u16); + new_bootorder = calloc(1, new_size); + if (!new_bootorder) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + memcpy(new_bootorder, bootorder, size); + new_bootorder[last] = index; + + ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + new_size, new_bootorder, false); + if (ret != EFI_SUCCESS) + goto out; + +out: + free(bootorder); + free(new_bootorder); + + return ret; +} + +/** + * create_boot_option_entry() - create boot option entry + * + * @data: pointer to the data to be passed to each entry callback + * @title: pointer to the entry title + * @val: pointer to boot option label + * @func: callback of each entry + * @iter: pointer to the menu entry iteration + * Return: status code + */ +static efi_status_t create_boot_option_entry(void *data, char *title, u16 *val, + eficonfig_entry_func func, + struct eficonfig_item *iter) +{ + u32 len; + char *p; + + len = strlen(title) + 1; + if (val) + len += utf16_utf8_strlen(val); + iter->title = calloc(1, len); + if (!iter->title) + return EFI_OUT_OF_RESOURCES; + + strcpy(iter->title, title); + if (val) { + p = iter->title + strlen(title); + utf16_utf8_strcpy(&p, val); + } + + iter->func = func; + iter->data = data; + + return EFI_SUCCESS; +} + +/** + * eficonfig_show_boot_option() - prepare menu entry for editing boot option + * + * Construct the structures to create edit boot option menu + * + * @bo: pointer to the boot option + * @header_str: pointer to the header string + * Return: status code + */ +static efi_status_t eficonfig_show_boot_option(struct eficonfig_boot_option *bo, + char *header_str) +{ + u32 i, len; + u16 *file_name, *p; + efi_handle_t handle; + struct eficonfig_item *menu_item, *iter; + efi_status_t ret = EFI_OUT_OF_RESOURCES; + char devname[BOOTMENU_DEVICE_NAME_MAX] = {0}; + + menu_item = calloc(EFICONFIG_EDIT_BOOT_OPTION_MENU_ENTRY, sizeof(struct eficonfig_item)); + if (!menu_item) + goto out; + + iter = menu_item; + + ret = create_boot_option_entry(bo, "Description: ", bo->description, + eficonfig_boot_add_enter_description, iter++); + if (ret != EFI_SUCCESS) + goto out; + + /* get the device name only when the user already selected the file path */ + handle = efi_dp_find_obj(bo->file_info.dp_volume, NULL, NULL); + if (handle) { + efi_disk_get_device_name(handle, devname, BOOTMENU_DEVICE_NAME_MAX); + if (ret != EFI_SUCCESS) + goto out; + } + /* + * efi_convert_device_path_to_text() automatically adds u'/' at the beginning of + * file name, append u'/' if there is no u'/' at bo->file_info.current_path[0]. + */ + if (bo->file_info.current_path[0] != u'\0' && bo->file_info.current_path[0] != u'/') + strlcat(devname, "/", BOOTMENU_DEVICE_NAME_MAX); + + len = strlen(devname); + len += utf16_utf8_strlen(bo->file_info.current_path) + 1; + file_name = calloc(1, len * sizeof(u16)); + if (!file_name) + goto out; + + p = file_name; + utf8_utf16_strcpy(&p, devname); + u16_strlcat(file_name, bo->file_info.current_path, len); + ret = create_boot_option_entry(&bo->file_info, "File: ", file_name, + eficonfig_select_file_handler, iter++); + if (ret != EFI_SUCCESS) + goto out; + + ret = create_boot_option_entry(bo, "Optional Data: ", bo->optional_data, + eficonfig_boot_add_optional_data, iter++); + if (ret != EFI_SUCCESS) + goto out; + + ret = create_boot_option_entry(bo, "Save", NULL, + eficonfig_boot_edit_save, iter++); + if (ret != EFI_SUCCESS) + goto out; + + ret = create_boot_option_entry(bo, "Quit", NULL, + eficonfig_process_quit, iter++); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_process_common(menu_item, EFICONFIG_EDIT_BOOT_OPTION_MENU_ENTRY, + header_str); + +out: + iter = menu_item; + for (i = 0; i < EFICONFIG_EDIT_BOOT_OPTION_MENU_ENTRY; i++) { + free(iter->title); + iter++; + } + + free(file_name); + free(menu_item); + + return ret; +} + +/** + * eficonfig_edit_boot_option() - prepare boot option structure for editing + * + * Construct the boot option structure and copy the existing value + * + * @varname: pointer to the UEFI variable name + * @bo: pointer to the boot option + * @description: pointer to the description + * @optional_data: pointer to the optional_data + * @optional_data_size: optional_data_size + * @dp: pointer to the device path + * @header_str: pointer to the header string + * Return : status code + */ +static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_boot_option *bo, + u16 *description, const u8 *optional_data, + efi_uintn_t optional_data_size, + struct efi_device_path *dp, + char *header_str) +{ + size_t len; + char *buf = NULL; + efi_status_t ret; + char *iter = NULL; + char *tmp = NULL, *p; + efi_uintn_t dp_size, fp_size; + struct efi_device_path *device_dp = NULL; + struct efi_device_path_file_path *fp; + + bo->file_info.current_path = calloc(1, EFICONFIG_FILE_PATH_BUF_SIZE); + if (!bo->file_info.current_path) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + bo->description = calloc(1, EFICONFIG_DESCRIPTION_MAX * sizeof(u16)); + if (!bo->description) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + bo->optional_data = calloc(1, EFICONFIG_OPTIONAL_DATA_MAX * sizeof(u16)); + if (!bo->optional_data) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + if (description && u16_strlen(description) >= EFICONFIG_DESCRIPTION_MAX) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + if (description) + u16_strcpy(bo->description, description); + + if (dp) { + u16 *file_str; + struct efi_device_path *file_dp = NULL; + + efi_dp_split_file_path(dp, &device_dp, &file_dp); + bo->file_info.dp_volume = device_dp; + file_str = efi_dp_str(file_dp); + u16_strcpy(bo->file_info.current_path, file_str); + efi_free_pool(file_dp); + efi_free_pool(file_str); + } + + if (optional_data && optional_data_size >= EFICONFIG_OPTIONAL_DATA_MAX * sizeof(u16)) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + if (optional_data && optional_data_size > 0) + memcpy(bo->optional_data, optional_data, optional_data_size); + + while (1) { + ret = eficonfig_show_boot_option(bo, header_str); + if (ret == EFI_SUCCESS && bo->edit_completed) + break; + if (ret == EFI_NOT_READY) + continue; + if (ret != EFI_SUCCESS) + goto out; + } + + dp_size = efi_dp_size(bo->file_info.dp_volume); + fp_size = sizeof(struct efi_device_path) + + ((u16_strlen(bo->file_info.current_path) + 1) * sizeof(u16)); + buf = calloc(1, dp_size + fp_size + sizeof(END)); + if (!buf) + goto out; + + iter = buf; + memcpy(iter, bo->file_info.dp_volume, dp_size); + iter += dp_size; + + fp = (struct efi_device_path_file_path *)iter; + fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; + fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH; + fp->dp.length = (u16)fp_size; + u16_strcpy(fp->str, bo->file_info.current_path); + iter += fp_size; + *((struct efi_device_path *)iter) = END; + + len = utf16_utf8_strlen(bo->optional_data) + 1; + tmp = calloc(1, len); + if (!tmp) + goto out; + p = tmp; + utf16_utf8_strncpy(&p, bo->optional_data, u16_strlen(bo->optional_data)); + + ret = eficonfig_set_boot_option(varname, (struct efi_device_path *)buf, + bo->description, tmp); + if (ret != EFI_SUCCESS) + goto out; + +out: + free(tmp); + free(buf); + free(bo->optional_data); + free(bo->description); + free(bo->file_info.current_path); + efi_free_pool(device_dp); + + return ret; +} + +/** + * eficonfig_process_add_boot_option() - handler to add boot option + * + * @data: pointer to the data for each entry + * Return: status code + */ +static efi_status_t eficonfig_process_add_boot_option(void *data) +{ + u16 varname[9]; + efi_status_t ret; + struct eficonfig_boot_option *bo = NULL; + + bo = calloc(1, sizeof(struct eficonfig_boot_option)); + if (!bo) + return EFI_OUT_OF_RESOURCES; + + ret = eficonfig_get_unused_bootoption(varname, sizeof(varname), &bo->boot_index); + if (ret != EFI_SUCCESS) + return ret; + + ret = eficonfig_edit_boot_option(varname, bo, NULL, NULL, 0, NULL, + " ** Add Boot Option ** "); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_append_bootorder((u16)bo->boot_index); + if (ret != EFI_SUCCESS) + goto out; + +out: + free(bo); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_SUCCESS : ret; + + return ret; +} + +/** + * eficonfig_init() - do required initialization for eficonfig command + * + * Return: status code + */ +static efi_status_t eficonfig_init(void) +{ + efi_status_t ret; + static bool init; + struct efi_handler *handler; + + if (!init) { + ret = efi_search_protocol(efi_root, &efi_guid_text_input_protocol, &handler); + if (ret != EFI_SUCCESS) + return ret; + + ret = efi_protocol_open(handler, (void **)&cin, efi_root, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + return ret; + } + + init = true; + + return ret; +} + +static const struct eficonfig_item maintenance_menu_items[] = { + {"Add Boot Option", eficonfig_process_add_boot_option}, + {"Quit", eficonfig_process_quit}, +}; + +/** + * do_eficonfig() - execute `eficonfig` command + * + * @cmdtp: table entry describing command + * @flag: bitmap indicating how the command was invoked + * @argc: number of arguments + * @argv: command line arguments + * Return: status code + */ +static int do_eficonfig(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + efi_status_t ret; + + if (argc > 1) + return CMD_RET_USAGE; + + ret = efi_init_obj_list(); + if (ret != EFI_SUCCESS) { + log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n", + ret & ~EFI_ERROR_MASK); + + return CMD_RET_FAILURE; + } + + ret = eficonfig_init(); + if (ret != EFI_SUCCESS) + return CMD_RET_FAILURE; + + while (1) { + ret = eficonfig_process_common(maintenance_menu_items, + ARRAY_SIZE(maintenance_menu_items), + " ** UEFI Maintenance Menu **"); + if (ret == EFI_ABORTED) + break; + } + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + eficonfig, 1, 0, do_eficonfig, + "provide menu-driven UEFI variable maintenance interface", + "" +); diff --git a/include/efi_config.h b/include/efi_config.h new file mode 100644 index 0000000000..1b48e47c48 --- /dev/null +++ b/include/efi_config.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Menu-driven UEFI Variable maintenance + * + * Copyright (c) 2022 Masahisa Kojima, Linaro Limited + */ + +#ifndef _EFI_CONFIG_H +#define _EFI_CONFIG_H + +#define EFICONFIG_ENTRY_NUM_MAX 99 +#define EFICONFIG_FILE_PATH_MAX 512 +#define EFICONFIG_FILE_PATH_BUF_SIZE (EFICONFIG_FILE_PATH_MAX * sizeof(u16)) + +typedef efi_status_t (*eficonfig_entry_func)(void *data); + +/** + * struct eficonfig_entry - menu entry structure + * + * @num: menu entry index + * @title: title of entry + * @key: unique key + * @efi_menu: pointer to the menu structure + * @next: pointer to the next entry + * @func: callback function to be called when this entry is selected + * @data: data to be passed to the callback function + */ +struct eficonfig_entry { + u32 num; + char *title; + char key[3]; + struct efimenu *efi_menu; + struct eficonfig_entry *next; + eficonfig_entry_func func; + void *data; +}; + +/** + * struct efimenu - efi menu structure + * + * @delay: delay for autoboot + * @active: active menu entry index + * @count: total count of menu entry + * @menu_header: menu header string + * @first: pointer to the first menu entry + */ +struct efimenu { + int delay; + int active; + int count; + char *menu_header; + struct eficonfig_entry *first; +}; + +/** + * struct eficonfig_item - structure to construct eficonfig_entry + * + * @title: title of entry + * @func: callback function to be called when this entry is selected + * @data: data to be passed to the callback function + */ +struct eficonfig_item { + char *title; + eficonfig_entry_func func; + void *data; +}; + +/** + * struct eficonfig_select_file_info - structure to be used for file selection + * + * @current_volume: pointer to the efi_simple_file_system_protocol + * @dp_volume: pointer to device path of the selected device + * @current_path: pointer to the selected file path string + * @file_selectred: flag indicates file selecting status + * @filepath_list: list_head structure for file path list + */ +struct eficonfig_select_file_info { + struct efi_simple_file_system_protocol *current_volume; + struct efi_device_path *dp_volume; + u16 *current_path; + struct list_head filepath_list; + bool file_selected; +}; + +void eficonfig_print_msg(char *msg); +efi_status_t eficonfig_process_quit(void *data); +efi_status_t eficonfig_process_common(const struct eficonfig_item *items, int count, + char *menu_header); +efi_status_t eficonfig_select_file_handler(void *data); + +#endif diff --git a/include/efi_loader.h b/include/efi_loader.h index bba5ffd482..c57f239043 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -142,6 +142,11 @@ static inline efi_status_t efi_launch_capsules(void) EFI_GUID(0x63293792, 0xadf5, 0x9325, \ 0xb9, 0x9f, 0x4e, 0x0e, 0x45, 0x5c, 0x1b, 0x1e) +/* GUID for the auto generated boot menu entry */ +#define EFICONFIG_AUTO_GENERATED_ENTRY_GUID \ + EFI_GUID(0x38c1acc1, 0x9fc0, 0x41f0, \ + 0xb9, 0x01, 0xfa, 0x74, 0xd6, 0xd6, 0xe4, 0xde) + /* Use internal device tree when starting UEFI application */ #define EFI_FDT_USE_INTERNAL NULL @@ -226,6 +231,9 @@ const char *__efi_nesting_dec(void); #define EFI_CACHELINE_SIZE 128 #endif +/* max bootmenu title size for volume selection */ +#define BOOTMENU_DEVICE_NAME_MAX 16 + /** * efi_handle_to_udev - accessor to the DM device associated to the EFI handle * @handle: pointer to the EFI handle @@ -255,6 +263,9 @@ extern const struct efi_hii_string_protocol efi_hii_string; uint16_t *efi_dp_str(struct efi_device_path *dp); +/* GUID for the auto generated boot menu entry */ +extern const efi_guid_t efi_guid_bootmenu_auto_generated; + /* GUID of the U-Boot root node */ extern const efi_guid_t efi_u_boot_guid; #ifdef CONFIG_SANDBOX @@ -320,6 +331,8 @@ extern const efi_guid_t efi_guid_firmware_management_protocol; extern const efi_guid_t efi_esrt_guid; /* GUID of the SMBIOS table */ extern const efi_guid_t smbios_guid; +/*GUID of console */ +extern const efi_guid_t efi_guid_text_input_protocol; extern char __efi_runtime_start[], __efi_runtime_stop[]; extern char __efi_runtime_rel_start[], __efi_runtime_rel_stop[]; @@ -895,6 +908,8 @@ efi_status_t efi_set_load_options(efi_handle_t handle, void *load_options); efi_status_t efi_bootmgr_load(efi_handle_t *handle, void **load_options); +efi_status_t efi_bootmenu_show_maintenance_menu(void); + /** * struct efi_image_regions - A list of memory regions * @@ -1068,4 +1083,32 @@ efi_status_t efi_esrt_populate(void); efi_status_t efi_load_capsule_drivers(void); efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr, u32 *sz); + +efi_status_t efi_locate_handle_buffer_int(enum efi_locate_search_type search_type, + const efi_guid_t *protocol, void *search_key, + efi_uintn_t *no_handles, efi_handle_t **buffer); + +efi_status_t efi_open_volume_int(struct efi_simple_file_system_protocol *this, + struct efi_file_handle **root); +efi_status_t efi_file_open_int(struct efi_file_handle *this, + struct efi_file_handle **new_handle, + u16 *file_name, u64 open_mode, + u64 attributes); +efi_status_t efi_file_close_int(struct efi_file_handle *file); +efi_status_t efi_file_read_int(struct efi_file_handle *this, + efi_uintn_t *buffer_size, void *buffer); +efi_status_t efi_file_setpos_int(struct efi_file_handle *file, u64 pos); + +typedef efi_status_t (*efi_console_filter_func)(struct efi_input_key *key); +efi_status_t efi_console_get_u16_string + (struct efi_simple_text_input_protocol *cin, + u16 *buf, efi_uintn_t count, efi_console_filter_func filer_func, + int row, int col); + +efi_status_t eficonfig_get_unused_bootoption(u16 *buf, + efi_uintn_t buf_size, u32 *index); +efi_status_t eficonfig_append_bootorder(u16 index); + +efi_status_t efi_disk_get_device_name(const efi_handle_t handle, char *buf, int size); + #endif /* _EFI_LOADER_H */ diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 234073ecb7..ede9116b3c 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -19,6 +19,9 @@ static const struct efi_boot_services *bs; static const struct efi_runtime_services *rs; +const efi_guid_t efi_guid_bootmenu_auto_generated = + EFICONFIG_AUTO_GENERATED_ENTRY_GUID; + /* * bootmgr implements the logic of trying to find a payload to boot * based on the BootOrder + BootXXXX variables, and then loading it. diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 4da64b5d29..1233418e77 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -2453,6 +2453,35 @@ static efi_status_t EFIAPI efi_protocols_per_handle( return EFI_EXIT(EFI_SUCCESS); } +efi_status_t efi_locate_handle_buffer_int(enum efi_locate_search_type search_type, + const efi_guid_t *protocol, void *search_key, + efi_uintn_t *no_handles, efi_handle_t **buffer) +{ + efi_status_t r; + efi_uintn_t buffer_size = 0; + + if (!no_handles || !buffer) { + r = EFI_INVALID_PARAMETER; + goto out; + } + *no_handles = 0; + *buffer = NULL; + r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, + *buffer); + if (r != EFI_BUFFER_TOO_SMALL) + goto out; + r = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, buffer_size, + (void **)buffer); + if (r != EFI_SUCCESS) + goto out; + r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, + *buffer); + if (r == EFI_SUCCESS) + *no_handles = buffer_size / sizeof(efi_handle_t); +out: + return r; +} + /** * efi_locate_handle_buffer() - locate handles implementing a protocol * @search_type: selection criterion @@ -2474,30 +2503,13 @@ efi_status_t EFIAPI efi_locate_handle_buffer( efi_uintn_t *no_handles, efi_handle_t **buffer) { efi_status_t r; - efi_uintn_t buffer_size = 0; EFI_ENTRY("%d, %pUs, %p, %p, %p", search_type, protocol, search_key, no_handles, buffer); - if (!no_handles || !buffer) { - r = EFI_INVALID_PARAMETER; - goto out; - } - *no_handles = 0; - *buffer = NULL; - r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, - *buffer); - if (r != EFI_BUFFER_TOO_SMALL) - goto out; - r = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, buffer_size, - (void **)buffer); - if (r != EFI_SUCCESS) - goto out; - r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, - *buffer); - if (r == EFI_SUCCESS) - *no_handles = buffer_size / sizeof(efi_handle_t); -out: + r = efi_locate_handle_buffer_int(search_type, protocol, search_key, + no_handles, buffer); + return EFI_EXIT(r); } diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index 3164fd484e..5be509f0d6 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -7,6 +7,7 @@ #define LOG_CATEGORY LOGC_EFI +#include #include #include #include @@ -1318,3 +1319,72 @@ out_of_memory: printf("ERROR: Out of memory\n"); return r; } + +/** + * efi_console_get_u16_string() - get user input string + * + * @cin: protocol interface to EFI_SIMPLE_TEXT_INPUT_PROTOCOL + * @buf: buffer to store user input string in UTF16 + * @count: number of u16 string including NULL terminator that buf has + * @filter_func: callback to filter user input + * @row: row number to locate user input form + * @col: column number to locate user input form + * Return: status code + */ +efi_status_t efi_console_get_u16_string(struct efi_simple_text_input_protocol *cin, + u16 *buf, efi_uintn_t count, + efi_console_filter_func filter_func, + int row, int col) +{ + efi_status_t ret; + efi_uintn_t len = 0; + struct efi_input_key key; + + printf(ANSI_CURSOR_POSITION + ANSI_CLEAR_LINE_TO_END + ANSI_CURSOR_SHOW, row, col); + + ret = EFI_CALL(cin->reset(cin, false)); + if (ret != EFI_SUCCESS) + return ret; + + for (;;) { + do { + ret = EFI_CALL(cin->read_key_stroke(cin, &key)); + mdelay(10); + } while (ret == EFI_NOT_READY); + + if (key.unicode_char == u'\b') { + if (len > 0) + buf[--len] = u'\0'; + + printf(ANSI_CURSOR_POSITION + "%ls" + ANSI_CLEAR_LINE_TO_END, row, col, buf); + continue; + } else if (key.unicode_char == u'\r') { + buf[len] = u'\0'; + return EFI_SUCCESS; + } else if (key.unicode_char == 0x3 || key.scan_code == 23) { + return EFI_ABORTED; + } else if (key.unicode_char < 0x20) { + /* ignore control codes other than Ctrl+C, '\r' and '\b' */ + continue; + } else if (key.scan_code != 0) { + /* only accept single ESC press for cancel */ + continue; + } + + if (filter_func) { + if (filter_func(&key) != EFI_SUCCESS) + continue; + } + + if (len >= (count - 1)) + continue; + + buf[len] = key.unicode_char; + len++; + printf(ANSI_CURSOR_POSITION "%ls", row, col, buf); + } +} diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index a8e8521e3e..e5a08f6b59 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -778,3 +778,49 @@ efi_status_t efi_disk_init(void) return EFI_SUCCESS; } + +/** + * efi_disk_get_device_name() - get U-Boot device name associated with EFI handle + * + * @handle: pointer to the EFI handle + * @buf: pointer to the buffer to store the string + * @size: size of buffer + * Return: status code + */ +efi_status_t efi_disk_get_device_name(const efi_handle_t handle, char *buf, int size) +{ + int diskid; + enum uclass_id id; + unsigned int part; + struct udevice *dev; + struct blk_desc *desc; + const char *if_typename; + bool is_partition = false; + struct disk_part *part_data; + + if (!handle || !buf || !size) + return EFI_INVALID_PARAMETER; + + dev = handle->dev; + id = device_get_uclass_id(dev); + if (id == UCLASS_BLK) { + desc = dev_get_uclass_plat(dev); + } else if (id == UCLASS_PARTITION) { + desc = dev_get_uclass_plat(dev_get_parent(dev)); + is_partition = true; + } else { + return EFI_INVALID_PARAMETER; + } + if_typename = blk_get_if_type_name(desc->if_type); + diskid = desc->devnum; + + if (is_partition) { + part_data = dev_get_uclass_plat(dev); + part = part_data->partnum; + snprintf(buf, size, "%s %d:%d", if_typename, diskid, part); + } else { + snprintf(buf, size, "%s %d", if_typename, diskid); + } + + return EFI_SUCCESS; +} diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c index 7a7077e6d0..c96a7f7ca3 100644 --- a/lib/efi_loader/efi_file.c +++ b/lib/efi_loader/efi_file.c @@ -246,10 +246,10 @@ error: return NULL; } -static efi_status_t efi_file_open_int(struct efi_file_handle *this, - struct efi_file_handle **new_handle, - u16 *file_name, u64 open_mode, - u64 attributes) +efi_status_t efi_file_open_int(struct efi_file_handle *this, + struct efi_file_handle **new_handle, + u16 *file_name, u64 open_mode, + u64 attributes) { struct file_handle *fh = to_fh(this); efi_status_t ret; @@ -369,11 +369,17 @@ static efi_status_t file_close(struct file_handle *fh) return EFI_SUCCESS; } -static efi_status_t EFIAPI efi_file_close(struct efi_file_handle *file) +efi_status_t efi_file_close_int(struct efi_file_handle *file) { struct file_handle *fh = to_fh(file); + + return file_close(fh); +} + +static efi_status_t EFIAPI efi_file_close(struct efi_file_handle *file) +{ EFI_ENTRY("%p", file); - return EFI_EXIT(file_close(fh)); + return EFI_EXIT(efi_file_close_int(file)); } static efi_status_t EFIAPI efi_file_delete(struct efi_file_handle *file) @@ -562,8 +568,8 @@ static efi_status_t dir_read(struct file_handle *fh, u64 *buffer_size, return EFI_SUCCESS; } -static efi_status_t efi_file_read_int(struct efi_file_handle *this, - efi_uintn_t *buffer_size, void *buffer) +efi_status_t efi_file_read_int(struct efi_file_handle *this, + efi_uintn_t *buffer_size, void *buffer) { struct file_handle *fh = to_fh(this); efi_status_t ret = EFI_SUCCESS; @@ -773,24 +779,11 @@ out: return EFI_EXIT(ret); } -/** - * efi_file_setpos() - set current position in file - * - * This function implements the SetPosition service of the EFI file protocol. - * See the UEFI spec for details. - * - * @file: file handle - * @pos: new file position - * Return: status code - */ -static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, - u64 pos) +efi_status_t efi_file_setpos_int(struct efi_file_handle *file, u64 pos) { struct file_handle *fh = to_fh(file); efi_status_t ret = EFI_SUCCESS; - EFI_ENTRY("%p, %llu", file, pos); - if (fh->isdir) { if (pos != 0) { ret = EFI_UNSUPPORTED; @@ -812,6 +805,28 @@ static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, fh->offset = pos; error: + return ret; +} + +/** + * efi_file_setpos() - set current position in file + * + * This function implements the SetPosition service of the EFI file protocol. + * See the UEFI spec for details. + * + * @file: file handle + * @pos: new file position + * Return: status code + */ +static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, + u64 pos) +{ + efi_status_t ret = EFI_SUCCESS; + + EFI_ENTRY("%p, %llu", file, pos); + + ret = efi_file_setpos_int(file, pos); + return EFI_EXIT(ret); } @@ -1138,17 +1153,23 @@ struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp) return f; } +efi_status_t efi_open_volume_int(struct efi_simple_file_system_protocol *this, + struct efi_file_handle **root) +{ + struct file_system *fs = to_fs(this); + + *root = file_open(fs, NULL, NULL, 0, 0); + + return EFI_SUCCESS; +} + static efi_status_t EFIAPI efi_open_volume(struct efi_simple_file_system_protocol *this, struct efi_file_handle **root) { - struct file_system *fs = to_fs(this); - EFI_ENTRY("%p, %p", this, root); - *root = file_open(fs, NULL, NULL, 0, 0); - - return EFI_EXIT(EFI_SUCCESS); + return EFI_EXIT(efi_open_volume_int(this, root)); } struct efi_simple_file_system_protocol * From patchwork Fri Jul 15 14:27:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 590836 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:5817:0:0:0:0 with SMTP id j23csp551517max; Fri, 15 Jul 2022 07:25:32 -0700 (PDT) X-Google-Smtp-Source: AGRyM1ssll1QgTq1E9QlUfUb7Ft4dZx3dSLw6uuuN9gW6+346FUrCvBCR56ooZRZ4TGBs6G8HbCY X-Received: by 2002:a05:6638:31c2:b0:335:dd22:83ec with SMTP id n2-20020a05663831c200b00335dd2283ecmr7731720jav.88.1657895132146; Fri, 15 Jul 2022 07:25:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657895132; cv=none; d=google.com; s=arc-20160816; b=AnZVZ7FqGGLBAd1MlejNL6sQi1j4qi5qpXE84R8rQRszMQK8w90gCdW7o+MeLNRdOK 9KLOtm35ivda83BYM/in4NH1OYNb3RLMxHuE9iwtBWabQMPQaN9DbyN3mWrKpZjNpTck 5jFxEyYd9BCoQVnZucty2ySY69ntUsXMSkFk4k9w8vV9vA+zI4MwVeBGScf7tUFP3Fp8 fhqxyXcqUOW0uDciiE4n08ZAisk7ONxRdjmMtLz+GYUEIpKjjshhwStAsm5SONbivd77 qJeVsbCubJC7uM5TksA9X4QoqUV9NKLHQ6uQEQVq0urqUAf2A6DWgFLJmSBTL09hX6US vkVg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=aQaX4258rFTXTFVQ01ZAB87u4TgPi8pZqYYB5qeGH1A=; b=vvWiq6cxsBsPuc/a+cVbLVcxBepBvsMnYU/HrJe9N7ZS21oSbXwOiRg/u5ckwcwoDw Y7x5RGSA0APdytRbC+XUo4pgS1c0LtrVUL9Cc3bbtPWcBcSKtbgrnehrU10fgmfXIfCD j65cdFFMZP9Ma7OFkHjq3V1uopgKTjAm8beDz2lZ1uia7Ws79g6Yy3WVt9CWPlVkEyKV aEGma224tVmDNsef1IMAvbJxBTDfP+4AKyJb2sOlMptifC9bHYGTnSjYcWk82YgKzSNg xijgE/jIH1rvOqSZ8s/aMZC9jO1iIkYCzUgpA/g9l+pSF5GwBYOx2lrLAiZzE3nKsg5G GA3Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=au7pmbd6; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id ay4-20020a5d9d84000000b0067b997b8b12si4536687iob.88.2022.07.15.07.25.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:25:32 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=au7pmbd6; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 4CD7781118; Fri, 15 Jul 2022 16:25:12 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="au7pmbd6"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 407A581118; Fri, 15 Jul 2022 16:25:11 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 8D62B81118 for ; Fri, 15 Jul 2022 16:25:06 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pl1-x633.google.com with SMTP id w7so3358391ply.12 for ; Fri, 15 Jul 2022 07:25:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=aQaX4258rFTXTFVQ01ZAB87u4TgPi8pZqYYB5qeGH1A=; b=au7pmbd6Rxy038k0/ZjwGcpmymY3hOW46eHZN2NT2bIAHtxISNiQEJPdMSvyxtfS+F A/QLO6tNdCfWYhhNGO7H+6G92YU3JuhVUQ8roCP4CfmCnTFAxH+d0LAr/s2pxcUdClpf flDlRr0uANI6hg+kEtf5SU9sFXC1kS4zC57v0SQM+684bWC4noz+O7AHOc0lOwe8NKuX 8QCIw9pTwMwjqStASYV88b87oBdOfU3ayPhtJziN5eIVYIUXEPIifzpLJtRVFTOAfKyz FIqi8ZkJES+xkJjcOCxpYobbc9XCVb39/0vSOGcmWoz5EAYuhzpAsyeh0+VHH7XmcqyL 1K5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=aQaX4258rFTXTFVQ01ZAB87u4TgPi8pZqYYB5qeGH1A=; b=mx0b0tQUdDs0RisjFzZqHAcpAbC3GWhr6cqXzsYFQcpvXIJMyn9bOeGiEdptgWFKhE 2V1dsGrkV4T01a9lXUg29IMMXlJ0lSu7fXSKhBoqND+cRxDM5WpbtkRa8/+uOAkv+5lQ YzBeVB/FzbOoa2XpAF7D1KZbDeUWw17Ag1M8ry0eAoRxMbNEhGDsYkgCATQCUW+kMHfr ih+MKhWa3hQV+kA4OiIEqhUDssrjV0l5Y6rKu5gQ32dN7v+epkx5MtHP1G23kwOOHjaI AzqSbHcNbFeGnSMPiRQConeShQ/7tQA877Emmeemn37GjBzZHyJpg0MJoTaWcCXfr6vH cLvQ== X-Gm-Message-State: AJIora/neoFaJk7WZZuDq0GluE2yYT0EaxnFmGqfEZWE8862p+WkA4iq awsAoCjTLhlZ+yZ47ysO2aFenE8wQZV5/Q== X-Received: by 2002:a17:90a:b114:b0:1ef:7d95:347 with SMTP id z20-20020a17090ab11400b001ef7d950347mr23030901pjq.137.1657895104528; Fri, 15 Jul 2022 07:25:04 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id d22-20020aa797b6000000b0051c49fb62b7sm3891174pfq.165.2022.07.15.07.25.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:25:04 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Mark Kettenis , Masahisa Kojima Subject: [PATCH 3/9] eficonfig: add "Edit Boot Option" menu entry Date: Fri, 15 Jul 2022 23:27:37 +0900 Message-Id: <20220715142743.30137-4-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220715142743.30137-1-masahisa.kojima@linaro.org> References: <20220715142743.30137-1-masahisa.kojima@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean This commit adds the menu entry to edit the existing BOOT#### variable contents. User selects the item from the boot option list, then user can edit the description, file path and optional_data. Note that automatically generated boot option entry by bootmenu to support the removable media device is filtered out and user can not edit the automatically generated entry. Signed-off-by: Masahisa Kojima --- Changes in v9: - add function comment Changes in v8: - fix menu header string - fix function and structure prefix to "eficonfig" Newly created in v7 cmd/eficonfig.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index 235d5014c7..d923afe726 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -78,6 +78,17 @@ struct eficonfig_file_entry_data { u16 *file_name; }; +/** + * struct eficonfig_boot_selection_data - structure to be used to select the boot option entry + * + * @bootorder_index: index in the BootOrder variable + * @selected: pointer to store the selected index in the BootOrder variable + */ +struct eficonfig_boot_selection_data { + u16 bootorder_index; + int *selected; +}; + /** * eficonfig_print_msg() - print message * @@ -1246,6 +1257,196 @@ out: return ret; } +/** + * eficonfig_process_boot_selected() - handler to select boot option entry + * + * @data: pointer to the data for each entry + * Return: status code + */ +static efi_status_t eficonfig_process_boot_selected(void *data) +{ + struct eficonfig_boot_selection_data *info = data; + + if (info) + *info->selected = info->bootorder_index; + + return EFI_SUCCESS; +} + +/** + * eficonfig_show_boot_selection() - construct boot option menu entry + * + * @bootorder: pointer to the BootOrder variable + * @count: the number of BootOrder + * @selected: pointer to store the selected index of BootOrder variable + * Return: status code + */ +static efi_status_t eficonfig_show_boot_selection(u16 *bootorder, efi_uintn_t count, + int *selected) +{ + u32 i; + efi_status_t ret; + efi_uintn_t size, actual_count = 1; /* include "Quit" entry */ + void *load_option; + struct efi_load_option lo; + u16 varname[] = u"Boot####"; + struct eficonfig_item *menu_item, *iter; + + menu_item = calloc(count + 1, sizeof(struct eficonfig_item)); + if (!menu_item) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + iter = menu_item; + for (i = 0; i < count; i++) { + efi_create_indexed_name(varname, sizeof(varname), + "Boot", bootorder[i]); + load_option = efi_get_var(varname, &efi_global_variable_guid, &size); + if (!load_option) + continue; + + ret = efi_deserialize_load_option(&lo, load_option, &size); + if (ret != EFI_SUCCESS) { + log_warning("Invalid load option for %ls\n", varname); + free(load_option); + continue; + } + + if (size >= sizeof(efi_guid_t) && + !guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated)) { + /* + * auto generated entry has GUID in optional_data, + * skip auto generated entry because it will be generated + * again even if it is edited or deleted. + */ + free(load_option); + continue; + } + + if (lo.attributes & LOAD_OPTION_ACTIVE) { + char *buf, *p; + struct eficonfig_boot_selection_data *info; + + info = calloc(1, sizeof(struct eficonfig_boot_selection_data)); + if (!info) { + free(load_option); + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + buf = calloc(1, utf16_utf8_strlen(lo.label) + 1); + if (!buf) { + free(load_option); + free(info); + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + p = buf; + utf16_utf8_strcpy(&p, lo.label); + info->bootorder_index = i; + info->selected = selected; + iter->title = buf; + iter->func = eficonfig_process_boot_selected; + iter->data = info; + iter++; + actual_count++; + } + free(load_option); + } + + /* add "Quit" entry */ + iter->title = strdup("Quit"); + iter->func = eficonfig_process_quit; + iter->data = NULL; + + ret = eficonfig_process_common(menu_item, actual_count, " ** Select Boot Option **"); + +out: + iter = menu_item; + for (i = 0; i < actual_count; i++, iter++) { + free(iter->title); + free(iter->data); + } + + free(menu_item); + + return ret; +} + +/** + * eficonfig_process_edit_boot_option() - handler to edit boot option + * + * @data: pointer to the data for each entry + * Return: status code + */ +static efi_status_t eficonfig_process_edit_boot_option(void *data) +{ + u16 *bootorder; + efi_status_t ret; + efi_uintn_t num, size; + struct eficonfig_boot_option *bo = NULL; + + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + if (!bootorder) { + eficonfig_print_msg("BootOrder is not defined!"); + ret = EFI_NOT_FOUND; + return ret; + } + + num = size / sizeof(u16); + while (1) { + int selected; + void *load_option; + struct efi_load_option lo; + u16 varname[] = u"Boot####"; + + ret = eficonfig_show_boot_selection(bootorder, num, &selected); + if (ret != EFI_SUCCESS) + break; + + bo = calloc(1, sizeof(struct eficonfig_boot_option)); + if (!bo) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + bo->boot_index = selected; + efi_create_indexed_name(varname, sizeof(varname), + "Boot", bootorder[selected]); + load_option = efi_get_var(varname, &efi_global_variable_guid, &size); + if (!load_option) { + free(bo); + ret = EFI_NOT_FOUND; + goto out; + } + + ret = efi_deserialize_load_option(&lo, load_option, &size); + if (ret != EFI_SUCCESS) { + free(bo); + free(load_option); + goto out; + } + + ret = eficonfig_edit_boot_option(varname, bo, lo.label, lo.optional_data, + size, lo.file_path, + " ** Edit Boot Option ** "); + + free(load_option); + free(bo); + if (ret != EFI_SUCCESS && ret != EFI_ABORTED) + break; + } + +out: + free(bootorder); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + /** * eficonfig_init() - do required initialization for eficonfig command * @@ -1275,6 +1476,7 @@ static efi_status_t eficonfig_init(void) static const struct eficonfig_item maintenance_menu_items[] = { {"Add Boot Option", eficonfig_process_add_boot_option}, + {"Edit Boot Option", eficonfig_process_edit_boot_option}, {"Quit", eficonfig_process_quit}, }; From patchwork Fri Jul 15 14:27:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 590837 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:5817:0:0:0:0 with SMTP id j23csp551705max; Fri, 15 Jul 2022 07:25:45 -0700 (PDT) X-Google-Smtp-Source: AGRyM1un5S4x23p0xb/AYehoDxI/wuCYoKYteqCz/N9Ys5YLJZr/y/IMUq+GaVXQWx+MS6omOUJ8 X-Received: by 2002:a05:6602:14d:b0:67b:9536:680f with SMTP id v13-20020a056602014d00b0067b9536680fmr7148646iot.202.1657895144867; Fri, 15 Jul 2022 07:25:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657895144; cv=none; d=google.com; s=arc-20160816; b=G1MGD4N8Fbclby0T5knVaEvgIGgbIZfFoaqiUQKX89peD7KgrQ+lr9CKzf/w+Z9vlK smllQFW53ddsUR1gPRhSFvfV+Sdris2Mr1sc5wBGP9riNt4ImCCq0g3c5AjwfAzEGJWK dWQGIFj5dqxcbHZiGpJMwYfDi2/hpS4PLN8rJrIKnhCapPe4qsibh1bIcZSu7cti/vZx 7B8tL4u2BJT9AyIMY1XQu33BlIHRBK4BZsyqyuSkEtbsVd/l4MZgdgk2SWt+sb66EYIw Ow3fUR+5DNw18Rs8S6nMPu1eZXBaW57+/3+W9DbnLSaD3h8JX/UkX/P3OEVIFnmEcdRO ZKsg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=w+mVP1Njm31l7f2XbiAc9Nmn/WOjAcUUdc/0fUHeZ54=; b=fK8icVWsldPkqsMCBEmKIvT3E9eQd54wa+eYRCPJqrn6hJVZi4kDlFXm8i8Ud9qw7h mtgcF4JisyWX2BX7IU9mjyddKXQwexcaLjlVyGbc1hm0Q2Rmnzu/Zhcc58no2ezigTpF BTeojG5dd5ppEp2DKBrvaxHgqqiFyZhT4uMMlrNyl0bjldDFVrEMnrl2mz6xS7TkuQKI /m7Sh3GBpGvT9yk8DlyQTN51KDf2jHz+Y5JzU321X6JVXRLctqOiIeORWGpF07W8J+Tf 5ZgpBbkuf4xSntsU+c1pgTYWc3h+O/ZljaRreZL51T+Ghd6zm2nZFiAjDjVBl7svuw7g EPMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="k7x/uRlS"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id l7-20020a6b3e07000000b00657bc68c9e2si3977780ioa.53.2022.07.15.07.25.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:25:44 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="k7x/uRlS"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 888FA8191C; Fri, 15 Jul 2022 16:25:18 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="k7x/uRlS"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 0D34C81872; Fri, 15 Jul 2022 16:25:14 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pg1-x536.google.com (mail-pg1-x536.google.com [IPv6:2607:f8b0:4864:20::536]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 6B2C6811CA for ; Fri, 15 Jul 2022 16:25:09 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pg1-x536.google.com with SMTP id e132so4544422pgc.5 for ; Fri, 15 Jul 2022 07:25:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=w+mVP1Njm31l7f2XbiAc9Nmn/WOjAcUUdc/0fUHeZ54=; b=k7x/uRlSj5tYgsKZxfngKGcNfDylTTeoccpPkVSxVN4Hz0JKModuvtYUUX2y1W7KsB /z2oNtOwMj4x4LBLVt/rYCLmNO4+loBJh/qxzZ7dcARQrL64DawofVuFUeHxCN3+rJjC DL7k7dAdag38RXdvk9UKFJ6JL63izRsQwD/WgbIpxXzcHpYl1DMYOAjcf74jm4Zspsdo OkmousrCor3A7Y0usRj+WzZlm3g7ZrcG7PNoZY2PvYK5uqImhcWOBV5/vmXhXscpgLHd JVir6QsHRNpU+C6fPzl9DQeE282HTu8AK17JpDOMZtHCXHC624H74gjRMgvBgUY9T74b T45g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=w+mVP1Njm31l7f2XbiAc9Nmn/WOjAcUUdc/0fUHeZ54=; b=BXAZGN2poLw5OyGsHB0JnPud0NOMDjkT2Z1PBevC3DISyjyI0NWE6ozyZwtEVPO+5T eRActhrXW+m34PB77zmSSH/kzJ6vAXM412I+B6M3etQ5OUQeMc0BbiUeW9mgOBXxvZSa oH45KWwwDtaihH0GF8NIkn68wudOtg0Gf7dc0TLVwKgOkdT6nmawCN59JUuXA+tRz8CY qKbuzr9BrF9Ob0cJStwoGLJCqw83ckny3/fn/22qCtxt9MbtGiXoalYnM6RCJWc7SeEJ 87MLEz+CuqfpVYYsfvkwjMnYhg5bZnyAQr50ReQKTRZ2I+jFSASARz8pPlCSkjsJ56m5 yHiA== X-Gm-Message-State: AJIora8jyU9Q28+caV9r6p4MHxMEoZHlzWLBI4OpeAVRrDw28CvSD0pg sutOKWijet2FkumVULo6LiVzGpaKt9Qodg== X-Received: by 2002:a63:551:0:b0:419:9286:56 with SMTP id 78-20020a630551000000b0041992860056mr11565694pgf.267.1657895107324; Fri, 15 Jul 2022 07:25:07 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id d22-20020aa797b6000000b0051c49fb62b7sm3891174pfq.165.2022.07.15.07.25.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:25:06 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Mark Kettenis , Masahisa Kojima Subject: [PATCH 4/9] menu: add KEY_PLUS and KEY_MINUS handling Date: Fri, 15 Jul 2022 23:27:38 +0900 Message-Id: <20220715142743.30137-5-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220715142743.30137-1-masahisa.kojima@linaro.org> References: <20220715142743.30137-1-masahisa.kojima@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean This is preparation to support menu-driven UEFI BootOrder variable updated by KEY_PLUS and KEY_MINUS. Signed-off-by: Masahisa Kojima Reviewed-by: Heinrich Schuchardt --- No change since v7 Newly created in v7 common/menu.c | 6 ++++++ include/menu.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/common/menu.c b/common/menu.c index 3e876b55b3..3470f95a98 100644 --- a/common/menu.c +++ b/common/menu.c @@ -548,4 +548,10 @@ void bootmenu_loop(struct bootmenu_data *menu, /* ^C was pressed */ if (c == 0x3) *key = KEY_QUIT; + + if (c == '+') + *key = KEY_PLUS; + + if (c == '-') + *key = KEY_MINUS; } diff --git a/include/menu.h b/include/menu.h index e74616cae8..4c32e74ce9 100644 --- a/include/menu.h +++ b/include/menu.h @@ -48,6 +48,8 @@ enum bootmenu_key { KEY_DOWN, KEY_SELECT, KEY_QUIT, + KEY_PLUS, + KEY_MINUS, }; void bootmenu_autoboot_loop(struct bootmenu_data *menu, From patchwork Fri Jul 15 14:27:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 590838 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:5817:0:0:0:0 with SMTP id j23csp551913max; Fri, 15 Jul 2022 07:25:57 -0700 (PDT) X-Google-Smtp-Source: AGRyM1sC109MdXZ2HOHgqjLjslxCKH/Rwk3mpFAnN0leaoWrJlzvn7oTiEW26QccFojPlmli96wh X-Received: by 2002:a02:a918:0:b0:33f:2a28:a2c6 with SMTP id n24-20020a02a918000000b0033f2a28a2c6mr7858635jam.8.1657895157677; Fri, 15 Jul 2022 07:25:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657895157; cv=none; d=google.com; s=arc-20160816; b=V8qHMO5oKaFFff1wTQpbIs44iUFePvdQrFuD4JiMNogq/T740h9/AyJmR1fTsCRila GG+WkxbyDnyaKxHUKux4/mJZ/HnPJAxzZ/RiIjKisb0OLveupylV6X9chdNYQepkk7+5 MCy6YP2S4oWMeXr2c66Bt7cuLbtxCAYwYBIOEeImQjWnShgeUuxL3iuKYCTSbsCI8S3l sXqdp2GitrQQypIXfPJyMXv3rABdjnQ35i5sYHMZ9pwv1iFY63Qi6TIUVYM+lHqTwij5 bSanBJssTpA3HLAyZgyhET4HS0nwDJe59MEqRl9S1Zhp5ABmvJKtbgeOoJiB7dO3AY2x OnSg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=M/lT3nJ1t8yhYNtoubxwDJTFByAtQ3M/a3iGy6nNdVU=; b=DoE8F4iQnmneng8rvh8kdcV7tToc4OKRBQOIEMCQg6I8LaBnWZ5B068fuPVsJw69gb Z47xkHYBKhZGjTNSgKxo/TiWLh2JXpqaa4KaNivzX25cT/PL4nqrUe+zunMS2jAbrHDO 3358FFnbdhPxx9CvJ6i6v/qyiZoSmbAMeSOGjSjK5C/J/GiaDMHOKv+dfDXoCsJtg2Bu kPz8/63DQEeiXI8h+6tRmNvuJGfoegUNROMLh4eVMZritgdC1ZeJuai92YHsJT7k0uOD YbIe4xrAFTbrcSSXf/5/+Sm1xKuIKw59yhG6MPTv7ZbTwSZfSCNB2XPP0byehoqPA9Rp hKkw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=th5m9OQC; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id t7-20020a056638348700b00331bd236a45si6780999jal.109.2022.07.15.07.25.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:25:57 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=th5m9OQC; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 0AC7381F5D; Fri, 15 Jul 2022 16:25:27 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="th5m9OQC"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id EEE0B81875; Fri, 15 Jul 2022 16:25:18 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 89B968156B for ; Fri, 15 Jul 2022 16:25:12 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pj1-x102d.google.com with SMTP id a15so5863252pjs.0 for ; Fri, 15 Jul 2022 07:25:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=M/lT3nJ1t8yhYNtoubxwDJTFByAtQ3M/a3iGy6nNdVU=; b=th5m9OQCJO4DF5E8GbLFCXc+9nqS942VU0U+SH4jWRLTVU92HzvzHQwNh0VfktOxQj 8XCAEIBNrFAt5TKbmhPRlVWr6BBqpp3iAn0Y/jFl8/ib390UC+d1/SaVisCga3awr6YZ Be75SP9gQzvowjyB0R1bwpub1qgox4GwemBFr56ICGenXgVjwTqRkH8CxffXjAQMxm9l WeM+DPzAlxtQayFyLSEq1gw2TpAgNx2ZXepOBEVfDrmIcPNWpfKHZoOIcid7WneSetCG dKiZAkSFSE75aPlAXWC5FyGcuXCtA8iLv9x2C7ecwQQ4XlZgn8DBxa/S8k7rafrqjlVT AKVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=M/lT3nJ1t8yhYNtoubxwDJTFByAtQ3M/a3iGy6nNdVU=; b=OcYJN7EHVR2WWOjzp0PD+ZqQXGCriMJ3eTBb0+tGWxDj6s6U3bybPkcIwoCtu6nKCY JVXEahE1xrRf4jszL7PB3D3JdGFFjbI/Z1WU3fOAvXKaRlwBaVda5D0lCe9ywWP2XWAb rYqeqA9DSTkesbnWyG0Mwv9Z3e8Fta2gF1+RRh445/lpwuUyF5YIp1bowKzTuWSPVJPx CmiylCn2FvKigsSR8Msk/SGIj3nl9SCECaAJc8X1r+Ggm9YrSVmOlOp7EmK7xlMQZvNI d0QZVSLHHHXGYUwR5h2C2UDKb1/w5vKz/0xsQ7ZGf2yJ6UhFp6lPILz2BKY6uuZg67dg uwng== X-Gm-Message-State: AJIora8g3wHFujyrnhozIrSYpLAU63cTUubNAu2KXG3Xxx7P1rBbMoer vYLCKZrbwlXUnrc/ZzyrtLNHG+hZr865vA== X-Received: by 2002:a17:90b:4d85:b0:1ef:9fd2:b789 with SMTP id oj5-20020a17090b4d8500b001ef9fd2b789mr22438906pjb.196.1657895110372; Fri, 15 Jul 2022 07:25:10 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id d22-20020aa797b6000000b0051c49fb62b7sm3891174pfq.165.2022.07.15.07.25.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:25:10 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Mark Kettenis , Masahisa Kojima Subject: [PATCH 5/9] eficonfig: add "Change Boot Order" menu entry Date: Fri, 15 Jul 2022 23:27:39 +0900 Message-Id: <20220715142743.30137-6-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220715142743.30137-1-masahisa.kojima@linaro.org> References: <20220715142743.30137-1-masahisa.kojima@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean This commit adds the menu entry to update UEFI BootOrder variable. User moves the entry with UP/DOWN key, changes the order with PLUS/MINUS key, then finalizes the order by ENTER key. The U-Boot menu framework is well designed for static menu, this commit implements the own menu display and key handling for dynamically change the order of menu entry. Signed-off-by: Masahisa Kojima --- Changes in v9: - add function comment Changes in v8: - add "Save" and "Quit" entries Changes in v7: - use UP/DOWN and PLUS/MINUS key to change to order no update in v6: cmd/eficonfig.c | 265 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index d923afe726..aeb60f1d09 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -89,6 +89,21 @@ struct eficonfig_boot_selection_data { int *selected; }; +/** + * struct eficonfig_boot_order - structure to be used to update BootOrder variable + * + * @num: index in the menu entry + * @description: pointer to the description string + * @prev_index: index in the BootOrder variable before changing order + * @list: list structure + */ +struct eficonfig_boot_order { + u32 num; + u16 *description; + u32 prev_index; + struct list_head list; +}; + /** * eficonfig_print_msg() - print message * @@ -1447,6 +1462,255 @@ out: return ret; } +/** + * eficonfig_display_change_boot_order() - display the BootOrder list + * + * @bo_list: pointer to the list structure + * @efi_menu: pointer to the efimenu structure + * Return: status code + */ +static void eficonfig_display_change_boot_order(struct list_head *bo_list, + struct efimenu *efi_menu) +{ + bool reverse; + struct list_head *pos, *n; + struct eficonfig_boot_order *entry; + + printf(ANSI_CLEAR_CONSOLE + ANSI_CURSOR_POSITION + "\n ** Change Boot Order **\n" + ANSI_CURSOR_POSITION + "\n" + " Press UP/DOWN to move, +/- to change order\n ENTER to complete, ESC/CTRL+C to quit" + ANSI_CURSOR_POSITION, + 0, 1, efi_menu->count + 5, 1, 4, 1); + + /* draw boot order list */ + list_for_each_safe(pos, n, bo_list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + reverse = (entry->num == efi_menu->active); + puts(" "); + if (reverse) + puts(ANSI_COLOR_REVERSE); + + printf("%ls\n", entry->description); + + if (reverse) + puts(ANSI_COLOR_RESET); + } +} + +/** + * eficonfig_choice_change_boot_order() - handle the BootOrder update + * + * @bo_list: pointer to the list structure + * @efi_menu: pointer to the efimenu structure + * Return: status code + */ +static efi_status_t eficonfig_choice_change_boot_order(struct list_head *bo_list, + struct efimenu *efi_menu) +{ + int esc = 0; + struct list_head *pos, *n; + struct eficonfig_boot_order *tmp; + enum bootmenu_key key = KEY_NONE; + struct eficonfig_boot_order *entry; + + while (1) { + bootmenu_loop(NULL, &key, &esc); + + switch (key) { + case KEY_PLUS: + if (efi_menu->active > 0) { + list_for_each_safe(pos, n, bo_list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + if (entry->num == efi_menu->active) + break; + } + tmp = list_entry(pos->prev, struct eficonfig_boot_order, list); + entry->num--; + tmp->num++; + list_del(&tmp->list); + list_add(&tmp->list, &entry->list); + } + fallthrough; + case KEY_UP: + if (efi_menu->active > 0) + --efi_menu->active; + return EFI_NOT_READY; + case KEY_MINUS: + if (efi_menu->active < efi_menu->count - 3) { + list_for_each_safe(pos, n, bo_list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + if (entry->num == efi_menu->active) + break; + } + tmp = list_entry(pos->next, struct eficonfig_boot_order, list); + entry->num++; + tmp->num--; + list_del(&entry->list); + list_add(&entry->list, &tmp->list); + + ++efi_menu->active; + } + return EFI_NOT_READY; + case KEY_DOWN: + if (efi_menu->active < efi_menu->count - 1) + ++efi_menu->active; + return EFI_NOT_READY; + case KEY_SELECT: + /* "Save" */ + if (efi_menu->active == efi_menu->count - 2) + return EFI_SUCCESS; + + /* "Quit" */ + if (efi_menu->active == efi_menu->count - 1) + return EFI_ABORTED; + + break; + case KEY_QUIT: + return EFI_ABORTED; + default: + break; + } + } +} + +/** + * eficonfig_process_change_boot_order() - handler to change boot order + * + * @data: pointer to the data for each entry + * Return: status code + */ +static efi_status_t eficonfig_process_change_boot_order(void *data) +{ + u32 i; + u16 *bootorder; + efi_status_t ret; + efi_uintn_t num, size; + struct list_head bo_list; + struct list_head *pos, *n; + struct eficonfig_boot_order *entry; + struct efimenu efi_menu; + + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + if (!bootorder) { + eficonfig_print_msg("BootOrder is not defined!"); + ret = EFI_NOT_FOUND; + return ret; + } + + INIT_LIST_HEAD(&bo_list); + + num = size / sizeof(u16); + for (i = 0; i < num; i++) { + void *load_option; + struct efi_load_option lo; + u16 varname[] = u"Boot####"; + + efi_create_indexed_name(varname, sizeof(varname), + "Boot", bootorder[i]); + load_option = efi_get_var(varname, &efi_global_variable_guid, &size); + if (!load_option) { + ret = EFI_NOT_FOUND; + goto out; + } + + ret = efi_deserialize_load_option(&lo, load_option, &size); + if (ret != EFI_SUCCESS) { + free(load_option); + goto out; + } + + entry = calloc(1, sizeof(struct eficonfig_boot_order)); + if (!entry) { + free(load_option); + goto out; + } + entry->num = i; + entry->description = u16_strdup(lo.label); + entry->prev_index = i; + list_add_tail(&entry->list, &bo_list); + + free(load_option); + } + + /* add "Save" and "Quit" entries */ + entry = calloc(1, sizeof(struct eficonfig_boot_order)); + if (!entry) + goto out; + + entry->num = i++; + entry->description = u16_strdup(u"Save"); + entry->prev_index = 0; + list_add_tail(&entry->list, &bo_list); + + entry = calloc(1, sizeof(struct eficonfig_boot_order)); + if (!entry) + goto out; + + entry->num = i++; + entry->description = u16_strdup(u"Quit"); + entry->prev_index = 0; + list_add_tail(&entry->list, &bo_list); + + efi_menu.delay = -1; + efi_menu.active = 0; + efi_menu.count = i; + + while (1) { + eficonfig_display_change_boot_order(&bo_list, &efi_menu); + + ret = eficonfig_choice_change_boot_order(&bo_list, &efi_menu); + if (ret == EFI_SUCCESS) { + u32 i = 0; + u16 *new_bootorder; + + /* update the BootOrder variable */ + size = num * sizeof(u16); + new_bootorder = calloc(1, size); + if (!new_bootorder) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + list_for_each_safe(pos, n, &bo_list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + new_bootorder[i] = bootorder[entry->prev_index]; + i++; + } + + ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, new_bootorder, false); + + free(new_bootorder); + goto out; + } else if (ret == EFI_NOT_READY) { + continue; + } else { + goto out; + } + } + +out: + list_for_each_safe(pos, n, &bo_list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + list_del(&entry->list); + free(entry->description); + free(entry); + } + + free(bootorder); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + /** * eficonfig_init() - do required initialization for eficonfig command * @@ -1477,6 +1741,7 @@ static efi_status_t eficonfig_init(void) static const struct eficonfig_item maintenance_menu_items[] = { {"Add Boot Option", eficonfig_process_add_boot_option}, {"Edit Boot Option", eficonfig_process_edit_boot_option}, + {"Change Boot Order", eficonfig_process_change_boot_order}, {"Quit", eficonfig_process_quit}, }; From patchwork Fri Jul 15 14:27:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 590841 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:5817:0:0:0:0 with SMTP id j23csp552680max; Fri, 15 Jul 2022 07:26:46 -0700 (PDT) X-Google-Smtp-Source: AGRyM1sfmEgJz0ldQgD+eyGHOitceCSkp0piHyyWPGQ2gL5NkJzCkk8X1YGSwvVV/9CbmtR0yJYU X-Received: by 2002:a02:2a4e:0:b0:33e:e3c8:35c2 with SMTP id w75-20020a022a4e000000b0033ee3c835c2mr7992732jaw.170.1657895206551; Fri, 15 Jul 2022 07:26:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657895206; cv=none; d=google.com; s=arc-20160816; b=i3rh4k3LwRP8PF/c6pzXH94CsL6Ba8l0deLh0CPo0oboLrOQHGkUBVTj+mvMT+fCSy hJW9FnvSrSGhNWakTKbuSbhuv/5RBwXvtNq5L7Muw11A97fQ0aetR0A3rw7kbPrBh6Sn 5r7zAY9w7yi11tKgfsRi105mAkGn4DvDaRWqJXxbmjAr9WDxQp9Hq07EPAcE5aq8oGhf 0a/K9Q5C6hqbta1LiqeUMGA8GeBlPgtnWxK/8DOGYdo+DFP78VqTcEqOPhrrlZMwDs7z OK4V7DEx7yiHyfmhNYCY7NP8Y+YDwLVOwsTJZK851XWEEMsObrvVzO8ReW0flXg43XoR 2F7g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=oIBrTySaJzlZ/PX304+FIQ1DHdTIHBezsK/WkUhJzrI=; b=eCiXPXqLpqZ5nxJ001gi9l9VFBaO7KxiSqb1OKwLm5xXiyvIzqIB9kaGHf17SmkfPY cZPaKfviGVz5hhnmWvkOOCZJT45ptVA2/MRPgnxFYTQ1A5HS2Qw3fNeMcDGJ/QcN+V1l JnOstXg0/4QzNDQLDDuUceZPmFCH/WVYdZ4UJLDORnGe03O0oAG1O6v+y7jjrk6AQNse 97ydhfpRWgqdEcgY6UI/Qw7GbhXpVIMpv2zS26JuC9+0fsqWhLTfmCYW2dJw2M1ONhCB 4Sd+u18L3yH132yNZf/vHMCogs3lOwbXQ27RqPQBlLSKwglGN/90SierIdrWUZ2h35zK mPqA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KZlu8maR; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id h14-20020a92c26e000000b002dc2dea6bfasi4902637ild.104.2022.07.15.07.26.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:26:46 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=KZlu8maR; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 330B78110C; Fri, 15 Jul 2022 16:25:48 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="KZlu8maR"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id AD199814BD; Fri, 15 Jul 2022 16:25:25 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x430.google.com (mail-pf1-x430.google.com [IPv6:2607:f8b0:4864:20::430]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id D41D1819B1 for ; Fri, 15 Jul 2022 16:25:15 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pf1-x430.google.com with SMTP id l124so4778203pfl.8 for ; Fri, 15 Jul 2022 07:25:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=oIBrTySaJzlZ/PX304+FIQ1DHdTIHBezsK/WkUhJzrI=; b=KZlu8maR0Kd2Ed4TLW/E/h30ceyvNL1VLkFcVVbckLlbawrKheoOFIyEfvivRPyfr9 ZFfntu2W+Kiv4PNEGCVsXpyxGDXEFHCAWE9YgGV/bIbGcmjTiOSVmYFyvx2f+4CRp7fe doSgmARxTpFRwuWQz7pYDgIMnitMI6GQzzHrM+pA2p4nQEaBuC7fPP9dJuieiEcgsujB 8bL0ssjCTFEiRT4yGI2XElRQ5NAv7p0FY0xDzYnUc09Ng94Wh+bxZxh/HQFgNqSne/oM 7Egw9cr+G/8Hnrkrvv3RDWSLCtUj/JXLae2AL6iS6sMKLB1Nd2R3/R+U1MKCcUksbUF2 zUEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=oIBrTySaJzlZ/PX304+FIQ1DHdTIHBezsK/WkUhJzrI=; b=5KtWaaZh8dtNsQaoiK6JenSZxw2AA5TBCwcM28jGP/xcPhCQrhLs9kXaRr8EFsK3i/ FW7oIWyQSuGVsoqz4lWwNzzjyDLFe4NmKbRricZ5jw3anMF6YDBsnKlNxnQNp4Sc+VBs te/h5aG8R28L6DO1ou+q6ZMn/fbKwJ0vrxM74eMGa9skWFnMAm9C5iMun+yVapvqymx+ KPNH5K9EqTVDSBK4GRcP1kwOeIuvCwWuuO6IOCwk3+9lztmJvOemeB24Wp89XPyaL5ZB wewq8o8XymEUojvQWC2nvnMiKL/JuUUmgK3gcN5UKSpOwE3QB3YvN5Jzm8+r4w9OH12T uh5g== X-Gm-Message-State: AJIora9wXaeegEvqqor+BMnFCT3zKdKapgKAeZ8Vj2tC5xLx9ElLOApx Af8Gx2hQ+X2O//onFJENqh8PLMABW9djbw== X-Received: by 2002:a05:6a00:4211:b0:52a:c86e:aba3 with SMTP id cd17-20020a056a00421100b0052ac86eaba3mr14548058pfb.41.1657895113422; Fri, 15 Jul 2022 07:25:13 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id d22-20020aa797b6000000b0051c49fb62b7sm3891174pfq.165.2022.07.15.07.25.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:25:13 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Mark Kettenis , Masahisa Kojima Subject: [PATCH 6/9] eficonfig: add "Delete Boot Option" menu entry Date: Fri, 15 Jul 2022 23:27:40 +0900 Message-Id: <20220715142743.30137-7-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220715142743.30137-1-masahisa.kojima@linaro.org> References: <20220715142743.30137-1-masahisa.kojima@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean This commit adds the menu entry to delete the UEFI boot option. User moves the entry with UP/DOWN key, changes, then presses ENTER key to delete the selected boot option. Signed-off-by: Masahisa Kojima --- cmd/eficonfig.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index aeb60f1d09..51d4e36a54 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -1711,6 +1711,81 @@ out: return ret; } +/** + * delete_boot_option() - delete selected boot option + * + * @bootorder: pointer to the bootorder + * @index: index to delete in the BootOrder variable + * @size: Bootorder variable size + * Return: status code + */ +static efi_status_t delete_boot_option(u16 *bootorder, u16 index, efi_uintn_t size) +{ + u16 varname[9]; + efi_status_t ret; + efi_uintn_t num; + + efi_create_indexed_name(varname, sizeof(varname), + "Boot", bootorder[index]); + ret = efi_set_variable_int(varname, &efi_global_variable_guid, + 0, 0, NULL, false); + if (ret != EFI_SUCCESS) { + log_err("delete boot option(%ls) failed\n", varname); + return ret; + } + + /* update BootOrder */ + num = size / sizeof(u16); + memmove(&bootorder[index], &bootorder[index + 1], + (num - index - 1) * sizeof(u16)); + size -= sizeof(u16); + ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, bootorder, false); + + return ret; +} + +/** + * eficonfig_process_delete_boot_option() - handler to delete boot option + * + * @data: pointer to the data for each entry + * Return: status code + */ +static efi_status_t eficonfig_process_delete_boot_option(void *data) +{ + int selected; + u16 *bootorder; + efi_status_t ret; + efi_uintn_t num, size; + + while (1) { + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + if (!bootorder) { + eficonfig_print_msg("BootOrder is not defined!"); + ret = EFI_NOT_FOUND; + return ret; + } + + num = size / sizeof(u16); + ret = eficonfig_show_boot_selection(bootorder, num, &selected); + if (ret == EFI_SUCCESS) + ret = delete_boot_option(bootorder, selected, size); + + if (ret != EFI_SUCCESS) + break; + } + + free(bootorder); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + /** * eficonfig_init() - do required initialization for eficonfig command * @@ -1742,6 +1817,7 @@ static const struct eficonfig_item maintenance_menu_items[] = { {"Add Boot Option", eficonfig_process_add_boot_option}, {"Edit Boot Option", eficonfig_process_edit_boot_option}, {"Change Boot Order", eficonfig_process_change_boot_order}, + {"Delete Boot Option", eficonfig_process_delete_boot_option}, {"Quit", eficonfig_process_quit}, }; From patchwork Fri Jul 15 14:27:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 590843 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:5817:0:0:0:0 with SMTP id j23csp553022max; Fri, 15 Jul 2022 07:27:09 -0700 (PDT) X-Google-Smtp-Source: AGRyM1vohZJaKrLiu6CYvhvcvBtgUTLIrQNGB0gTcBKrbVW67wpah4tBBQg+3ag7cEnV8nWuqCXx X-Received: by 2002:a02:a105:0:b0:33f:1909:6c82 with SMTP id f5-20020a02a105000000b0033f19096c82mr8058561jag.278.1657895229122; Fri, 15 Jul 2022 07:27:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657895229; cv=none; d=google.com; s=arc-20160816; b=XIKfUcqCSAq/wEDqsQyUuQsd5HQT6Q2NwPoc1d0y+P7OyPKz0JjgpBOmdh1IWwoJ5C ++401RhwgsMPOVJN79h+QlGNV/XmB81E2tI86le4TWEh522p0NsPM6XUs/cnOSSrlyy+ 4Lt15qrkWx2PVyIYw5r+M7tkQRUAnFO1lw7kX0nTzvauKke2QX0ngejoNHwo2kYYMzku 8seAJL6nioVH5ghv4UXXiJqeQwhcfaVauFAIR9oRGvwkIz6YaW9XulL9PGcP0rO13+jF xeRYHzK3Vxdt94mZqgvR/v25/8n2IifAGGqG7JoEjyL6GtHctYj09KDO4h9qRhhsg30Y h88A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=lI9wobL/7MV8jW7HEsy1CpL2JfpMd/jkFVI98+juEIQ=; b=nvKSgRvNwoglBwsxG4LxTtUgdKBL50Fgto3FAk0qiEef4CFVBxu0HtVINm5sY3imsq DJtE7GrX+/sKa6qDreSvgMZFkc2RqpjvP1EmFz2ewBBoO8I1DpIo2M2C84rhwwfqmh1K 3iyk71u6as3Id1Yn5TWUIhPePEHJPURv0aleZDS1NjVp48R+5VygL4AYtBWOI4cJphoH GUGfkLt50mMPJBwCt7A7HfgQ2e9Be0PoRZgzEV6zPiZdr0TIKV2DdJ7rU8yP5M0wRp6L hd+1MPAgBkj2D5sf/Uvqty8zMVfyvUAEosfAFMXZFYZIpJWnoXMnYJfcoN2Nl4Q1gIX0 Fx9g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FIQKsyo9; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id p15-20020a0566022b0f00b0067b9269ea5dsi4921807iov.86.2022.07.15.07.27.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:27:09 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=FIQKsyo9; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 62AF88356F; Fri, 15 Jul 2022 16:25:55 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="FIQKsyo9"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 8F37A8171B; Fri, 15 Jul 2022 16:25:34 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id C65C581F69 for ; Fri, 15 Jul 2022 16:25:23 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pj1-x1033.google.com with SMTP id y14-20020a17090a644e00b001ef775f7118so11718539pjm.2 for ; Fri, 15 Jul 2022 07:25:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=lI9wobL/7MV8jW7HEsy1CpL2JfpMd/jkFVI98+juEIQ=; b=FIQKsyo9ZJVMCnbZG0VnsOeCTsaOxnWt1tEN/ppUdoxxQvAh0Soemh4Ti890ODvP05 VI1HAua2W9KfFoYC6gOePbPQi9/9JS+zHfFhwmMlbZxl3tGGyf6L0cwt++Va6YglKXUr 6UPCNf1i7c8nNk+grt4b3zdZZ/1fOv57+93q+YQ7UfJ0WyFjjHheW+Awl84Sp9ENlHqU 9531aFGwdltboOykNVxkopLdBwvhb7HIUJMZMp9Eo9lc03z1ycm7Ofcuub/lAcT2CB8a nPoW2QHLFKbFMpRo76biLFWtA/aN9vhhwTcSKWEdJ0h6mWCYfKxf+reCBjOOd9Qv3qJT 3qTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=lI9wobL/7MV8jW7HEsy1CpL2JfpMd/jkFVI98+juEIQ=; b=dkyIBabqzljoTRsHR+B/rk4ZWmGtYd6nMpEKQL9ubqv2FfjyDsv2aycP9AyHqFDQRU StYMot8m9h1oyZdaXN0db/ZmNYWhRyFNTfoouFa9/En+nt+5oAtbr5ViOa2RVOWMXQzY PXbk64vS+TEfHBtYJ6IGPV8qqRYidlOMxbICyvDAvS63Td5T7WEJruymlAiedM2/fgDW yXj0B+EfwdiV+sy3H7s82rJd9uzuc5HivD82uZ/gT/rratcNTuh6ZZah+tdnTW7oaOzx q+y841HHlEh+8WszrAjxWxfd8C3/shQNuz2qPjNIkq6dF6kVzlZC6vH4ZteKg9M8ovX+ KL/w== X-Gm-Message-State: AJIora+lsilsFZnXVRFJrdTNAkADaU4GG3T7VSkGLr1RbQUG5/HmpUYM FsUfeSKLe/eeTonyRK9QECybxgANGBPvXA== X-Received: by 2002:a17:90b:48c7:b0:1ef:a692:9593 with SMTP id li7-20020a17090b48c700b001efa6929593mr16183692pjb.184.1657895116829; Fri, 15 Jul 2022 07:25:16 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id d22-20020aa797b6000000b0051c49fb62b7sm3891174pfq.165.2022.07.15.07.25.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:25:16 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Mark Kettenis , Masahisa Kojima Subject: [PATCH 7/9] bootmenu: add removable media entries Date: Fri, 15 Jul 2022 23:27:41 +0900 Message-Id: <20220715142743.30137-8-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220715142743.30137-1-masahisa.kojima@linaro.org> References: <20220715142743.30137-1-masahisa.kojima@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean UEFI specification requires booting from removal media using a architecture-specific default image name such as BOOTAA64.EFI. This commit adds the removable media entries into bootmenu, so that user can select the removable media and boot with default image. The bootmenu automatically enumerates the possible bootable media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, add it as new UEFI boot option(BOOT####) and update BootOrder variable. This automatically generated UEFI boot option has the dedicated guid in the optional_data to distinguish it from the UEFI boot option user adds manually. This optional_data is removed when the efi bootmgr loads the selected UEFI boot option. This commit also provides the BOOT#### variable maintenance feature. Depending on the system hardware setup, some devices may not exist at a later system boot, so bootmenu checks the available device in each bootmenu invocation and automatically removes the BOOT#### variable corrensponding to the non-existent media device. Signed-off-by: Masahisa Kojima --- Changes in v9: - update efi_disk_get_device_name() parameter to pass efi_handle_t - add function comment Changes in v8: - function and structure prefix is changed to "eficonfig" Changes in v7: - rename prepare_media_device_entry() to generate_media_device_boot_option() Changes in v6: - optional_data size is changed to 16bytes - check the load option size before comparison - remove guid included in optional_data of auto generated entry when loading Changes in v5: - Return EFI_SUCCESS if there is no BootOrder defined - correctly handle the case if no removable device found - use guid to identify the automatically generated entry by bootmenu cmd/bootmenu.c | 103 +++++++++++++++++++++++++++-- cmd/eficonfig.c | 125 +++++++++++++++++++++++++++++++++++ include/efi_loader.h | 20 ++++++ lib/efi_loader/efi_bootmgr.c | 4 ++ 4 files changed, 247 insertions(+), 5 deletions(-) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 704d36debe..e593345853 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -220,7 +220,90 @@ static int prepare_bootmenu_entry(struct bootmenu_data *menu, return 1; } -#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR)) +#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR)) && (CONFIG_IS_ENABLED(CMD_EFICONFIG)) +/** + * generate_media_device_boot_option() - generate the media device boot option + * + * This function enumerates all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL + * and generate the bootmenu entries. + * This function also provide the BOOT#### variable maintenance for + * the media device entries. + * - Automatically create the BOOT#### variable for the newly detected device, + * this BOOT#### variable is distinguished by the special GUID + * stored in the EFI_LOAD_OPTION.optional_data + * - If the device is not attached to the system, the associated BOOT#### variable + * is automatically deleted. + * + * Return: status code + */ +static efi_status_t generate_media_device_boot_option(void) +{ + u32 i; + efi_status_t ret; + efi_uintn_t count; + efi_handle_t *volume_handles = NULL; + struct eficonfig_media_boot_option *opt = NULL; + + ret = efi_locate_handle_buffer_int(BY_PROTOCOL, &efi_simple_file_system_protocol_guid, + NULL, &count, (efi_handle_t **)&volume_handles); + if (ret != EFI_SUCCESS) + return ret; + + opt = calloc(count, sizeof(struct eficonfig_media_boot_option)); + if (!opt) + goto out; + + /* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */ + ret = eficonfig_enumerate_boot_option(opt, volume_handles, count); + if (ret != EFI_SUCCESS) + goto out; + + /* + * System hardware configuration may vary depending on the user setup. + * The boot option is automatically added by the bootmenu. + * If the device is not attached to the system, the boot option needs + * to be deleted. + */ + ret = eficonfig_delete_invalid_boot_option(opt, count); + if (ret != EFI_SUCCESS) + goto out; + + /* add non-existent boot option */ + for (i = 0; i < count; i++) { + u32 boot_index; + u16 var_name[9]; + + if (!opt[i].exist) { + ret = eficonfig_get_unused_bootoption(var_name, sizeof(var_name), + &boot_index); + if (ret != EFI_SUCCESS) + goto out; + + ret = efi_set_variable_int(var_name, &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + opt[i].size, opt[i].lo, false); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_append_bootorder(boot_index); + if (ret != EFI_SUCCESS) + goto out; + } + } + +out: + if (opt) { + for (i = 0; i < count; i++) + free(opt[i].lo); + } + free(opt); + efi_free_pool(volume_handles); + + return ret; +} + /** * prepare_uefi_bootorder_entry() - generate the uefi bootmenu entries * @@ -340,11 +423,21 @@ static struct bootmenu_data *bootmenu_create(int delay) if (ret < 0) goto cleanup; -#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR)) +#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR)) && (CONFIG_IS_ENABLED(CMD_EFICONFIG)) if (i < MAX_COUNT - 1) { - ret = prepare_uefi_bootorder_entry(menu, &iter, &i); - if (ret < 0 && ret != -ENOENT) - goto cleanup; + efi_status_t efi_ret; + + /* + * UEFI specification requires booting from removal media using + * a architecture-specific default image name such as BOOTAA64.EFI. + */ + efi_ret = generate_media_device_boot_option(); + if (efi_ret != EFI_SUCCESS && efi_ret != EFI_NOT_FOUND) + goto cleanup; + + ret = prepare_uefi_bootorder_entry(menu, &iter, &i); + if (ret < 0 && ret != -ENOENT) + goto cleanup; } #endif diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index 51d4e36a54..564ddd02c1 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -1786,6 +1786,131 @@ static efi_status_t eficonfig_process_delete_boot_option(void *data) return ret; } +efi_status_t eficonfig_enumerate_boot_option(struct eficonfig_media_boot_option *opt, + efi_handle_t *volume_handles, efi_status_t count) +{ + u32 i; + struct efi_handler *handler; + efi_status_t ret = EFI_SUCCESS; + + for (i = 0; i < count; i++) { + char *optional_data; + u16 *dev_name, *p; + struct efi_load_option lo; + char buf[BOOTMENU_DEVICE_NAME_MAX]; + struct efi_device_path *device_path; + + ret = efi_search_protocol(volume_handles[i], &efi_guid_device_path, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&device_path, + efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + ret = efi_disk_get_device_name(volume_handles[i], buf, BOOTMENU_DEVICE_NAME_MAX); + if (ret != EFI_SUCCESS) + continue; + + dev_name = calloc(1, (strlen(buf) + 1) * sizeof(u16)); + if (!dev_name) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + p = dev_name; + utf8_utf16_strncpy(&p, buf, strlen(buf)); + + lo.label = dev_name; + lo.attributes = LOAD_OPTION_ACTIVE; + lo.file_path = device_path; + lo.file_path_length = efi_dp_size(device_path) + sizeof(END); + /* + * Set the dedicated guid to optional_data, it is used to identify + * the boot option that automatically generated by the bootmenu. + * efi_serialize_load_option() expects optional_data is null-terminated + * utf8 string, so set the "1234567" string to allocate enough space + * to store guid, instead of realloc the load_option. + */ + lo.optional_data = "1234567"; + opt[i].size = efi_serialize_load_option(&lo, (u8 **)&opt[i].lo); + if (!opt[i].size) { + ret = EFI_OUT_OF_RESOURCES; + free(dev_name); + goto out; + } + /* set the guid */ + optional_data = (char *)opt[i].lo + (opt[i].size - u16_strsize(u"1234567")); + memcpy(optional_data, &efi_guid_bootmenu_auto_generated, sizeof(efi_guid_t)); + free(dev_name); + } + +out: + return ret; +} + +efi_status_t eficonfig_delete_invalid_boot_option(struct eficonfig_media_boot_option *opt, + efi_status_t count) +{ + u16 *bootorder; + u32 i, j; + efi_status_t ret; + efi_uintn_t num, size, bootorder_size; + void *load_option; + struct efi_load_option lo; + u16 varname[] = u"Boot####"; + + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &bootorder_size); + if (!bootorder) + return EFI_SUCCESS; /* BootOrder is not defined, nothing to do */ + + num = bootorder_size / sizeof(u16); + for (i = 0; i < num;) { + efi_uintn_t tmp; + + efi_create_indexed_name(varname, sizeof(varname), + "Boot", bootorder[i]); + load_option = efi_get_var(varname, &efi_global_variable_guid, &size); + if (!load_option) + goto next; + + tmp = size; + ret = efi_deserialize_load_option(&lo, load_option, &size); + if (ret != EFI_SUCCESS) + goto next; + + if (size >= sizeof(efi_guid_bootmenu_auto_generated)) { + if (guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated) == 0) { + for (j = 0; j < count; j++) { + if (opt[j].size == tmp && + memcmp(opt[j].lo, load_option, tmp) == 0) { + opt[j].exist = true; + break; + } + } + + if (j == count) { + ret = delete_boot_option(bootorder, i, bootorder_size); + if (ret != EFI_SUCCESS) { + free(load_option); + goto out; + } + + num--; + bootorder_size -= sizeof(u16); + free(load_option); + continue; + } + } + } +next: + free(load_option); + i++; + } + +out: + return ret; +} + /** * eficonfig_init() - do required initialization for eficonfig command * diff --git a/include/efi_loader.h b/include/efi_loader.h index c57f239043..0f52e3ee5d 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -959,6 +959,22 @@ struct efi_signature_store { struct x509_certificate; struct pkcs7_message; +/** + * struct eficonfig_media_boot_option - boot option for (removable) media device + * + * This structure is used to enumerate possible boot option + * + * @lo: Serialized load option data + * @size: Size of serialized load option data + * @exist: Flag to indicate the load option already exists + * in Non-volatile load option + */ +struct eficonfig_media_boot_option { + void *lo; + efi_uintn_t size; + bool exist; +}; + bool efi_hash_regions(struct image_region *regs, int count, void **hash, const char *hash_algo, int *len); bool efi_signature_lookup_digest(struct efi_image_regions *regs, @@ -1108,6 +1124,10 @@ efi_status_t efi_console_get_u16_string efi_status_t eficonfig_get_unused_bootoption(u16 *buf, efi_uintn_t buf_size, u32 *index); efi_status_t eficonfig_append_bootorder(u16 index); +efi_status_t eficonfig_enumerate_boot_option(struct eficonfig_media_boot_option *opt, + efi_handle_t *volume_handles, efi_status_t count); +efi_status_t eficonfig_delete_invalid_boot_option(struct eficonfig_media_boot_option *opt, + efi_status_t count); efi_status_t efi_disk_get_device_name(const efi_handle_t handle, char *buf, int size); diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index ede9116b3c..4b24b41047 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -246,6 +246,10 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle, } /* Set load options */ + if (size >= sizeof(efi_guid_t) && + !guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated)) + size = 0; + if (size) { *load_options = malloc(size); if (!*load_options) { From patchwork Fri Jul 15 14:27:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 590840 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:5817:0:0:0:0 with SMTP id j23csp552289max; Fri, 15 Jul 2022 07:26:23 -0700 (PDT) X-Google-Smtp-Source: AGRyM1u2d+SeSsDC/4AyXZsjhBfyLJBVFgD5oWCZDwArTXpMHI3l92nKYERpWa42TCbVhv5kpxzD X-Received: by 2002:a05:6e02:1583:b0:2d7:a75d:888f with SMTP id m3-20020a056e02158300b002d7a75d888fmr7256996ilu.13.1657895183149; Fri, 15 Jul 2022 07:26:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657895183; cv=none; d=google.com; s=arc-20160816; b=dMH+IU/16NdSioTwNljIhWuGyWWYqaGm3GBdcUSv/Ikce1Uz/9scfVXVjz7ZdFq0SV OklXnAJAhBIMxMLmEe7r6b38JXfgCmKgICOHYUG47CXwX5HXcI/CoUWHLJVOvWMfmYrX xbopECagw1miVkNC7yJAfMxNO7/zutQuuugeMhnXHm55fGMKQpm2fuU4cb5lWWjlV1Eo xk1RYCE8rpEqM2SgWalQMlf0kGBwaiXPDKsltNhl8X+iLD2RDrlhV/y4sBoYbWVEuXFy MMqfOo9qWqe2JRrWzeP0Xo47/ff+OxpGQmaozkfFYkqTm4hUdK2Lb+MsarTnBgP0KbJJ 3c8w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=wrdys3/dbUUfK+3BxRJnxUf8rBAvOa2YOd7ils7QECc=; b=LVURB6U10+yoYJdCDL1+nbckHm+7Vw4FHehlhb8PhcW4jnpqljWUN05ufrCXXiumq+ 2IIG4NtgecJacpTWGtR01KQZqzwteTYi7+tdSe3mVUzD5gj385OGJJ0RlQ1CA+c2XW+o ybGwhMvfF0XV9iMOZEv/w5sFEtu3iArAoTXvFRmdpr+hK5lyzudpzmq7mK41wa823wFI 1OdTJjL3xfsmdPCus9NBE6TQP9LAUoGrW4a0w0iQ7/rmhW9Dx04T5F1myPQaTvhrG71k QB6vlKhrhmIqr9H2U61j7ko7Pc3GxmLmb05OS1j89uwbu9Tz/zKm8IXXJIpC4TGfpThM 1wlg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UGgiU1D2; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id u2-20020a5ec002000000b0067b957cdf4csi4062148iol.14.2022.07.15.07.26.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:26:23 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UGgiU1D2; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id CCE06819FC; Fri, 15 Jul 2022 16:25:34 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="UGgiU1D2"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 8CA7C8171B; Fri, 15 Jul 2022 16:25:25 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x430.google.com (mail-pf1-x430.google.com [IPv6:2607:f8b0:4864:20::430]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 57CBC81877 for ; Fri, 15 Jul 2022 16:25:21 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pf1-x430.google.com with SMTP id b133so1004852pfb.6 for ; Fri, 15 Jul 2022 07:25:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=wrdys3/dbUUfK+3BxRJnxUf8rBAvOa2YOd7ils7QECc=; b=UGgiU1D2rUI1Kl4rHU+pr5iUbuC/FLF6Z4Sv7NUSUXHGlg0pdQIHMOu2R/C0bQXGJ3 ARv9x+DUiaWMUwLsypdL9EP82J/SU5RCjTuVcD9RdW47gLCmBulOy7AyJJ4Rvhm9irx7 ObREL45EqZibj0sOnKqslN/ZKXbOvWF9RWKMNGLzTEAYaUy5lIxAb1ovpn0wdgiYJ9YS d0p5D02g4oworHV74Et/ZBGFzr+c6OEm9D+d4nL9Vir+99hku4ldTiODjhiBgDyJWlvx kKcGSZaXBcENgjsWduYxw2opthB07InlPkC1x/AoqPpx4MVfgn3bOES7VJCGcyjjc96H eT9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=wrdys3/dbUUfK+3BxRJnxUf8rBAvOa2YOd7ils7QECc=; b=iWf2BgN+RgzsTzV3oMwp2mDb2thQ0TWJDSYk5zij/LgZeYcVgHhalFDT7pqedq2WJi f331ELBoFT+lvn2AMp26Gmm51J7zW32ITaz6/srup+xyuN/1s1oYCPwcE3tqHfcHsC/+ lzhB9fJmW7HWPXfKnw9z1gSfqz1gQVp42Bxfa0mCWPr5ntyqbeXSo+YN/xEuf/yXmi8v x7yF5EMawB0lLoy5BcUOewaGQD55wiiI0tVOuB0hrMobG0qp5SRMyCY5vadwHv+1TW+e yTaxCJyjwnNCEes782ornE6KlD1LJyPH4f6hb7e/5OZu6HPJmQCs4fd1AE8Tby8biG5O iy+Q== X-Gm-Message-State: AJIora9YL0CxVmH6LcMV+mlRDcF3x+cPUcooxcHnDJLsKDtnh3WJkOTx +XvWCE6iQysC3RR4KWtqiJPGkybiqeRqyg== X-Received: by 2002:a05:6a00:2410:b0:528:be6e:8c2e with SMTP id z16-20020a056a00241000b00528be6e8c2emr14243972pfh.31.1657895119466; Fri, 15 Jul 2022 07:25:19 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id d22-20020aa797b6000000b0051c49fb62b7sm3891174pfq.165.2022.07.15.07.25.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:25:19 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Mark Kettenis , Masahisa Kojima , Bin Meng Subject: [PATCH 8/9] doc:bootmenu: add description for UEFI boot support Date: Fri, 15 Jul 2022 23:27:42 +0900 Message-Id: <20220715142743.30137-9-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220715142743.30137-1-masahisa.kojima@linaro.org> References: <20220715142743.30137-1-masahisa.kojima@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean The bootmenu enumerates the UEFI boot options for boot device selection. This commit adds the description how the UEFI boot work in bootmenu. This commit also adds "Synopsis", "Description" and "Configuration" sections to follow the U-Boot command documentation format. Signed-off-by: Masahisa Kojima --- No change since v7 Changes in v7: - update the description what bootmenu do for uefi-related boot menu - add default behavior when user exits from bootmenu Changes in v6: - remove distro boot related contents because the distro boot support in bootmenu is dropped - update uefi entry example - add [delay] argument of bootmenu command - add description to enable uefi boot entry Changes in v5: - follow the cmd documentation format same as other command, add "Synopsis", "Description" add "Configuration" sections Newly created in v4 doc/usage/cmd/bootmenu.rst | 74 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/doc/usage/cmd/bootmenu.rst b/doc/usage/cmd/bootmenu.rst index 9430f8c9aa..69435090a2 100644 --- a/doc/usage/cmd/bootmenu.rst +++ b/doc/usage/cmd/bootmenu.rst @@ -4,6 +4,15 @@ bootmenu command ================ +Synopsis +-------- +:: + + bootmenu [delay] + +Description +----------- + The "bootmenu" command uses U-Boot menu interfaces and provides a simple mechanism for creating menus with different boot items. The cursor keys "Up" and "Down" are used for navigation through @@ -79,6 +88,55 @@ The above example will be rendered as below:: The selected menu entry will be highlighted - it will have inverted background and text colors. +UEFI boot variable enumeration +'''''''''''''''''''''''''''''' +If enabled, the bootmenu command will automatically generate and add +UEFI-related boot menu entries for the following items. + + * possible bootable media with default file names + * user-defined UEFI boot options + +The bootmenu automatically enumerates the possible bootable +media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. +This auto generated entry is named as " :" format. +(e.g. "usb 0:1") + +The bootmenu displays the UEFI-related menu entries in order of "BootOrder". +When the user selects the UEFI boot menu entry, the bootmenu sets +the selected boot variable index to "BootNext" without non-volatile attribute, +then call the uefi boot manager with the command "bootefi bootmgr". + +Example bootmenu is as below:: + + *** U-Boot Boot Menu *** + + mmc 0:1 + mmc 0:2 + debian + nvme 0:1 + ubuntu + nvme 0:2 + usb 0:2 + U-Boot console + +Default behavior when user exits from the bootmenu +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +User can exit from bootmenu by selecting the last entry +"U-Boot console"/"Quit" or ESC/CTRL+C key. + +When the CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE is disabled, +user exits from the bootmenu and returns to the U-Boot console. + +When the CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE is enabled, user can not +enter the U-Boot console. When the user exits from the bootmenu, +the bootmenu invokes the following default behabior. + + * if CONFIG_CMD_BOOTEFI_BOOTMGR is enabled, execute "bootefi bootmgr" command + * "bootefi bootmgr" fails or is not enabled, then execute "run bootcmt" command. + +Configuration +------------- + The "bootmenu" command is enabled by:: CONFIG_CMD_BOOTMENU=y @@ -88,3 +146,19 @@ To run the bootmenu at startup add these additional settings:: CONFIG_AUTOBOOT_KEYED=y CONFIG_BOOTDELAY=30 CONFIG_AUTOBOOT_MENU_SHOW=y + +UEFI boot variable enumeration is enabled by:: + + CONFIG_CMD_BOOTEFI_BOOTMGR=y + +To improve the product security, entering U-Boot console from bootmenu +can be disabled by:: + + CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE=y + +To scan the discoverable devices connected to the buses such as +USB and PCIe prior to bootmenu showing up, CONFIG_PREBOOT can be +used to run the command before showing the bootmenu, i.e.:: + + CONFIG_USE_PREBOOT=y + CONFIG_PREBOOT="pci enum; usb start; scsi scan; nvme scan; virtio scan" From patchwork Fri Jul 15 14:27:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 590842 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:5817:0:0:0:0 with SMTP id j23csp552835max; Fri, 15 Jul 2022 07:26:57 -0700 (PDT) X-Google-Smtp-Source: AGRyM1t+GND5rx76dBRBBkkzg4LqqaaDDqBnKB/6DU6dy6gbxVEP4X1Z5ZpBVObtzy1MVY8UlgRR X-Received: by 2002:a02:1981:0:b0:33f:82f:cc41 with SMTP id b123-20020a021981000000b0033f082fcc41mr7252838jab.44.1657895217785; Fri, 15 Jul 2022 07:26:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657895217; cv=none; d=google.com; s=arc-20160816; b=vLdfLzpbcg7iuTDe7jBVUMF3q+TquHQjs6GcBvj+MEFSuzV39Vau4+YtLFzLW0vx0K V7i4tYm0086y5bY8/lX5lgF7iDkxe3D43BnL+rdt4FE98DBipgoQOVKV9KY+F6OiLCjQ lIKNsEaexBAuyFLt+OXse45zrdraFCV/DAijMPNfq0uULWBzLdYh5/2PnmZUAo5CU4Di 1kn8zqwR2VL6IEGz3dMl999/a6UCGHrSEQp0Sr3skg7zCAEDMkhVYFRcR5vTbr0Zas2n 68QObg1PweuRNQ/mZzmfuDqu/NCOZd0EEGiXKzQpz7rXlVdZLK8CNnRs10I2ykF6ODV5 jjpA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=vuLfgFvgZHZ4kdb0w0HXLMs9Pp7vocINI2Oojq9LWDs=; b=QHBV6a6Ugsxuklpi6YGTCPvDxIjDnd6TTFCe4z+FjvppjHxyHkGQD8FwlaDyOLrY+v UivPHvM88MksqM+QWLxvLXgI4W4mzoHUTLUlXC5j7DcI4QvUcdu9t7ok+lpBMkz+UEpP GCQmUIfXm4luGUmGAMbPUQ8yLtMg3jgm/6Ad0puZbOGRJEiV+1uTbGQqBR80eIdS5oCA 1bLDlBMgn+8AH5N4ONFBSuPwTSsAPzZQ18ZQc1g4QdCrRMh9FpYj9VtzuxVkvS6n9shT smZx0oJyuTyNzdIElAnh28wpJuQzFZUhtsCPrI819wW8FPiEiTLide4HBvtBTvA/uujm yOjQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=f28KyNun; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id o7-20020a056e02188700b002dc46abb3fbsi5047373ilu.164.2022.07.15.07.26.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:26:57 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=f28KyNun; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 2A75C82DA1; Fri, 15 Jul 2022 16:25:51 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="f28KyNun"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 89460814BD; Fri, 15 Jul 2022 16:25:30 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pg1-x52a.google.com (mail-pg1-x52a.google.com [IPv6:2607:f8b0:4864:20::52a]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id A5A8381297 for ; Fri, 15 Jul 2022 16:25:24 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pg1-x52a.google.com with SMTP id 72so4577616pge.0 for ; Fri, 15 Jul 2022 07:25:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=vuLfgFvgZHZ4kdb0w0HXLMs9Pp7vocINI2Oojq9LWDs=; b=f28KyNunNag99xdrW1lD9pVbHGs5jQ9W4/Lb6fN5D6fXK/T8STSXuRJ5C67KNvlLPl 23nMLF0gb1CCGkeCJmcp/NeqTwsY8ghHcMFGuq+OpwieJIhVK/emYv4X+wWox/IpaE0I afA0xDJuT0JBsm7ThqCmGa8hSPDkvfPhX1GgvteybqFFcqrdPZWRgITV0wmwiuQShmh4 BxJJZF3nkdStqhcE/yYVaq9Tg24OeNNRnN/CuRONCh/fxH0eEAlQX4o3RjGVT8FB5pcX x3zCFzK3Dm+rhZPHcKbCrM/aQK8t0txXeCd9Nqv9O/2e06FCy8tHNWfaTRqvet0I7HGp s5Vg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=vuLfgFvgZHZ4kdb0w0HXLMs9Pp7vocINI2Oojq9LWDs=; b=yUaslZINBW0Bj2EemSBtu8ej++riJ68IZoBVyENDrc5FOMtVaiKLC35Eavg+UfsxFk 4/7TqXSgVQVSGxBmkaCl1wbzNSYokDSr13b2xUaD5NfMozc/jjfbnb/DHVsO1pt7Oykz 7CapmFVkbsvGEL1g1FAbIBwoI3OB0Wh/2XtP+N8pDes3eR8appfo7PKdG0e34qmQblxk wRJST6zWQmBahKufVZCGJGEpYJe12YLCmnBfcRI2vtS6e+Cfu3IZfYbdV8VADLaxNxUd 3peX/N6YhYiIn/JNZ4uVNqeARu5KJa0EDWjMaHxXIB80+MPrqcEiB4bNtGzmlj0Wp/3s 1kvw== X-Gm-Message-State: AJIora/HPSYQQa3umYgIdOHGmmEGGgEIJ7rUPJfGSKNbae8kt45rlS2z ebyutvfxiOnckzyth99z8nypeQ+/M8z/kg== X-Received: by 2002:a05:6a00:2445:b0:528:5a5b:67d3 with SMTP id d5-20020a056a00244500b005285a5b67d3mr14104176pfj.32.1657895122820; Fri, 15 Jul 2022 07:25:22 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id d22-20020aa797b6000000b0051c49fb62b7sm3891174pfq.165.2022.07.15.07.25.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Jul 2022 07:25:22 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Mark Kettenis , Masahisa Kojima , Bin Meng , =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH 9/9] doc:eficonfig: add documentation for eficonfig command Date: Fri, 15 Jul 2022 23:27:43 +0900 Message-Id: <20220715142743.30137-10-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220715142743.30137-1-masahisa.kojima@linaro.org> References: <20220715142743.30137-1-masahisa.kojima@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean Add documentation for eficonfig command. Signed-off-by: Masahisa Kojima --- No change sinch v8 Changes in v8: - command name is changed from "efimenu" to "eficonfig" Newly created in v7 doc/usage/cmd/eficonfig.rst | 49 +++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + 2 files changed, 50 insertions(+) create mode 100644 doc/usage/cmd/eficonfig.rst diff --git a/doc/usage/cmd/eficonfig.rst b/doc/usage/cmd/eficonfig.rst new file mode 100644 index 0000000000..f150d7301c --- /dev/null +++ b/doc/usage/cmd/eficonfig.rst @@ -0,0 +1,49 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. (C) Copyright 2022, Masahisa Kojima + +eficonfig command +================= + +Synopsis +-------- +:: + + eficonfig + +Description +----------- + +The "eficonfig" command uses U-Boot menu interface and privides +a menu-driven UEFI variable maintenance feature. +The "eficonfig" has the following menu entries. + +Add Boot Option + Add new UEFI Boot Option. + User can edit description, file path, and optional_data. + +Edit Boot Option + Edit the existing UEFI Boot Option + User can edit description, file path, and optional_data. + +Change Boot Order + Change the order of UEFI BootOrder variable. + +Delete Boot Option + Delete the UEFI Boot Option + +Configuration +------------- + +The "eficonfig" command is enabled by:: + + CONFIG_CMD_EFICONFIG=y + +If CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE is enabled, user can not enter +U-Boot console. In this case, bootmenu can be used to invoke "eficonfig":: + + CONFIG_USE_PREBOOT=y + CONFIG_PREBOOT="setenv bootmenu_0 UEFI Maintenance Menu=eficonfig" + +See also +-------- +* :doc:`bootmenu` provides a simple mechanism for creating menus with different boot items diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 8b98629d6b..1afbb6bc5d 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -35,6 +35,7 @@ Shell commands cmd/conitrace cmd/dm cmd/echo + cmd/eficonfig cmd/env cmd/event cmd/exception