From patchwork Thu Mar 24 13:54:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 553912 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:1248:0:0:0:0 with SMTP id z8csp4437888mag; Thu, 24 Mar 2022 06:54:59 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxaYLVRkxkEPNU2VkXn93oieh1Kk6MxB4le5lCEBuh7MSiShEdmD4GcbgadIeE7XWcVAO7G X-Received: by 2002:a05:6402:b7a:b0:419:3046:3abb with SMTP id cb26-20020a0564020b7a00b0041930463abbmr6823030edb.257.1648130099632; Thu, 24 Mar 2022 06:54:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648130099; cv=none; d=google.com; s=arc-20160816; b=VLYz+wZX66JILDIhjXufJnT2sTRAnXjwhumdbfvBTZAp1GVJ2yJJj0HwJATuCMbnna ldqr3OnMif1PY+wq6wFRaukdBUnxNItGKH/vMSUDQpMjde/NZkRCgMhZnLSyV7zDbm65 s8ejpKDZNDzK6y2Yg9opNUQvN/Q29v3n8KKypNjqvNF1YqSdMzqNt4oZ6akIizlmWSO6 Yc5UtMM1ZzON91QQqaGjDbu7UVOeuS0zJGHeVjKWYYy5kr+usd2wesrt81Nojb9Sf9LE BLzQE7khDbj5axG0oRwXvZB1x3up9CX5w0y5LtyTHPm7+DojBaiODn9ac9/WHCNK+C7l gLSg== 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=QBSkDh3vm6Z4sZAfYprPul9XVTdLS/kAXFY6He4ogYE=; b=CvWiHXzOFpLKU7xej7ZN/Hk1rjMETztm2gNQW2ZPDvX4UAB/nczRQTYbmfwlGhO4Rx fW8pLrFnsi1pjxdxiexIjMT6pIYhS1fvYb2/0/z+I2FCqBNcLPR+lpOGptu3mCVHuXO8 C91lkIGKUBrteGSJ1aqspO0mB5PGT6PSzv3m5t4IkxYKgCknjpEv96Ghc/BW2tkrkx2j IMLYN1+SH0Rg/lZ8urFCFqgIpRuFoSr6ru+IWW0LoLtBOJcworKElzQOPBlImQBE8v3m s4R07X9dYDjL7NCqWPx4OFUN1xojiigtRycT51GrHROGXj9gHxdXUOaDy5pT6D51QDPm IPlw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=c7sXBQRB; 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 tc26-20020a1709078d1a00b006df76385d3fsi12561493ejc.479.2022.03.24.06.54.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:54:59 -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=c7sXBQRB; 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 2DBCE840B3; Thu, 24 Mar 2022 14:54:50 +0100 (CET) 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="c7sXBQRB"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id ECB8C840AC; Thu, 24 Mar 2022 14:54:44 +0100 (CET) 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-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) (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 27AA1840A6 for ; Thu, 24 Mar 2022 14:54:42 +0100 (CET) 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-x62a.google.com with SMTP id k6so4734512plg.12 for ; Thu, 24 Mar 2022 06:54:42 -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=QBSkDh3vm6Z4sZAfYprPul9XVTdLS/kAXFY6He4ogYE=; b=c7sXBQRBb5Mm2ZM9oWlbubqOlSqrkLnHupOqk5zzuOqDUZZfqHXojyaLWhYN2YuCL2 /cIxgkq/oy8amoTnuJu2BAIhPfoQGgjIyXRv8iUi5K3w48OG6g8EDvsAbWpgaHdNASpJ WDvOVsO6mhBh4b0FcnoxrbkTB0KjwKnSMoyz6iKbyspmAAOStkMa5t1OOs5Wzyth/wnZ K0Tb3rJ4RojpqOk+brXwE8RkeYVLP2xyMZWd3deR4YsAMaOvE2GhKUzh0hfjNide5FVY iw1LQuHjUVYmcalPGYb4LjjNrlSf65DV/FhfcrPeyTRdyyU7Y836Vmny8IJbNycOL5Ig NaiQ== 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=QBSkDh3vm6Z4sZAfYprPul9XVTdLS/kAXFY6He4ogYE=; b=Uir0ZpMqvRpnN7YVoadLfPuPsdeJ0yTnOLoZXfunnk7YqtAOeBbxmJISY5obHjFLw9 x00yIwmlE6us27Bltkb5bGMMkzL6M4L8cIDKgMq6tVEk9aLmDYWsxfo8G2JN7buppUik N7VWo5OY5Z7J/jVrwuibL/CENiLJgdB0ehh9HNZDu+vWavAgIqJgXjw0Mev+fAPC8TYM 8tHHbNeu8f3GR3Au5QiX2ywePZr32fHCWt+oPjHLVJgiyT5iDCOGC1vzElTh7IArI8Cf oZ3U9n0+P2Oi7UyMmP6jGTOTIWwT7gqO9Z06YuNbAj2nygzp6OMYRdUMsXdRysg4av4b Temg== X-Gm-Message-State: AOAM530zKxalB0Xu59nZN1mbYrXPF6jEcAjJVzk+7YaT2OkEruO1A4M5 YXj3p7RD0KgLOnw4Cb6YRAeZ+0q7JLaCOw== X-Received: by 2002:a17:902:ecd1:b0:154:5393:aaa4 with SMTP id a17-20020a170902ecd100b001545393aaa4mr5859283plh.131.1648130080489; Thu, 24 Mar 2022 06:54:40 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id p15-20020a056a000a0f00b004f7c63cba5asm3974609pfh.21.2022.03.24.06.54.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:54:40 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima Subject: [PATCH v4 01/11] bootmenu: fix menu API error handling Date: Thu, 24 Mar 2022 22:54:33 +0900 Message-Id: <20220324135443.1571-2-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220324135443.1571-1-masahisa.kojima@linaro.org> References: <20220324135443.1571-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.5 at phobos.denx.de X-Virus-Status: Clean U-Boot menu framework(common/menu.c) returns 1 if it is successful, returns negative value if it fails. Signed-off-by: Masahisa Kojima Acked-by: Ilias Apalodimas --- Newly added in v4 cmd/bootmenu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 409ef9a848..d573487272 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -463,7 +463,7 @@ static void bootmenu_show(int delay) } for (iter = bootmenu->first; iter; iter = iter->next) { - if (!menu_item_add(menu, iter->key, iter)) + if (menu_item_add(menu, iter->key, iter) != 1) goto cleanup; } @@ -476,7 +476,7 @@ static void bootmenu_show(int delay) init = 1; - if (menu_get_choice(menu, &choice)) { + if (menu_get_choice(menu, &choice) == 1) { iter = choice; title = strdup(iter->title); command = strdup(iter->command); From patchwork Thu Mar 24 13:54:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 553913 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:1248:0:0:0:0 with SMTP id z8csp4438083mag; Thu, 24 Mar 2022 06:55:13 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx0X0DXo9YNIdJtrJBY/s5h9xR/EiLY5kwkn6P+Hb/tsrgRTxEzaG0h5SjQQ+cyYUJ4LiyO X-Received: by 2002:a17:906:b1d0:b0:6cd:fa02:b427 with SMTP id bv16-20020a170906b1d000b006cdfa02b427mr5814337ejb.99.1648130113418; Thu, 24 Mar 2022 06:55:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648130113; cv=none; d=google.com; s=arc-20160816; b=xgs9SSD+q0UslubjamBeZo4tx6ydwBTQHfIh/ETvvOjkeEnd43vQfrvQ5ZylBTxq5H fGUqSh3v5aHiixE45GGykdYhn81yujNiQtu5wEiSqOh+Njy7nOu8KHspnJxgBDrjjKiC 14gqzAbx12CjsVzuOqyXGYLdJV16QSIKXzI/rvMJNhwx/Ynxbpu3i+gdpiP1iDX96Wlc 78b+2XQr3Wb+nPKPEyZ3qKhcpsCTNDUe0zSKkLifLqpyYMXGnZh3Sa/D/XGFNQB5kZ16 cs3cXV+2qcKe9/qGsfMaNvVno2Q6m7m41U2lfxxCAYZQevicWTWa+BZJIGbCWSV9+6cX DaJg== 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=YHAVowG0AofRG7/Ws+4OdImSbygNMfErEAZyDcKG+Fo=; b=YGUANfaMGyiTxBVO4vciXtvxMWeNZAS1hKCOcc8S7PFm+hdWsL9pVy6j4otB22ObGS Uxuh8zeQ/mxAxmvbvD6BXDJWghJqxHaUlMeLxdWpmIGxD7s16m2pkN3XfZN2oY0cz7bf guNPPsmwrqoHsl9eS5stOP7hAw32RhN6sAy2i1nx4DM+jIKHbDqRxDGfqyoKR205KJHP 5VUVWk5GPlL5KhFX9ejTGSRkja+Y/wfBcgk+d5jDllZt9Ubs58NlhFlcvN2HIaqGCLUd VDmoNY5txINWPlFuymejJNUued7PyKVv+B0125iGY6Pu6KJQ7BIoVyBT8afMB6bQE+rG QgHQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=a9ukwrf3; 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 fb15-20020a1709073a0f00b006df7a784b52si13887950ejc.508.2022.03.24.06.55.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:55:13 -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=a9ukwrf3; 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 50145840B2; Thu, 24 Mar 2022 14:54:53 +0100 (CET) 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="a9ukwrf3"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id DDEE3840B3; Thu, 24 Mar 2022 14:54:47 +0100 (CET) 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-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) (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 CED0F840A1 for ; Thu, 24 Mar 2022 14:54:44 +0100 (CET) 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-x62d.google.com with SMTP id g3so4754216plo.6 for ; Thu, 24 Mar 2022 06:54:44 -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=YHAVowG0AofRG7/Ws+4OdImSbygNMfErEAZyDcKG+Fo=; b=a9ukwrf3MX7Xh+RpBv7WyyVGofgMPpi7jVL2mUKFafzrhzaIJNjb6eA3SlojR9Zd2F rSEHozP7CkZSbxCK5HzRWzajScsxA67kXv/YUzssT9IW3NupwBaoI9wEU20rSDE9xeb5 QHGxJethZQI5y3lH0IKIQ3dv5+L6+WSErdKZrcIvnEZvUFiPy1oMX8qkMSTGXBAw9WzF HEfpM2eMbcdx62CU4ijuxHtMPfSTAgc0zpu1Ng6MaaSsf8n6kPomPnRRK1lemAV/JPhV jqc31DDplmrZ1fchliuSAdrir9lXFE1v10Yy+28yadUMFuNuPW7Rwsb6wBYO4oe/ZvQZ eK4Q== 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=YHAVowG0AofRG7/Ws+4OdImSbygNMfErEAZyDcKG+Fo=; b=2yw++xPEHBDcAIgR8cl9Sj433J4+250rY511bTl4XWRYN1SAcIuDxkJUdLRgKdmECF Z/nnab8FFhCFbzJ8feA3zacE/+wQJT5RW5phsF/ngiPAJ8zleGzGFny5iVr6mR+6Z9Hn kqWZi12CUV3bm0+9XOseHKBQ6XGiJuC47bE8KkY9z3/rQLNjTfyB+IDqI0THZOK0QorD KAOYlE3j06yhCmTaooTqW9rrpQzNCGg9iCaHD9RplFJ/gBHymHE2n6rKm4tlMmB6kVOl fFebMFKecJefaOqkt+aQ3n1f5uWxCgGHAS76W7HwKUPbfoF9jql6oFSuLgIQQnIC7IE7 LMlw== X-Gm-Message-State: AOAM531UPqhcdUzs2AUTwUjrtSp88u2nKKSyowvRsvlkcw8NQ2adGSNY SlYruyYSYGZ57IJlUQuWYHkY4fqOirkQ+w== X-Received: by 2002:a17:902:7d93:b0:14d:d401:f59b with SMTP id a19-20020a1709027d9300b0014dd401f59bmr6148908plm.14.1648130083120; Thu, 24 Mar 2022 06:54:43 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id p15-20020a056a000a0f00b004f7c63cba5asm3974609pfh.21.2022.03.24.06.54.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:54:42 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima Subject: [PATCH v4 02/11] lib/charset: add u16_strlcat() function Date: Thu, 24 Mar 2022 22:54:34 +0900 Message-Id: <20220324135443.1571-3-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220324135443.1571-1-masahisa.kojima@linaro.org> References: <20220324135443.1571-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.5 at phobos.denx.de X-Virus-Status: Clean Provide u16 string version of strlcat(). Signed-off-by: Masahisa Kojima Reviewed-by: Simon Glass --- Changes in v4: - add blank line above the return statement Changes in v2: - implement u16_strlcat(with the destination buffer size in argument) instead of u16_strcat include/charset.h | 15 +++++++++++++++ lib/charset.c | 21 +++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/include/charset.h b/include/charset.h index b93d023092..dc5fc275ec 100644 --- a/include/charset.h +++ b/include/charset.h @@ -259,6 +259,21 @@ u16 *u16_strcpy(u16 *dest, const u16 *src); */ u16 *u16_strdup(const void *src); +/** + * u16_strlcat() - Append a length-limited, %NUL-terminated string to another + * + * Append the src string to the dest string, overwriting the terminating + * null word at the end of dest, and then adds a terminating null word. + * It will append at most size - u16_strlen(dst) - 1 bytes, NUL-terminating the result. + * + * @dest: destination buffer (null terminated) + * @src: source buffer (null terminated) + * @size: destination buffer size in bytes + * Return: total size of the created string in bytes. + * If return value >= size, truncation occurred. + */ +size_t u16_strlcat(u16 *dest, const u16 *src, size_t size); + /** * utf16_to_utf8() - Convert an utf16 string to utf8 * diff --git a/lib/charset.c b/lib/charset.c index f44c58d9d8..47997eca7d 100644 --- a/lib/charset.c +++ b/lib/charset.c @@ -428,6 +428,27 @@ u16 *u16_strdup(const void *src) return new; } +size_t u16_strlcat(u16 *dest, const u16 *src, size_t size) +{ + size_t dstrlen = u16_strnlen(dest, size >> 1); + size_t dlen = dstrlen * sizeof(u16); + size_t len = u16_strlen(src) * sizeof(u16); + size_t ret = dlen + len; + + if (dlen >= size) + return ret; + + dest += dstrlen; + size -= dlen; + if (len >= size) + len = size - sizeof(u16); + + memcpy(dest, src, len); + dest[len >> 1] = u'\0'; + + return ret; +} + /* Convert UTF-16 to UTF-8. */ uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size) { From patchwork Thu Mar 24 13:54: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: 553914 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:1248:0:0:0:0 with SMTP id z8csp4438267mag; Thu, 24 Mar 2022 06:55:27 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzgxXspgjoEPtph82cunVyVF3DMaeFtzJOifzxeZU7ZIWa38uf382VTSlL/hEYFvhUy/Obm X-Received: by 2002:a17:906:e28a:b0:6d6:e2e9:d39d with SMTP id gg10-20020a170906e28a00b006d6e2e9d39dmr5923029ejb.2.1648130126879; Thu, 24 Mar 2022 06:55:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648130126; cv=none; d=google.com; s=arc-20160816; b=J5tpdFrngUxCRs6zz0ogkWEBw+v7XCE3ZWpZ2c90pT6jnLMFeB+mjoTAuEUoQPjx5Z DoiGX1IghynOjrkSfuwJtg0nwwbyzZcP4wxP0zpRUGbKTM10+E89uzf2JxLNCWH95MbE rtlhssuyU/x275ykBlxoyrAdrjUPOeguvwd97wE1jIQAY+4dflSUTrdoyARXpgBzAx9i H+MAc0vetCmAFquBNe53RlRFcbbisKSg9VUiIF/sG3C/sUDInijIP/6GwSoB6lH+eSi8 PprWa1Skqe0c9xZLM2tG0cpf5vFRJqL111C0xEbW3xszu5dC1fCtf4tNL4yQAKGbkwP7 g34A== 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=WbGWy1ftbC23huCet0201xoU+6I2uYKaBD5Szx9Q3Sg=; b=FjtZeIC4hFZQyQLKZQ7nRGMiXfODT6ue6gT9VxUEQeL3oLi0yHytqvPrvmuJOyQvwd a7cX7sdQc2ISPscOQZpIZJ2zFjBE6RWRsFcdyBLQe7e2iGbc1WxHXc8J5esUBkblLPAD Fb9EgJw5o4hn/9ydjDs1tw2sh+Gh8Dpkop+x3arwn6lFRy3kEWGhS4RyZh7gWJSm9SuI EmzJZyniCXEMt/7HnpHNEJMzXwrj9BYAf/WU1RhoRlvh41sTSDPPsWCmE9ZKglLkVeTb 86tTemb5KtStDqlBW0sJ7om4kMzfcWLqZX4WU+CTsNasYbepJ/nPoQGQihNb/OxnQq4V suZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=YKM3V9mW; 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 m21-20020a50d7d5000000b00418c2b5bdedsi24845754edj.207.2022.03.24.06.55.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:55:26 -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=YKM3V9mW; 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 668FB840B8; Thu, 24 Mar 2022 14:54:59 +0100 (CET) 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="YKM3V9mW"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 66940840AB; Thu, 24 Mar 2022 14:54:50 +0100 (CET) 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-x102a.google.com (mail-pj1-x102a.google.com [IPv6:2607:f8b0:4864:20::102a]) (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 529D0840AB for ; Thu, 24 Mar 2022 14:54:47 +0100 (CET) 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-x102a.google.com with SMTP id gp15-20020a17090adf0f00b001c7cd11b0b3so685857pjb.3 for ; Thu, 24 Mar 2022 06:54:47 -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=WbGWy1ftbC23huCet0201xoU+6I2uYKaBD5Szx9Q3Sg=; b=YKM3V9mWyPK6+qSAtuwLgvTsBe0ax0CRlm4eBezkEXWtfPNgIs6D1Zytr8DKWSBDyI Pd8gZlgbdT5VdKFdRjz0tAm/Zq/kpVtWmsRYghRC1PO2qTcxCpvQPx2TapwcQUx6UjhD eejNJlOE3VjnIHH+nvQ/ho1fbPm9/lBoB+AYktqQB3l1Vy0fkUjHFssw58seMrS1XrdQ prkxFyOQwW1dIopGb5E12co1Zu1kOYmj/6VeH9Z4eIIzyOaq8Erd28h/4PTP8E1qz05e 7eYjFQX+SumVbBGaMjvkez+7XQjumEbK+549CCITICAl1PzRLrPO+FeZBXj9IEHx2DyA H6mA== 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=WbGWy1ftbC23huCet0201xoU+6I2uYKaBD5Szx9Q3Sg=; b=5yvZgfcf7TtSMxweWgZWJPDs0/hM31BEbGtlGUytRxjmx1yOQZbW739X86AfbSmKLp OANNaYycEXwe/YJ4ScSCbiceG0IYD1h5PNVx+vbSp4C6QYlnsPR3P77FavECI2dVnOFr IKDuG87Y1Rc/pL+OJks7mxL1fhEK6fX+cn51jQMSYthIJ+WqhsalrDnRO/GUP+Zfsai3 TsZDEaVf+62Y11fzLng+SaBVBRS9l770DVUUs9CeZkGrcmt5w2amOcPIZNd8hdyTIcl6 bKlwQQZjY+0z7kr2qH/bOHxWKsPF3ycWnA/JaKNsUIjbqurV870SAnG014jamG/Z4HZQ kv+g== X-Gm-Message-State: AOAM532UaZzfjf7Ztv43xrfvIqDbQqOQKh47oDklY7YhhyNq89jR+SgI f9jdFbF8FcexK1OxxgTs8fUlp4Ro+4wG9Q== X-Received: by 2002:a17:902:f54c:b0:154:6794:ab18 with SMTP id h12-20020a170902f54c00b001546794ab18mr6172710plf.118.1648130085624; Thu, 24 Mar 2022 06:54:45 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id p15-20020a056a000a0f00b004f7c63cba5asm3974609pfh.21.2022.03.24.06.54.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:54:45 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima Subject: [PATCH v4 03/11] test: unit test for u16_strlcat() Date: Thu, 24 Mar 2022 22:54:35 +0900 Message-Id: <20220324135443.1571-4-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220324135443.1571-1-masahisa.kojima@linaro.org> References: <20220324135443.1571-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.5 at phobos.denx.de X-Virus-Status: Clean Provide a unit test for function u16_strlcat(). Signed-off-by: Masahisa Kojima Reviewed-by: Simon Glass --- No change since v2 Newly created in v2 test/unicode_ut.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/test/unicode_ut.c b/test/unicode_ut.c index f2f63d5367..f79b0439bc 100644 --- a/test/unicode_ut.c +++ b/test/unicode_ut.c @@ -758,6 +758,51 @@ static int unicode_test_efi_create_indexed_name(struct unit_test_state *uts) UNICODE_TEST(unicode_test_efi_create_indexed_name); #endif +static int unicode_test_u16_strlcat(struct unit_test_state *uts) +{ + u16 buf[11]; + u16 dest[] = u"U-Boot"; + u16 src[] = u"test"; + u16 expected[] = u"U-Boottest"; + u16 null_src = u'\0'; + size_t ret; + + memcpy(buf, dest, sizeof(dest)); + ret = u16_strlcat(buf, src, sizeof(buf)); + ut_asserteq(20, ret); + ut_assert(!unicode_test_u16_strcmp(buf, expected, 11)); + + /* dest is empty string */ + memset(buf, 0, sizeof(buf)); + ret = u16_strlcat(buf, src, sizeof(buf)); + ut_asserteq(8, ret); + ut_assert(!unicode_test_u16_strcmp(buf, src, 11)); + + /* src is empty string */ + memset(buf, 0, sizeof(buf)); + memcpy(buf, dest, sizeof(dest)); + ret = u16_strlcat(buf, &null_src, sizeof(buf)); + ut_asserteq(12, ret); + ut_assert(!unicode_test_u16_strcmp(buf, dest, 11)); + + /* size is smaller than dest size */ + memset(buf, 0, sizeof(buf)); + memcpy(buf, dest, sizeof(dest)); + ret = u16_strlcat(buf, src, 6); + ut_asserteq(14, ret); + ut_assert(!unicode_test_u16_strcmp(buf, dest, 11)); + + /* size is insufficient to append src string */ + memset(buf, 0, sizeof(buf)); + memcpy(buf, dest, sizeof(dest)); + ret = u16_strlcat(buf, src, 20); + ut_asserteq(20, ret); + ut_assert(!unicode_test_u16_strcmp(buf, u"U-Boottes", 11)); + + return 0; +} +UNICODE_TEST(unicode_test_u16_strlcat); + int do_ut_unicode(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { struct unit_test *tests = UNIT_TEST_SUITE_START(unicode_test); From patchwork Thu Mar 24 13:54: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: 553915 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:1248:0:0:0:0 with SMTP id z8csp4438502mag; Thu, 24 Mar 2022 06:55:43 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzN/ldRANLdmthPr1FuICBUxAlcPrG9x1B3qAgnKVvQrDKu1iiwPGSZpWWOchdv0hlikrDL X-Received: by 2002:a17:907:980a:b0:6db:799c:cb44 with SMTP id ji10-20020a170907980a00b006db799ccb44mr5864862ejc.485.1648130143218; Thu, 24 Mar 2022 06:55:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648130143; cv=none; d=google.com; s=arc-20160816; b=JUyA111ukKFerYhbau9oQk/IwyLTrGAUxy0XOvm9/aKo2xw6EF1n0fmCQa0g8U5MLE YfvjuvBb0jVyieixyHIAhrGSW9My98RHYJ6kbRhuXC57EMQhM6SnM8HwgGfjNp/Abdpz 6VDstZH9GsCatzBGbUOlKgWMUhRQcmJ9Li38/SCcj8ZTixr9x1g0GNHDzen07TKHt0Vb 4Vx3Gmhny/DcFkbKVCV9MzW6TMVtDOPZQsj1PSyrOoWapZaVhzzkAdgFj/E6rmLO+dwl SU+TKAChclljGE5eSy2w378Huu44d/dGYIdbjTgQdyGQmcLfLzKZRH2neDOWAvp2+Nsc 7OZg== 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=inPoRgeH+VJX8pUin3UaTZQE8S9q7KobOwG0AX/qUsU=; b=gI4wtWuDNCxsN5W0awaN5nwPnmbgJa3PTeIa1eIEPbXH+7PhyfYUruVdBIGDqTPrKq CIevU2bjY+G11nWco9ZIuKFFXriOfTgb+5lbZ2VdO/PzgzUqniYrL9KFmZxi/BDEb5fA FaxFuWwy7aSXzUcoYDdLaH5S7Zxt1AGAKcFrN0xP4YCIJVHTWCIwMtIcFjbONKZEc2+x Epe+E+3eYa5pEpLaVtmF/BaGC7WzOf2X03OygiAGodCCXUWkiZd87GBSZmJH+ou/NN1k oLlnOPYse6olLdMLRWU8sc4qxUDx8Zh5GK4+/6PezYc+f87cydRkRoQjK3v2vV/UyXMy jkiQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Deb6nchD; 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 b16-20020a170906729000b006df76385bccsi14047462ejl.108.2022.03.24.06.55.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:55:43 -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=Deb6nchD; 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 4273B840C9; Thu, 24 Mar 2022 14:55:05 +0100 (CET) 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="Deb6nchD"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 4332A840BF; Thu, 24 Mar 2022 14:54:53 +0100 (CET) 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-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) (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 45046840B4 for ; Thu, 24 Mar 2022 14:54:50 +0100 (CET) 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-x102b.google.com with SMTP id mj15-20020a17090b368f00b001c637aa358eso9591336pjb.0 for ; Thu, 24 Mar 2022 06:54:50 -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=inPoRgeH+VJX8pUin3UaTZQE8S9q7KobOwG0AX/qUsU=; b=Deb6nchDY67BiIer70SW72Atux6OMNUtHI6fgd9Z7xfKrxjv8cdjlwr+Wf7YJW6FWB rQkLx0tUbhJQkBbYCtMd7ijAUjjQnv1+m5IskhsxLsYETKW/Xn045gPm+vgIus9PUU6O pwcMbV/fjBlbUEvXkQ1C57qUeHcwg13K0kldcAClRLw3N+Cd0YyOTqEUaEpCCCvobPuX foxz/wSUzEo/LQN/TV5kb/qvypUpgTkpViE5sw708mWAmFotfQKERJtXnWrVER5yekbH p0kapZKIvpH/YpyEElJHxKFWX/zsN5eqU1NFba6C5I5O9j2KxXD8uRsnuNjG0cCr54gR IWhw== 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=inPoRgeH+VJX8pUin3UaTZQE8S9q7KobOwG0AX/qUsU=; b=3647cYCL39FWrAtQnNpLVLWGLLiG/uvGJr8zi1U47d5yY2HNSSSzGfQU7Xqsb6bhze nZjNtzibgJrLLMetdbn79UqmZ7FG1SMe99+mZXteZt5LasgZtA9fuEOy+ohg7LVkwhcM //cK+OvEdxgTWbFXccB5lYNUkC4hme/1yxeeFmCjMTfHGfJxm5fs/smVfIh2at1M2LyP RMIkRDRndxld+/Wivk0/Fn863IARW9GlM4upBKo9Y65CZMfZRrrR465IYY49R1R68DG7 OSLQX9VdkaMRx81Y6gI8rfBasrgOS32acX1ODoaNPeN0Ksbw9XWWP5/TrDqkrxtIESgc 4GIg== X-Gm-Message-State: AOAM531VjArwxm2A2zti9psllLUr24On+uYtXzs22XoFjL5mWBHhxXqd 50nj6OJMRaEEj6Hel3ib0D3cuGj6Bo8ejA== X-Received: by 2002:a17:903:20c:b0:154:b58:d424 with SMTP id r12-20020a170903020c00b001540b58d424mr5789787plh.45.1648130088527; Thu, 24 Mar 2022 06:54:48 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id p15-20020a056a000a0f00b004f7c63cba5asm3974609pfh.21.2022.03.24.06.54.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:54:48 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima Subject: [PATCH v4 04/11] menu: always show the menu regardless of the number of entry Date: Thu, 24 Mar 2022 22:54:36 +0900 Message-Id: <20220324135443.1571-5-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220324135443.1571-1-masahisa.kojima@linaro.org> References: <20220324135443.1571-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.5 at phobos.denx.de X-Virus-Status: Clean To make user aware of the menu entry selection, menu always appears regardless of the number of entry. Signed-off-by: Masahisa Kojima --- Newly created in v4 common/menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/menu.c b/common/menu.c index 5fb2ffbd06..b577d80b4f 100644 --- a/common/menu.c +++ b/common/menu.c @@ -271,7 +271,7 @@ int menu_get_choice(struct menu *m, void **choice) if (!m || !choice) return -EINVAL; - if (!m->prompt || m->item_cnt == 1) + if (!m->prompt) return menu_default_choice(m, choice); return menu_interactive_choice(m, choice); From patchwork Thu Mar 24 13:54: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: 553916 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:1248:0:0:0:0 with SMTP id z8csp4438688mag; Thu, 24 Mar 2022 06:55:57 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzKFLNjTeaeT0ojtgya2ltsvkxbFrGrRDaS6XU12pfdrwNlJ7v03xMoXOmJ1CUoAsP/Bu1M X-Received: by 2002:a17:907:7711:b0:6ce:e03c:e1e2 with SMTP id kw17-20020a170907771100b006cee03ce1e2mr5762418ejc.769.1648130157454; Thu, 24 Mar 2022 06:55:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648130157; cv=none; d=google.com; s=arc-20160816; b=UTCJtGutUK4O9itx8ccrQskfzJUd4a/l7D8wuS/hvskGdgcY5Ps2o1jEXHibKgXETC ubKFtqDx8CuAo5VG6XtMpPu+uazL1c3BdjIs79oSVBlqH0BogppJGNv7tfFesmYJ7jS/ 3e0O/vaLrpyWOKIn6VONB87Ic5or79kHSMMJBUqpljOC1XOp4LTIW35w6KZJdmkZKiZU UaPRZJaeQ4oUkAvUMzt06b6ksMkCPy4gfnZXg66Hb+h4dml74Gd4UUjojNuQrXUXdXFM uDW07rfUlP+bGn7b7rrq/znXMePP1OtXJ46TNVROq1QBYyehND6vIz/IjVPeIdI8XKsd ezdA== 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=xvVdSORk6u4Mc23DqOajg9xXbHy3DSF6AJNDQ5Ve8rg=; b=CdL3DKDlUxT+F4cg8gZY2AOOIbgA+A1WgFvmjPJN4wez2XD0Bd+ps0m81lc2Y1JCYS VgI+7PFhlZqNAfzjQ1Fn1puXT/3S4P0dXfLu0lQkqzy3C2CEsNaTRBTRbPpdMarzhmxs o7hW8o4qlQ19F2XkdLHpTLhl7FsWzDPppvg2fHKICJzb4OMe+uy2tB90Ooi1NJ+2RDpp wMVJ30vcd7nkRYbNtruvN4mmsfnCcOJZQ3+GE8f8BZm23yXP1qFNvVVpey66t4iNOb0e IXX1rGVo7A9i3lpeLrsRZcWhl3y1OK389yTp9KFlkBb9ihs0ex+b1MDDni+hEpwtaceV bFjA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=DJ7GFGe6; 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 hc38-20020a17090716a600b006df76385d6esi20506268ejc.526.2022.03.24.06.55.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:55: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=DJ7GFGe6; 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 81151840C5; Thu, 24 Mar 2022 14:55:10 +0100 (CET) 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="DJ7GFGe6"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id DC9C6840B8; Thu, 24 Mar 2022 14:54:56 +0100 (CET) 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-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) (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 BA1AF840BB for ; Thu, 24 Mar 2022 14:54:52 +0100 (CET) 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-x62d.google.com with SMTP id x2so4755908plm.7 for ; Thu, 24 Mar 2022 06:54:52 -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=xvVdSORk6u4Mc23DqOajg9xXbHy3DSF6AJNDQ5Ve8rg=; b=DJ7GFGe6IaZUQ9nxDPLxEkA7FFf3kDAKFzh9P4yo3iCfSgCgomeoOCg1AMip4WhPrt /UUc1Hi1NMdRqxRWhABH/jswu9W2eIrQGFOu7Z9VUGVL6pqL6Nyrjg/5qYFoZFCfA4qC h4w/JKYMaY2NnmOyo+wkksqqvhZxNMKDXI8ThAMjqeAscRCBRP32veWtT/Wt7m8QSZUp gcBHxJmWPpgbf8oewZ6oCc3fgHJsnOtV4gTWaePZJNr6IhL4ZKZ9mhKJdn9aLWpz7gc4 YbJMF/aHMDuptzzN9RyH2hsakPVnMG8r4nN0dYXpH5coYQYbQYd316mAB3RRr4AGQ14q jBTA== 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=xvVdSORk6u4Mc23DqOajg9xXbHy3DSF6AJNDQ5Ve8rg=; b=F/clyffu5TSv9fa0OzIvSOYJks9BuepjRN08q/j6gx8I/UWFNjW9zLjSoQ5AdLn+Nh 0FBu0QSjYI+IGm7nkyj11uD3wSq6/xcTcxRIXqBG0mid4oEGll3v99/NtXkpXI/KOgwz NG3w6Dy2aS0VnImHeb2mNlFvizfXvVPvgF54SW5LQCaudD3a/Mtv+wNBYiIAv7Hu0DxM S85gO+NLQ6XeVT0B4/oVaGmvDBpUN3djhIpJF/4AJOATjnfR2WEVkj4VDxEgSdHpeGdE UNJZXTxG/Oe/g1CWUNlKGqm7mVpd0pqxO8/6pyAKBFcnxs3fgHmzwz8V/fftJyVoWicf W8sQ== X-Gm-Message-State: AOAM531Z/BDdbn45uAHspCO4Of8YBDym7t7QDvXtAcR2vHkfteJ6WmCt ounI4ARyrheb5oyCyzP4Jt/eV8z3fjUnAg== X-Received: by 2002:a17:90a:1db:b0:1bf:711d:267a with SMTP id 27-20020a17090a01db00b001bf711d267amr6444962pjd.155.1648130091091; Thu, 24 Mar 2022 06:54:51 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id p15-20020a056a000a0f00b004f7c63cba5asm3974609pfh.21.2022.03.24.06.54.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:54:50 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima Subject: [PATCH v4 05/11] efi_loader: export efi_locate_device_handle() Date: Thu, 24 Mar 2022 22:54:37 +0900 Message-Id: <20220324135443.1571-6-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220324135443.1571-1-masahisa.kojima@linaro.org> References: <20220324135443.1571-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.5 at phobos.denx.de X-Virus-Status: Clean From: AKASHI Takahiro This function will be used in the next commit where some behavior of EFI boot manager will be expanded. Signed-off-by: AKASHI Takahiro Reviewed-by: Ilias Apalodimas --- No changes from original version include/efi_loader.h | 4 ++++ lib/efi_loader/efi_boottime.c | 7 +++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index af36639ec6..ce22660d5b 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -593,6 +593,10 @@ efi_status_t efi_create_handle(efi_handle_t *handle); void efi_delete_handle(efi_handle_t obj); /* Call this to validate a handle and find the EFI object for it */ struct efi_object *efi_search_obj(const efi_handle_t handle); +/* Locate device_path handle */ +efi_status_t EFIAPI efi_locate_device_path(const efi_guid_t *protocol, + struct efi_device_path **device_path, + efi_handle_t *device); /* Load image */ efi_status_t EFIAPI efi_load_image(bool boot_policy, efi_handle_t parent_image, diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 5bcb8253ed..4da64b5d29 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1799,10 +1799,9 @@ failure: * * Return: status code */ -static efi_status_t EFIAPI efi_locate_device_path( - const efi_guid_t *protocol, - struct efi_device_path **device_path, - efi_handle_t *device) +efi_status_t EFIAPI efi_locate_device_path(const efi_guid_t *protocol, + struct efi_device_path **device_path, + efi_handle_t *device) { struct efi_device_path *dp; size_t i; From patchwork Thu Mar 24 13:54: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: 553917 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:1248:0:0:0:0 with SMTP id z8csp4438865mag; Thu, 24 Mar 2022 06:56:09 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx8CcJrsUvjdyY3wARM/p3oxcYNgaEEouWfCfLEShkdw+SJgUWf5i5iAtl4TvNEmAmcUNJc X-Received: by 2002:a17:907:9805:b0:6db:4c33:7883 with SMTP id ji5-20020a170907980500b006db4c337883mr6031763ejc.555.1648130168849; Thu, 24 Mar 2022 06:56:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648130168; cv=none; d=google.com; s=arc-20160816; b=Wu0JKl7ljgFUtFKfBWYsqPn6f4cWj0ZzdWifm//RW/agZdBvkdrgjx/haXQ7aOKutu vcQuiB32uiTw57sNpT17K6durjTAe/b67vddndItmqDGEMwuWveJcqyRFbb3OBYLY2Ox VmFM9up/6bc8ZAGvBy5CmfhC+AY8AoTzc7eziHKOy7TNqidfCKBOvUwMWejFMkqXZ4+N 2Rez8ZQqSNAkmJG6iID7EF8e29X2zCa2/vL7O7yojSuEwjVauEldfPyImMm+eP2NmR/C Bqvyz0egjjwxwXI9jmqwssIZeJzL9b/ney+HO+8DFZzkJ6GAftLhYV8J1nUvawY2cW3J 2feQ== 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=GOezjTssLHvI1Nn5U9dVQHrrcZp9+fMf0V7XRbaJooU=; b=gxmlGkaSb5l0hKhDsO3zT1mCyl0pbgiDDZNSzgJZh1tp5RUZeM36oZeUlHYjYud2lx NvP05sQJSzYpy5bxSgA45GJTCreKvkc+bdSbICDBdx5x0g+uAb/c2iWT2M8o7sYo4tJs G9jmcMY3CqJtlSqG17sdb7rZstw5Kz4loeEVW5sPaIlcSkVCLnSPzbA4QloagZENhG9S G3//LCbotD4i0dWDVZdo5UD2F90DMd4BAfmiwXoDDGHcON4S4mK8SOZF9C/8kkA1ixOe 0z8uX9/0zNGUBmT4ig6x0C/iZ0DO2pJ+aORT+4AGIA8h6sHeZv30hel8ida1jGn3wl62 bATg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ikQOp+8t; 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 26-20020a17090600da00b006df76385c0csi16096721eji.172.2022.03.24.06.56.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:56:08 -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=ikQOp+8t; 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 5912C840C4; Thu, 24 Mar 2022 14:55:21 +0100 (CET) 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="ikQOp+8t"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id EB730840BB; Thu, 24 Mar 2022 14:54:59 +0100 (CET) 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-x632.google.com (mail-pl1-x632.google.com [IPv6:2607:f8b0:4864:20::632]) (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 57295840B7 for ; Thu, 24 Mar 2022 14:54:56 +0100 (CET) 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-x632.google.com with SMTP id k6so4735161plg.12 for ; Thu, 24 Mar 2022 06:54:56 -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=GOezjTssLHvI1Nn5U9dVQHrrcZp9+fMf0V7XRbaJooU=; b=ikQOp+8tcEQZr2IGr9LAonNjHiadfOwAyP0GIu+RW5w7wWrGCQs1lAsv5iVG8HLE/W k4YD3GJuxG44h6DapZRlinMtzrYykhMTznWnzdGdBT/7CYu3ewocuZfAHN9cFUSvqA02 bLjrmi2r3kgfcBBjGJLzdXsUY/W7cOruhegbsBrzayW8ABJjqnNKTUad69dmCJF0wYUT uYXfSvYk5Yra7hMINwmjkUvUzPP50QXuOv9rfRFkyM0qGD2ta/ZX5i9VgjEVipzCclDO jAnqdplqvHEvS0R0BoRo5btWtoUeb4YL+VP6HTujpLPmsWU2MRcaANRxG1Y18PeqAcmO x/Ow== 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=GOezjTssLHvI1Nn5U9dVQHrrcZp9+fMf0V7XRbaJooU=; b=xoFSRwPUdShdZV/JgrPQf7DYxpRoT/fOtmAh1d0VUyYNSPT5X6IsKp/HCcyixaGfE7 S/9P9SiL9xqB0stqXrKmyjiW9IwSl18JHrzp61OC6Nqg721IHRYl/gNMassJyVQFSIZy b9efCUSAlraeYjCHE5u4gu/By3/YMXU9WOhk6UcPsmuNmvrfY++ez8g6cmVWPjz3fFgg oCDhgWN/TvDQjGfNcYOr69oNYu+Uc1yq2FxBfsTHkVvIjQg2ePp9M9DV8x+ejaXn8s8Z 7oKOk+BFJP8ohGvacAOEuM8hfg2w21SFq9yCOiAUkV5Nt0tvouJdNUe+ejLPHNFtpK9v ZNWw== X-Gm-Message-State: AOAM531Iw4MLIIhyF5/CdStbt/lss09SB4j3Apf8QMh6cEOBoBje5XP6 DlXOQ8tw76mL7YklN+RFssdR5RjqyYHCcw== X-Received: by 2002:a17:90a:5b0d:b0:1bc:7e66:2970 with SMTP id o13-20020a17090a5b0d00b001bc7e662970mr6424645pji.12.1648130094487; Thu, 24 Mar 2022 06:54:54 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id p15-20020a056a000a0f00b004f7c63cba5asm3974609pfh.21.2022.03.24.06.54.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:54:54 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima , Mark Kettenis , Andre Przywara , Neil Armstrong Subject: [PATCH v4 06/11] efi_loader: bootmgr: add booting from removable media Date: Thu, 24 Mar 2022 22:54:38 +0900 Message-Id: <20220324135443.1571-7-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220324135443.1571-1-masahisa.kojima@linaro.org> References: <20220324135443.1571-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.5 at phobos.denx.de X-Virus-Status: Clean From: AKASHI Takahiro Under the current implementation, booting from removable media using a architecture-specific default image name, say BOOTAA64.EFI, is supported only in distro_bootcmd script. See the commit 74522c898b35 ("efi_loader: Add distro boot script for removable media"). This is, however, half-baked implementation because 1) UEFI specification requires this feature to be implemented as part of Boot Manager's responsibility: 3 - Boot Manager 3.5.1 Boot via the Simple File Protocol When booting via the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, the FilePath will start with a device path that points to the device that implements the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL or the EFI_BLOCK_IO_PROTOCOL. The next part of the FilePath may point to the file name, including subdirectories, which contain the bootable image. If the file name is a null device path, the file name must be generated from the rules defined below. ... 3.5.1.1 Removable Media Boot Behavior To generate a file name when none is present in the FilePath, the firmware must append a default file name in the form \EFI\BOOT\BOOT{machine type short-name}.EFI ... 2) So (1) entails the hehavior that the user's preference of boot media order should be determined by Boot#### and BootOrder variables. With this patch, the semantics mentioned above is fully implemented. For example, if you want to boot the system from USB and SCSI in this order, * define Boot0001 which contains only a device path to the USB device (without any file path/name) * define Boot0002 which contains only a device path to the SCSI device, and * set BootOrder to Boot0001:Boot0002 Signed-off-by: AKASHI Takahiro Signed-off-by: Masahisa Kojima --- Changes from original version: - create new include file "efi_default_filename.h" to avoid conflict with config_distro_bootcmd.h - modify the target pointer of efi_free_pool(), expand_media_path() should only free the pointer allocated by efi_dp_from_file() function. include/config_distro_bootcmd.h | 14 +-------- include/efi_default_filename.h | 26 +++++++++++++++++ lib/efi_loader/efi_bootmgr.c | 50 ++++++++++++++++++++++++++++++++- 3 files changed, 76 insertions(+), 14 deletions(-) create mode 100644 include/efi_default_filename.h diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index 2f90929178..ef2c9f330e 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -91,19 +91,7 @@ #endif #ifdef CONFIG_EFI_LOADER -#if defined(CONFIG_ARM64) -#define BOOTEFI_NAME "bootaa64.efi" -#elif defined(CONFIG_ARM) -#define BOOTEFI_NAME "bootarm.efi" -#elif defined(CONFIG_X86_RUN_32BIT) -#define BOOTEFI_NAME "bootia32.efi" -#elif defined(CONFIG_X86_RUN_64BIT) -#define BOOTEFI_NAME "bootx64.efi" -#elif defined(CONFIG_ARCH_RV32I) -#define BOOTEFI_NAME "bootriscv32.efi" -#elif defined(CONFIG_ARCH_RV64I) -#define BOOTEFI_NAME "bootriscv64.efi" -#endif +#include #endif #ifdef BOOTEFI_NAME diff --git a/include/efi_default_filename.h b/include/efi_default_filename.h new file mode 100644 index 0000000000..de030d2692 --- /dev/null +++ b/include/efi_default_filename.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Default boot file name when none is present in the FilePath. + * + * Copyright (c) 2022, Linaro Limited + */ +#ifndef _EFI_DEFAULT_FILENAME_H +#define _EFI_DEFAULT_FILENAME_H + +#if defined(CONFIG_ARM64) +#define BOOTEFI_NAME "BOOTAA64.EFI" +#elif defined(CONFIG_ARM) +#define BOOTEFI_NAME "BOOTARM.EFI" +#elif defined(CONFIG_X86_64) +#define BOOTEFI_NAME "BOOTX64.EFI" +#elif defined(CONFIG_X86) +#define BOOTEFI_NAME "BOOTIA32.EFI" +#elif defined(CONFIG_ARCH_RV32I) +#define BOOTEFI_NAME "BOOTRISCV32.EFI" +#elif defined(CONFIG_ARCH_RV64I) +#define BOOTEFI_NAME "BOOTRISCV64.EFI" +#else +#error Unsupported UEFI architecture +#endif + +#endif diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 8c04ecbdc8..22a4302aac 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,50 @@ static const struct efi_runtime_services *rs; * should do normal or recovery boot. */ +/** + * expand_media_path() - expand a device path for default file name + * @device_path: device path to check against + * + * If @device_path is a media or disk partition which houses a file + * system, this function returns a full device path which contains + * an architecture-specific default file name for removable media. + * + * Return: a newly allocated device path + */ +static +struct efi_device_path *expand_media_path(struct efi_device_path *device_path) +{ + struct efi_device_path *dp, *full_path; + efi_handle_t handle; + efi_status_t ret; + + if (!device_path) + return NULL; + + /* + * If device_path is a (removable) media or partition which provides + * simple file system protocol, append a default file name to support + * booting from removable media. + */ + dp = device_path; + ret = efi_locate_device_path(&efi_simple_file_system_protocol_guid, + &dp, &handle); + if (ret == EFI_SUCCESS) { + if (dp->type == DEVICE_PATH_TYPE_END) { + dp = efi_dp_from_file(NULL, 0, + "/EFI/BOOT/" BOOTEFI_NAME); + full_path = efi_dp_append(device_path, dp); + efi_free_pool(dp); + } else { + full_path = efi_dp_dup(device_path); + } + } else { + full_path = efi_dp_dup(device_path); + } + + return full_path; +} + /** * try_load_entry() - try to load image for boot option * @@ -68,13 +113,16 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle, } if (lo.attributes & LOAD_OPTION_ACTIVE) { + struct efi_device_path *file_path; u32 attributes; log_debug("%s: trying to load \"%ls\" from %pD\n", __func__, lo.label, lo.file_path); - ret = EFI_CALL(efi_load_image(true, efi_root, lo.file_path, + file_path = expand_media_path(lo.file_path); + ret = EFI_CALL(efi_load_image(true, efi_root, file_path, NULL, 0, handle)); + efi_free_pool(file_path); if (ret != EFI_SUCCESS) { log_warning("Loading %ls '%ls' failed\n", varname, lo.label); From patchwork Thu Mar 24 13:54:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 553918 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:1248:0:0:0:0 with SMTP id z8csp4438986mag; Thu, 24 Mar 2022 06:56:20 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyONZeRCWxgHkVp5X4zrF4i62fjp0tBEG7s0x4AWX/nt6xQRqyIeL/zqvsSYaWoBppknz4U X-Received: by 2002:a17:906:2a0c:b0:6df:ec76:af8c with SMTP id j12-20020a1709062a0c00b006dfec76af8cmr5759801eje.269.1648130180377; Thu, 24 Mar 2022 06:56:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648130180; cv=none; d=google.com; s=arc-20160816; b=sVwTHDfayfRhZb3LQQdq1R+if0N0dGkAZlIS1getr+YiQyeYq+m/RmFwGVtVFFFuO3 hwqcjDEGLaG9j9rJoJ3A3u+ALGmkoun7en8xAgH9zEP9+dFu7W/p7CHjsYJUBp95SKYY e8HuMqfWSn7sUBoVtVXm5qTe38MpbdrcoIsCV/uE4GWmdY/jhZEviF8otQCKO9w0kG3F HYetDDwr3YRa0QvB/6a4sPc9PwJ88ttXfbpcqnyhfNaeXWvq7s0qf6oQZZojeOc4/lfA 3FRWl0I7SsOb88RayjfOK4YYcw0Zxd0ooGegtT1J1nX+p3d6H2fttdDHFHH63zhUCjPk +bRw== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=ipuQmM3oZLP1WmIxqKmCEQhRJj1SQDrjEpvrIgBOu5w=; b=s74MIJ8R+mT/0DPBYLqBkuXed78xiLb2uUwgwErj0t9aHAbltXYj9bBr+GgcqjgbIv V42qph6OipxgR7DzqV5eDEBBQh47HyOsYhMrNJ6hIxaBD4cvzJjIiIS35s6/V5udZPdG BzspKxXHpzkJeG/zER5HX7FrD5952TGVffL+GH9wSTVYBEGOqCEKLzbkST8oL/Thd8Ky R426SZbBQ0P4pgiZR5aIxvl9gXXo/rqK1p6+CPBJU6x5ECktqsH4uWvqLvyDVIiz/+uV VsqCCbv7K4it7j2oJqWCIA/3uMB6ouOlWwxUYStKbYioMKZowsrexvjzUo9oZkx+0RuB pO6Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=X6TIZxmA; 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 z2-20020a170906270200b006df76385e97si15655618ejc.823.2022.03.24.06.56.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:56:20 -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=X6TIZxmA; 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 0BE6B840D4; Thu, 24 Mar 2022 14:55:24 +0100 (CET) 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="X6TIZxmA"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 0A9B7840D1; Thu, 24 Mar 2022 14:55:11 +0100 (CET) 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-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) (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 9754A840BB for ; Thu, 24 Mar 2022 14:55:00 +0100 (CET) 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-x102c.google.com with SMTP id mp6-20020a17090b190600b001c6841b8a52so9527920pjb.5 for ; Thu, 24 Mar 2022 06:55:00 -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 :mime-version:content-transfer-encoding; bh=ipuQmM3oZLP1WmIxqKmCEQhRJj1SQDrjEpvrIgBOu5w=; b=X6TIZxmAYeyr8+to3wze0iw7+qRRYDKMxavGE11fM/hVSSvu5K306HCm1H14k4pJX5 +rDj8IIiwceHuRFWlh4Dk44kT4mUP+Y5Kxd8S7RoRcIdfUT6C7ZxBs3rewbT7K1XMrfV g5eGD/6jVCtFjijYpld9CFi9p8jtr8N3NIPkqQS6bXC30XXr1qAy7wFK799LUe/u73FN rpeJduNrKsA0l8nuPxtZfWvlge1flO98RAEFVFscZHO8mafBBtOnfrls9JYVIexqUoMz fTLXtrEb2ibYG1+z8o1mEEMd5jtjEVwtFHezittB1ltUzgpFLdPjc6aLs2eWqdRAZ4sj JfkA== 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:mime-version:content-transfer-encoding; bh=ipuQmM3oZLP1WmIxqKmCEQhRJj1SQDrjEpvrIgBOu5w=; b=uMrxBAyBjO1CNRd342vjscrkiZrYNj+rDq2RQ35YHxLo2XDP1+qUiFZv27U3cClQr/ fCmfW0Q4Oy7oNCX+BsdCwvI4uPyqtFnF04XJHhsixcha+NdpYDw1u3FZybeyLolgcSup q1cPdPvEKnDtdtbImNNB7qI8uDBfXksLeg52Cp45HKTJPvftwnGOUEolv+5KnycaaJfU a5uhGHHEUgE5OSXR0jECQuyGXaqmsOHdJ+tGzoBGPzNtWJl/EhvMQyMmtE5eZYtueuWP ObfdYB4LwDCEiK5H6faUA4mkS3TKiWjdL81DwonzXTK+9zckxjYxWnZsM5Vmej36pKLl 9oyA== X-Gm-Message-State: AOAM532fd8a6tODNUWqX5kX3KYppZDfDl7DZUfTipRgYLN12GgWv3een 9eNa+xY00eFWJMbpV1hrQ5EKu2sfbjsQPnHM X-Received: by 2002:a17:90b:1a87:b0:1c7:3d66:8cb with SMTP id ng7-20020a17090b1a8700b001c73d6608cbmr18677167pjb.142.1648130098704; Thu, 24 Mar 2022 06:54:58 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id p15-20020a056a000a0f00b004f7c63cba5asm3974609pfh.21.2022.03.24.06.54.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:54:58 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima , Peng Fan , Jaehoon Chung , Michal Simek , Kory Maincent , Aswath Govindraju , Ovidiu Panait , Ashok Reddy Soma , Franck LENORMAND Subject: [PATCH v4 07/11] bootmenu: add UEFI and disto_boot entries Date: Thu, 24 Mar 2022 22:54:39 +0900 Message-Id: <20220324135443.1571-8-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220324135443.1571-1-masahisa.kojima@linaro.org> References: <20220324135443.1571-1-masahisa.kojima@linaro.org> MIME-Version: 1.0 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.5 at phobos.denx.de X-Virus-Status: Clean This commit adds the UEFI related menu entries and distro_boot entries into the bootmenu. For UEFI, user can select which UEFI "Boot####" option to execute, call UEFI bootmgr and UEFI boot variable maintenance menu. UEFI bootmgr entry is required to correctly handle "BootNext" variable. For distro_boot, user can select the boot device included in "boot_targets" u-boot environment variable. The menu example is as follows. *** U-Boot Boot Menu *** bootmenu_00 : Boot 1. kernel bootmenu_01 : Boot 2. kernel bootmenu_02 : Reset board UEFI BOOT0000 : debian UEFI BOOT0001 : ubuntu distro_boot : usb0 distro_boot : scsi0 distro_boot : virtio0 distro_boot : dhcp Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit Signed-off-by: Masahisa Kojima --- Changes in v4: - add Kconfig option "CMD_BOOTMENU_ENTER_UBOOT_CONSOLE" to disable to enter U-Boot console from bootmenu - update the menu entry display format - create local function to create menu entry for bootmenu, UEFI boot option and distro boot command - handle "BootNext" before showing bootmenu - call "bootefi bootmgr" instead of "bootefi bootindex" - move bootmenu_show() into loop - add default boot behavior(run "bootefi bootmgr" then "run bootcmd") when user quit the bootmenu if U-Boot console is disabled Changes in v3: - newly created cmd/Kconfig | 10 ++ cmd/bootmenu.c | 393 +++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 360 insertions(+), 43 deletions(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index 5e25e45fd2..5fbeab266f 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -300,6 +300,16 @@ config CMD_BOOTMENU help Add an ANSI terminal boot menu command. +config CMD_BOOTMENU_ENTER_UBOOT_CONSOLE + bool "Allow Bootmenu to enter the U-Boot console" + depends on CMD_BOOTMENU + default n + help + Add an entry to enter U-Boot console in bootmenu. + If this option is disabled, user can not enter + the U-Boot console from bootmenu. It increases + the system security. + config CMD_ADTIMG bool "adtimg" help diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index d573487272..947b3a49ff 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -3,9 +3,12 @@ * (C) Copyright 2011-2013 Pali Rohár */ +#include #include #include #include +#include +#include #include #include #include @@ -24,11 +27,27 @@ */ #define MAX_ENV_SIZE (9 + 2 + 1) +enum bootmenu_ret { + BOOTMENU_RET_SUCCESS = 0, + BOOTMENU_RET_FAIL, + BOOTMENU_RET_QUIT, + BOOTMENU_RET_UPDATED, +}; + +enum boot_type { + BOOTMENU_TYPE_NONE = 0, + BOOTMENU_TYPE_BOOTMENU, + BOOTMENU_TYPE_UEFI_BOOT_OPTION, + BOOTMENU_TYPE_DISTRO_BOOT, +}; + struct bootmenu_entry { unsigned short int num; /* unique number 0 .. MAX_COUNT */ char key[3]; /* key identifier of number */ - char *title; /* title of entry */ + u16 *title; /* title of entry */ char *command; /* hush command of entry */ + enum boot_type type; /* boot type of entry */ + u16 bootorder; /* order for each boot type */ struct bootmenu_data *menu; /* this bootmenu */ struct bootmenu_entry *next; /* next menu entry (num+1) */ }; @@ -75,7 +94,14 @@ static void bootmenu_print_entry(void *data) if (reverse) puts(ANSI_COLOR_REVERSE); - puts(entry->title); + if (entry->type == BOOTMENU_TYPE_BOOTMENU) + printf("bootmenu_%02d : %ls", entry->bootorder, entry->title); + else if (entry->type == BOOTMENU_TYPE_UEFI_BOOT_OPTION) + printf("UEFI BOOT%04X : %ls", entry->bootorder, entry->title); + else if (entry->type == BOOTMENU_TYPE_DISTRO_BOOT) + printf("distro_boot : %ls", entry->title); + else + printf("%ls", entry->title); if (reverse) puts(ANSI_COLOR_RESET); @@ -87,6 +113,10 @@ static void bootmenu_autoboot_loop(struct bootmenu_data *menu, int i, c; if (menu->delay > 0) { + /* flush input */ + while (tstc()) + getchar(); + printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); printf(" Hit any key to stop autoboot: %2d ", menu->delay); } @@ -275,31 +305,20 @@ static void bootmenu_destroy(struct bootmenu_data *menu) free(menu); } -static struct bootmenu_data *bootmenu_create(int delay) +static int prepare_bootmenu_entry(struct bootmenu_data *menu, + struct bootmenu_entry **current, + unsigned short int *index) { - unsigned short int i = 0; - const char *option; - struct bootmenu_data *menu; - struct bootmenu_entry *iter = NULL; - int len; char *sep; - char *default_str; - struct bootmenu_entry *entry; - - menu = malloc(sizeof(struct bootmenu_data)); - if (!menu) - return NULL; - - menu->delay = delay; - menu->active = 0; - menu->first = NULL; - - default_str = env_get("bootmenu_default"); - if (default_str) - menu->active = (int)simple_strtol(default_str, NULL, 10); + const char *option; + unsigned short int i = *index; + struct bootmenu_entry *entry = NULL; + struct bootmenu_entry *iter = *current; while ((option = bootmenu_getoption(i))) { + u16 *buf; + sep = strchr(option, '='); if (!sep) { printf("Invalid bootmenu entry: %s\n", option); @@ -308,23 +327,23 @@ static struct bootmenu_data *bootmenu_create(int delay) entry = malloc(sizeof(struct bootmenu_entry)); if (!entry) - goto cleanup; + return -ENOMEM; len = sep-option; - entry->title = malloc(len + 1); + buf = calloc(1, (len + 1) * sizeof(u16)); + entry->title = buf; if (!entry->title) { free(entry); - goto cleanup; + return -ENOMEM; } - memcpy(entry->title, option, len); - entry->title[len] = 0; + utf8_utf16_strncpy(&buf, option, len); len = strlen(sep + 1); entry->command = malloc(len + 1); if (!entry->command) { free(entry->title); free(entry); - goto cleanup; + return -ENOMEM; } memcpy(entry->command, sep + 1, len); entry->command[len] = 0; @@ -333,6 +352,158 @@ static struct bootmenu_data *bootmenu_create(int delay) entry->num = i; entry->menu = menu; + entry->type = BOOTMENU_TYPE_BOOTMENU; + entry->bootorder = i; + entry->next = NULL; + + if (!iter) + menu->first = entry; + else + iter->next = entry; + + iter = entry; + i++; + + if (i == MAX_COUNT - 1) + break; + } + + *index = i; + *current = iter; + + return 1; +} + +static int prepare_uefi_bootorder_entry(struct bootmenu_data *menu, + struct bootmenu_entry **current, + unsigned short int *index) +{ + u16 *bootorder; + efi_status_t ret; + unsigned short j; + efi_uintn_t num, size; + void *load_option; + struct efi_load_option lo; + u16 varname[] = u"Boot####"; + unsigned short int i = *index; + struct bootmenu_entry *entry = NULL; + struct bootmenu_entry *iter = *current; + + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + if (!bootorder) + return -ENOENT; + + num = size / sizeof(u16); + for (j = 0; j < num; j++) { + entry = malloc(sizeof(struct bootmenu_entry)); + if (!entry) + return -ENOMEM; + + efi_create_indexed_name(varname, sizeof(varname), + "Boot", bootorder[j]); + 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); + free(entry); + continue; + } + + if (lo.attributes & LOAD_OPTION_ACTIVE) { + entry->title = u16_strdup(lo.label); + if (!entry->title) { + free(load_option); + free(entry); + return -ENOMEM; + } + entry->command = strdup("bootefi bootmgr"); + sprintf(entry->key, "%d", i); + entry->num = i; + entry->menu = menu; + entry->type = BOOTMENU_TYPE_UEFI_BOOT_OPTION; + entry->bootorder = bootorder[j]; + entry->next = NULL; + + if (!iter) + menu->first = entry; + else + iter->next = entry; + + iter = entry; + i++; + } + + free(load_option); + + if (i == MAX_COUNT - 1) + break; + } + + free(bootorder); + *index = i; + *current = iter; + + return 1; +} + +static int prepare_distro_boot_entry(struct bootmenu_data *menu, + struct bootmenu_entry **current, + unsigned short int *index) +{ + char *p; + int len; + char *token; + char *boot_targets; + unsigned short int i = *index; + struct bootmenu_entry *entry = NULL; + struct bootmenu_entry *iter = *current; + + /* list the distro boot "boot_targets" */ + boot_targets = env_get("boot_targets"); + if (!boot_targets) + return -ENOENT; + + len = strlen(boot_targets); + p = calloc(1, len + 1); + strlcpy(p, boot_targets, len); + + token = strtok(p, " "); + + do { + u16 *buf; + char *command; + int command_size; + + entry = malloc(sizeof(struct bootmenu_entry)); + if (!entry) + return -ENOMEM; + + len = strlen(token); + buf = calloc(1, (len + 1) * sizeof(u16)); + entry->title = buf; + if (!entry->title) { + free(entry); + return -ENOMEM; + } + utf8_utf16_strncpy(&buf, token, len); + sprintf(entry->key, "%d", i); + entry->num = i; + entry->menu = menu; + + command_size = sizeof("run bootcmd_") + len; + command = calloc(1, command_size); + if (!command) { + free(entry->title); + free(entry); + return -ENOMEM; + } + snprintf(command, command_size, "run bootcmd_%s", token); + entry->command = command; + entry->type = BOOTMENU_TYPE_DISTRO_BOOT; entry->next = NULL; if (!iter) @@ -341,10 +512,59 @@ static struct bootmenu_data *bootmenu_create(int delay) iter->next = entry; iter = entry; - ++i; + i++; if (i == MAX_COUNT - 1) break; + + token = strtok(NULL, " "); + } while (token); + + free(p); + *index = i; + *current = iter; + + return 1; +} + +static struct bootmenu_data *bootmenu_create(int delay) +{ + int ret; + unsigned short int i = 0; + struct bootmenu_data *menu; + struct bootmenu_entry *iter = NULL; + struct bootmenu_entry *entry; + + char *default_str; + + menu = malloc(sizeof(struct bootmenu_data)); + if (!menu) + return NULL; + + menu->delay = delay; + menu->active = 0; + menu->first = NULL; + + default_str = env_get("bootmenu_default"); + if (default_str) + menu->active = (int)simple_strtol(default_str, NULL, 10); + + ret = prepare_bootmenu_entry(menu, &iter, &i); + if (ret < 0) + goto cleanup; + + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { + if (i < MAX_COUNT - 1) { + ret = prepare_uefi_bootorder_entry(menu, &iter, &i); + if (ret < 0 && ret != -ENOENT) + goto cleanup; + } + } + + if (i < MAX_COUNT - 1) { + ret = prepare_distro_boot_entry(menu, &iter, &i); + if (ret < 0 && ret != -ENOENT) + goto cleanup; } /* Add U-Boot console entry at the end */ @@ -353,7 +573,12 @@ static struct bootmenu_data *bootmenu_create(int delay) if (!entry) goto cleanup; - entry->title = strdup("U-Boot console"); + /* Add dummy entry if entering U-Boot console is disabled */ + if (IS_ENABLED(CONFIG_CMD_BOOTMENU_ENTER_UBOOT_CONSOLE)) + entry->title = u16_strdup(u"U-Boot console"); + else + entry->title = u16_strdup(u""); + if (!entry->title) { free(entry); goto cleanup; @@ -370,6 +595,7 @@ static struct bootmenu_data *bootmenu_create(int delay) entry->num = i; entry->menu = menu; + entry->type = BOOTMENU_TYPE_NONE; entry->next = NULL; if (!iter) @@ -378,7 +604,7 @@ static struct bootmenu_data *bootmenu_create(int delay) iter->next = entry; iter = entry; - ++i; + i++; } menu->count = i; @@ -423,43 +649,73 @@ static void menu_display_statusline(struct menu *m) puts(ANSI_CLEAR_LINE); } -static void bootmenu_show(int delay) +static void handle_uefi_bootnext(void) { + u16 bootnext; + efi_status_t ret; + efi_uintn_t size; + + /* Initialize EFI drivers */ + 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; + } + + /* If UEFI BootNext variable is set, boot the BootNext load option */ + size = sizeof(u16); + ret = efi_get_variable_int(u"BootNext", + &efi_global_variable_guid, + NULL, &size, &bootnext, NULL); + if (ret == EFI_SUCCESS) + /* BootNext does exist here, try to boot */ + run_command("bootefi bootmgr", 0); +} + +static enum bootmenu_ret bootmenu_show(int delay) +{ + int cmd_ret; int init = 0; void *choice = NULL; - char *title = NULL; + u16 *title = NULL; char *command = NULL; struct menu *menu; struct bootmenu_data *bootmenu; struct bootmenu_entry *iter; + efi_status_t efi_ret = EFI_SUCCESS; char *option, *sep; + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) + handle_uefi_bootnext(); + /* If delay is 0 do not create menu, just run first entry */ if (delay == 0) { option = bootmenu_getoption(0); if (!option) { puts("bootmenu option 0 was not found\n"); - return; + return BOOTMENU_RET_FAIL; } sep = strchr(option, '='); if (!sep) { puts("bootmenu option 0 is invalid\n"); - return; + return BOOTMENU_RET_FAIL; } - run_command(sep+1, 0); - return; + cmd_ret = run_command(sep + 1, 0); + return (cmd_ret == CMD_RET_SUCCESS ? BOOTMENU_RET_SUCCESS : BOOTMENU_RET_FAIL); } bootmenu = bootmenu_create(delay); if (!bootmenu) - return; + return BOOTMENU_RET_FAIL; menu = menu_create(NULL, bootmenu->delay, 1, menu_display_statusline, bootmenu_print_entry, bootmenu_choice_entry, bootmenu); if (!menu) { bootmenu_destroy(bootmenu); - return; + return BOOTMENU_RET_FAIL; } for (iter = bootmenu->first; iter; iter = iter->next) { @@ -478,8 +734,33 @@ static void bootmenu_show(int delay) if (menu_get_choice(menu, &choice) == 1) { iter = choice; - title = strdup(iter->title); + /* last entry is U-Boot console or Quit */ + if (iter->num == iter->menu->count - 1) { + menu_destroy(menu); + bootmenu_destroy(bootmenu); + return BOOTMENU_RET_QUIT; + } + + title = u16_strdup(iter->title); command = strdup(iter->command); + } else { + goto cleanup; + } + + /* + * If the selected entry is UEFI BOOT####, set the BootNext variable. + * Then uefi bootmgr is invoked by the preset command in iter->command. + */ + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { + if (iter->type == BOOTMENU_TYPE_UEFI_BOOT_OPTION) { + efi_ret = efi_set_variable_int(u"BootNext", &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(u16), &iter->bootorder, false); + if (efi_ret != EFI_SUCCESS) + goto cleanup; + } } cleanup: @@ -493,21 +774,47 @@ cleanup: } if (title && command) { - debug("Starting entry '%s'\n", title); + debug("Starting entry '%ls'\n", title); free(title); - run_command(command, 0); + if (efi_ret == EFI_SUCCESS) + cmd_ret = run_command(command, 0); free(command); } #ifdef CONFIG_POSTBOOTMENU run_command(CONFIG_POSTBOOTMENU, 0); #endif + + if (efi_ret == EFI_SUCCESS && cmd_ret == CMD_RET_SUCCESS) + return BOOTMENU_RET_SUCCESS; + + return BOOTMENU_RET_FAIL; } #ifdef CONFIG_AUTOBOOT_MENU_SHOW int menu_show(int bootdelay) { - bootmenu_show(bootdelay); + int ret; + + while (1) { + ret = bootmenu_show(bootdelay); + bootdelay = -1; + if (ret == BOOTMENU_RET_UPDATED) + continue; + + if (!IS_ENABLED(CONFIG_CMD_BOOTMENU_ENTER_UBOOT_CONSOLE)) { + if (ret == BOOTMENU_RET_QUIT) { + /* default boot process */ + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) + run_command("bootefi bootmgr", 0); + + run_command("run bootcmd", 0); + } + } else { + break; + } + } + return -1; /* -1 - abort boot and run monitor code */ } #endif From patchwork Thu Mar 24 13:54: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: 553920 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:1248:0:0:0:0 with SMTP id z8csp4439275mag; Thu, 24 Mar 2022 06:56:43 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxFyAu31etTWEreZ/jy7nh9C96c5qUNBIzriiaZpJqVYDQGvjQgX9kMOvXMu3s5Nyq5asNk X-Received: by 2002:a17:906:dc8f:b0:6e0:5ce7:d80e with SMTP id cs15-20020a170906dc8f00b006e05ce7d80emr5889113ejc.435.1648130203553; Thu, 24 Mar 2022 06:56:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648130203; cv=none; d=google.com; s=arc-20160816; b=C2UpV9cOjbsapo/Qr8Y9htD7cplCcrLGp7lee98MOQ0Zeho0xLcU2GFC2q87lLlZke K0PbngGcvyfY2OngY6NBbQ4oX7CJRM3qgzZzgOoIcjkLOMdTrZQ0fre7ehYWY9pzUgib p9yLB8mZ4joDRVatsxhWMWtZmy5p08Aqpae2wU7EGl4vYFGMtpWSr4QhZzN1/AinqLse KouG6jX+g4ErrvnDUPQHHbTKDgBkxVEHpw3Exr7b6rvkBRU8LEgkvr82R4OpNjEJHzG3 KEr3DHjfo1W2cOmNBOnECvxiklBq1aMywv9jNe/wo4osbmiBbMIInKjMlsmr6n2p4PGN 2i5Q== 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=kOs5aDDpW09AmD54XHrzAwT37TzHG82kUe4j+wzLMC8=; b=VqmQ5Hb8pZ2jy6tDuCDSMxIKYD1fSxbNaUrgWbp7MqnWXrRZIr1z7uFl/ZCJfMl3cT p2io6m0MUNQUe28J/GAEF5OKq+fKsYWuSfnJYVJdPb6E+yRi4LuV55LdYOY8Vl4hk9q6 2DgrVuAWKXavVsxP+Wu17+4uO0adLRCOg004W+CmU0Ykculdxobh/upkP+QZ8j1FqLOe k2DvwpJomQziFd++a8+EzER65k/mULd4T8q+q82vTF1akp6kPcqIO6xY7MPdJBVUywUs Vf2lrmA8BYkLR511piHxVu1JKA5WLWJ0A2yt9HylY9T63j0ejTmbaEur0VDZ7ex0fC+K 8YBw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=G3twfnKm; 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 ss12-20020a170907038c00b006df76385e5dsi14540109ejb.765.2022.03.24.06.56.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:56:43 -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=G3twfnKm; 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 BF9A6840E3; Thu, 24 Mar 2022 14:55:31 +0100 (CET) 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="G3twfnKm"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 5B242840C2; Thu, 24 Mar 2022 14:55:15 +0100 (CET) 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-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) (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 837A5840BF for ; Thu, 24 Mar 2022 14:55:03 +0100 (CET) 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-x631.google.com with SMTP id w8so4752211pll.10 for ; Thu, 24 Mar 2022 06:55:03 -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=kOs5aDDpW09AmD54XHrzAwT37TzHG82kUe4j+wzLMC8=; b=G3twfnKmusD3HvHsat9mH2Pw1CyK4SYNJ932ELL1avjP2tnW+KqIV/0kEsioFDkryL s6NvKeUU0Fr3oDAydufS1U+gQnrbGji8Xnm3/I0gd36LCSec1jik9YHxmra4wYUgzKj1 pX8r/Oab80qODdTOblKsaG0mHkxClT2tEQ7w3alT7PAeQlgTzgfH45HOfMt3J5Yo5U02 fvNsDHjb4g0df+tcks/4Atf6dXUkRG5HMmadJt/HS8ysPbjxydqrpSCeHH/8ljU7zZ44 engaBx6XklzuxgiaAc4+b4ljm+9TVeqC6CzDx0bAgQKOwn63n0KxDT/CfAGDCzfbZMEF NavA== 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=kOs5aDDpW09AmD54XHrzAwT37TzHG82kUe4j+wzLMC8=; b=lYCDdkKJrQvkv/g7SaBtPjaDBmiHSUhYRYpFO8tus/FXALhUTcUY0hkfhsh5e89gEF xppCCP++NjU/hSk3966G8Tmu3o/ODE4thVs/oSloVWl7btm/4+NxtMwldbPn0IheoONV 95/IKMGWUkP9z++K/LYPH0p0pmdRT3RG9wbPAnyQDQ9c717HIzkcqAlAEGHNu8c+q4Xj WAR3ZTJT8GEH0I9fzTV5ZGLpli1hcLrGJz4l7PTA5w4I0lMXIVBqpANBcpT5GI1Ey5Z3 K477cWsWrkUtCMldZEVNJXuNGqgBwv2Ni4532o2hjjU20OWNFAEI75uTOXleK8hSOaA1 l62g== X-Gm-Message-State: AOAM531A0GvT58QEPAjKsFl8dStB1EXbCI6FyQgFa0Hn1J8ufCRP9MPX j7yw+WNak7AEcyih8jFAjFv8dgGafuSvGQ== X-Received: by 2002:a17:90a:990c:b0:1bc:3c9f:2abe with SMTP id b12-20020a17090a990c00b001bc3c9f2abemr6441143pjp.220.1648130101646; Thu, 24 Mar 2022 06:55:01 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id p15-20020a056a000a0f00b004f7c63cba5asm3974609pfh.21.2022.03.24.06.54.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:55:01 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima Subject: [PATCH v4 08/11] bootmenu: factor out the user input handling Date: Thu, 24 Mar 2022 22:54:40 +0900 Message-Id: <20220324135443.1571-9-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220324135443.1571-1-masahisa.kojima@linaro.org> References: <20220324135443.1571-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.5 at phobos.denx.de X-Virus-Status: Clean This commit moves the user input handling from cmd/bootmenu.c to common/menu.c to reuse it from other modules. Signed-off-by: Masahisa Kojima --- Newly created in v4. cmd/bootmenu.c | 149 ------------------------------------------------- common/menu.c | 137 +++++++++++++++++++++++++++++++++++++++++++++ include/menu.h | 20 +++++++ 3 files changed, 157 insertions(+), 149 deletions(-) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 947b3a49ff..d3591aa4a9 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -52,21 +52,6 @@ struct bootmenu_entry { struct bootmenu_entry *next; /* next menu entry (num+1) */ }; -struct bootmenu_data { - int delay; /* delay for autoboot */ - int active; /* active menu entry */ - int count; /* total count of menu entries */ - struct bootmenu_entry *first; /* first menu entry */ -}; - -enum bootmenu_key { - KEY_NONE = 0, - KEY_UP, - KEY_DOWN, - KEY_SELECT, - KEY_QUIT, -}; - static char *bootmenu_getoption(unsigned short int n) { char name[MAX_ENV_SIZE]; @@ -107,140 +92,6 @@ static void bootmenu_print_entry(void *data) puts(ANSI_COLOR_RESET); } -static void bootmenu_autoboot_loop(struct bootmenu_data *menu, - enum bootmenu_key *key, int *esc) -{ - int i, c; - - if (menu->delay > 0) { - /* flush input */ - while (tstc()) - getchar(); - - printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); - printf(" Hit any key to stop autoboot: %2d ", menu->delay); - } - - while (menu->delay > 0) { - for (i = 0; i < 100; ++i) { - if (!tstc()) { - WATCHDOG_RESET(); - mdelay(10); - continue; - } - - menu->delay = -1; - c = getchar(); - - switch (c) { - case '\e': - *esc = 1; - *key = KEY_NONE; - break; - case '\r': - *key = KEY_SELECT; - break; - case 0x3: /* ^C */ - *key = KEY_QUIT; - break; - default: - *key = KEY_NONE; - break; - } - - break; - } - - if (menu->delay < 0) - break; - - --menu->delay; - printf("\b\b\b%2d ", menu->delay); - } - - printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); - puts(ANSI_CLEAR_LINE); - - if (menu->delay == 0) - *key = KEY_SELECT; -} - -static void bootmenu_loop(struct bootmenu_data *menu, - enum bootmenu_key *key, int *esc) -{ - int c; - - if (*esc == 1) { - if (tstc()) { - c = getchar(); - } else { - WATCHDOG_RESET(); - mdelay(10); - if (tstc()) - c = getchar(); - else - c = '\e'; - } - } else { - while (!tstc()) { - WATCHDOG_RESET(); - mdelay(10); - } - c = getchar(); - } - - switch (*esc) { - case 0: - /* First char of ANSI escape sequence '\e' */ - if (c == '\e') { - *esc = 1; - *key = KEY_NONE; - } - break; - case 1: - /* Second char of ANSI '[' */ - if (c == '[') { - *esc = 2; - *key = KEY_NONE; - } else { - /* Alone ESC key was pressed */ - *key = KEY_QUIT; - *esc = (c == '\e') ? 1 : 0; - } - break; - case 2: - case 3: - /* Third char of ANSI (number '1') - optional */ - if (*esc == 2 && c == '1') { - *esc = 3; - *key = KEY_NONE; - break; - } - - *esc = 0; - - /* ANSI 'A' - key up was pressed */ - if (c == 'A') - *key = KEY_UP; - /* ANSI 'B' - key down was pressed */ - else if (c == 'B') - *key = KEY_DOWN; - /* other key was pressed */ - else - *key = KEY_NONE; - - break; - } - - /* enter key was pressed */ - if (c == '\r') - *key = KEY_SELECT; - - /* ^C was pressed */ - if (c == 0x3) - *key = KEY_QUIT; -} - static char *bootmenu_choice_entry(void *data) { struct bootmenu_data *menu = data; diff --git a/common/menu.c b/common/menu.c index b577d80b4f..6dcac035b7 100644 --- a/common/menu.c +++ b/common/menu.c @@ -4,11 +4,14 @@ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. */ +#include #include #include #include #include +#include #include +#include #include "menu.h" @@ -418,3 +421,137 @@ int menu_destroy(struct menu *m) return 1; } + +void bootmenu_autoboot_loop(struct bootmenu_data *menu, + enum bootmenu_key *key, int *esc) +{ + int i, c; + + if (menu->delay > 0) { + /* flush input */ + while (tstc()) + getchar(); + + printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); + printf(" Hit any key to stop autoboot: %2d ", menu->delay); + } + + while (menu->delay > 0) { + for (i = 0; i < 100; ++i) { + if (!tstc()) { + WATCHDOG_RESET(); + mdelay(10); + continue; + } + + menu->delay = -1; + c = getchar(); + + switch (c) { + case '\e': + *esc = 1; + *key = KEY_NONE; + break; + case '\r': + *key = KEY_SELECT; + break; + case 0x3: /* ^C */ + *key = KEY_QUIT; + break; + default: + *key = KEY_NONE; + break; + } + + break; + } + + if (menu->delay < 0) + break; + + --menu->delay; + printf("\b\b\b%2d ", menu->delay); + } + + printf(ANSI_CURSOR_POSITION, menu->count + 5, 1); + puts(ANSI_CLEAR_LINE); + + if (menu->delay == 0) + *key = KEY_SELECT; +} + +void bootmenu_loop(struct bootmenu_data *menu, + enum bootmenu_key *key, int *esc) +{ + int c; + + if (*esc == 1) { + if (tstc()) { + c = getchar(); + } else { + WATCHDOG_RESET(); + mdelay(10); + if (tstc()) + c = getchar(); + else + c = '\e'; + } + } else { + while (!tstc()) { + WATCHDOG_RESET(); + mdelay(10); + } + c = getchar(); + } + + switch (*esc) { + case 0: + /* First char of ANSI escape sequence '\e' */ + if (c == '\e') { + *esc = 1; + *key = KEY_NONE; + } + break; + case 1: + /* Second char of ANSI '[' */ + if (c == '[') { + *esc = 2; + *key = KEY_NONE; + } else { + /* Alone ESC key was pressed */ + *key = KEY_QUIT; + *esc = (c == '\e') ? 1 : 0; + } + break; + case 2: + case 3: + /* Third char of ANSI (number '1') - optional */ + if (*esc == 2 && c == '1') { + *esc = 3; + *key = KEY_NONE; + break; + } + + *esc = 0; + + /* ANSI 'A' - key up was pressed */ + if (c == 'A') + *key = KEY_UP; + /* ANSI 'B' - key down was pressed */ + else if (c == 'B') + *key = KEY_DOWN; + /* other key was pressed */ + else + *key = KEY_NONE; + + break; + } + + /* enter key was pressed */ + if (c == '\r') + *key = KEY_SELECT; + + /* ^C was pressed */ + if (c == 0x3) + *key = KEY_QUIT; +} diff --git a/include/menu.h b/include/menu.h index ad5859437e..e74616cae8 100644 --- a/include/menu.h +++ b/include/menu.h @@ -35,4 +35,24 @@ int menu_default_choice(struct menu *m, void **choice); */ int menu_show(int bootdelay); +struct bootmenu_data { + int delay; /* delay for autoboot */ + int active; /* active menu entry */ + int count; /* total count of menu entries */ + struct bootmenu_entry *first; /* first menu entry */ +}; + +enum bootmenu_key { + KEY_NONE = 0, + KEY_UP, + KEY_DOWN, + KEY_SELECT, + KEY_QUIT, +}; + +void bootmenu_autoboot_loop(struct bootmenu_data *menu, + enum bootmenu_key *key, int *esc); +void bootmenu_loop(struct bootmenu_data *menu, + enum bootmenu_key *key, int *esc); + #endif /* __MENU_H__ */ From patchwork Thu Mar 24 13:54: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: 553922 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:1248:0:0:0:0 with SMTP id z8csp4439576mag; Thu, 24 Mar 2022 06:57:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzfxOCd4nmOne5GNFb08uULIEXX6Go48jFFkN5+3lA21pt1+n4UgXb7I26HEWEINrzhoA7N X-Received: by 2002:a05:6402:187:b0:415:c784:abe0 with SMTP id r7-20020a056402018700b00415c784abe0mr6978911edv.168.1648130227513; Thu, 24 Mar 2022 06:57:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648130227; cv=none; d=google.com; s=arc-20160816; b=kVZyryOLW+YqxQNoStQrGEp7pNNhQqlGY7H7tCkykaiRnfr0AZXQlo9F1QZNTR2aE1 E0zQA41RQUmSKF7XBeG4YtrvIgEbRnaPQzH0qeakWe7KnED6THCdVXrHEOO6u5DqFhSF OGWssIhajLH6r5zZAWCmylzEJx37Q/qXHmIzewGx0rN1lwlGugbs3D562sQ+1b9GL8yB KQonWOgRtBD9z3+DIu2MiaOcxeNMwAdBCzbona5gslGyEU0CsnT0xOh7gYPuTbp9WZtw jKEQ8T3Cj4ZlfUvPj+JsbECjJ2zIDK8HpWiWEIeVTniS8VpI5A3fmqAnTyCXIGYO2kfp QnCA== 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=oKsLTkkfap7/XGGXjHS2gEZjb7CPm8zkXBlJz3xF6RI=; b=Lg/YBzenj64Wkq1BmA9K8lFMJ5IeuKRbQOoB1/shWVpVsor3y/W0ITesvU59YD8WIu eXmpfn9bqXgkujSsMTOdljSap1IVFahvx7qF6K4zd/MGltQxDt6vvhV96zaK1w0RMMcS rhYFqbjtFvD8KUYsgdqjD2sZLhTfmZ3RkQ9mrXw4oK2fDv1zVn0h6bigZ92YjBx10sp+ otZB5wKAMLom6kECeXUaUTzveMemmbWltuNReJAXokVfq/t5dQAyQZoTcjDTM6PcJ9bh Pc4uCOm0M8CoSvthBrP3yFk6UHFrzB2J2k/477nKvAgh7uYWT8dsPFvblMNQlLhoDnEZ kEqw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=vVMAITxp; 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 y27-20020a170906519b00b006dfad257082si15861854ejk.489.2022.03.24.06.57.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:57:07 -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=vVMAITxp; 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 E40D4840E1; Thu, 24 Mar 2022 14:55:38 +0100 (CET) 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="vVMAITxp"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 6C8D8840AA; Thu, 24 Mar 2022 14:55:19 +0100 (CET) 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 69DAC840CD for ; Thu, 24 Mar 2022 14:55:07 +0100 (CET) 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 v4so4800474pjh.2 for ; Thu, 24 Mar 2022 06:55:07 -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=oKsLTkkfap7/XGGXjHS2gEZjb7CPm8zkXBlJz3xF6RI=; b=vVMAITxpaLH/swKl7yTv9BFkYjS0z17F0BKgsqCapzuQOM1+j+xrLWqCa56bACuy4A YDPkz+ocEKz8i7bJPWFjGr6IF2LxO/X6kQUotKowHlSTcwN0L//jd5AYRSHcljMNaqrd vPYqyJMXsndLvvqbWby9Ah31CsaTv7Rn8fsk90GKfxv92M2bnV7Ha999DCXwmdoQ/bJz aWKQZYcfUB5x2CvL5PZTZBql18RPF5T7eXxR52sDjR0TEXBkCIvlW7sovHUDehdAj0dt CHTW5qYoohCTaj/YZSUz8wx5CCge5xtdmzhI4uB7UJuTp01yzlH6o5bD0Tq9rc7y0P0Z dc2Q== 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=oKsLTkkfap7/XGGXjHS2gEZjb7CPm8zkXBlJz3xF6RI=; b=RJiPMS/GjIAZFZWXxaBCUDBh3RMpdAFiGc321jPw0q4GxfQLDX0cBrNnur210EmbMi KJaSB1iMSZReULXqKBaITMkdxb32Uz7oqy1W6c9LsXZ/KZmugz6N88gIaU61X6ieB0Az HBwnwPPdDqo/GU3PIfGIaIZMmuyEPrQqOVbQnI/UQ07w+am14JTHxs0baKBSriO4loVx yu7fwRunGFNGj3biulztwpHF7tSeYsjtOkSZXSaTC2EVpkevzVGO4k6Nah8TVlKVnjHQ Dp7AHYd5DTgfEljjWy8u1DmPwZS7sc/qk0szRmd/zmj1pPcgBKgUp3bPd8sD77cupFYa uDHQ== X-Gm-Message-State: AOAM532hzqLBnl/L6C1Tz/raDFtxCiKaVSKVRV6yCuMiYTM+C/iLJ2Go 1F4GBSdhRguXJGwycL+Z9QQOVdMqNb1K/w== X-Received: by 2002:a17:90b:1d04:b0:1c7:1174:56ae with SMTP id on4-20020a17090b1d0400b001c7117456aemr18348997pjb.153.1648130105083; Thu, 24 Mar 2022 06:55:05 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id p15-20020a056a000a0f00b004f7c63cba5asm3974609pfh.21.2022.03.24.06.55.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:55:04 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima Subject: [PATCH v4 09/11] efi_loader: add menu-driven UEFI Boot Variable maintenance Date: Thu, 24 Mar 2022 22:54:41 +0900 Message-Id: <20220324135443.1571-10-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220324135443.1571-1-masahisa.kojima@linaro.org> References: <20220324135443.1571-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.5 at phobos.denx.de X-Virus-Status: Clean This commit adds the menu-driven UEFI Boot Variable maintenance. User can add and delete the Boot#### variable, and update the BootOrder variable through menu operation. Signed-off-by: Masahisa Kojima --- 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 v3: not included in v3 series Changes in 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/bootmenu.c | 70 +- include/efi_loader.h | 37 + lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_bootmenu_maintenance.c | 1116 +++++++++++++++++++++ lib/efi_loader/efi_boottime.c | 52 +- lib/efi_loader/efi_console.c | 81 ++ lib/efi_loader/efi_disk.c | 11 + lib/efi_loader/efi_file.c | 75 +- 8 files changed, 1388 insertions(+), 55 deletions(-) create mode 100644 lib/efi_loader/efi_bootmenu_maintenance.c diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index d3591aa4a9..458eb90b63 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -19,6 +19,8 @@ /* maximum bootmenu entries */ #define MAX_COUNT 99 +#define STATIC_ENTRY 2 +#define MAX_DYNAMIC_ENTRY (MAX_COUNT - STATIC_ENTRY) /* maximal size of bootmenu env * 9 = strlen("bootmenu_") @@ -39,10 +41,11 @@ enum boot_type { BOOTMENU_TYPE_BOOTMENU, BOOTMENU_TYPE_UEFI_BOOT_OPTION, BOOTMENU_TYPE_DISTRO_BOOT, + BOOTMENU_TYPE_UEFI_MAINTENANCE, }; struct bootmenu_entry { - unsigned short int num; /* unique number 0 .. MAX_COUNT */ + unsigned short int num; /* unique number 0 .. MAX_DYNAMIC_ENTRY */ char key[3]; /* key identifier of number */ u16 *title; /* title of entry */ char *command; /* hush command of entry */ @@ -56,7 +59,7 @@ static char *bootmenu_getoption(unsigned short int n) { char name[MAX_ENV_SIZE]; - if (n > MAX_COUNT) + if (n > MAX_DYNAMIC_ENTRY) return NULL; sprintf(name, "bootmenu_%d", n); @@ -215,7 +218,7 @@ static int prepare_bootmenu_entry(struct bootmenu_data *menu, iter = entry; i++; - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; } @@ -290,7 +293,7 @@ static int prepare_uefi_bootorder_entry(struct bootmenu_data *menu, free(load_option); - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; } @@ -365,7 +368,7 @@ static int prepare_distro_boot_entry(struct bootmenu_data *menu, iter = entry; i++; - if (i == MAX_COUNT - 1) + if (i == MAX_DYNAMIC_ENTRY) break; token = strtok(NULL, " "); @@ -405,19 +408,56 @@ static struct bootmenu_data *bootmenu_create(int delay) goto cleanup; if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { - if (i < MAX_COUNT - 1) { + if (i < MAX_DYNAMIC_ENTRY) { ret = prepare_uefi_bootorder_entry(menu, &iter, &i); if (ret < 0 && ret != -ENOENT) goto cleanup; } } - if (i < MAX_COUNT - 1) { + if (i < MAX_DYNAMIC_ENTRY) { ret = prepare_distro_boot_entry(menu, &iter, &i); if (ret < 0 && ret != -ENOENT) goto cleanup; } + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { + /* Add UEFI Boot Manager Maintenance entry */ + if (i <= MAX_DYNAMIC_ENTRY) { + entry = malloc(sizeof(struct bootmenu_entry)); + if (!entry) + goto cleanup; + + entry->title = u16_strdup(u"UEFI Boot Manager Maintenance"); + if (!entry->title) { + free(entry); + goto cleanup; + } + + entry->command = strdup(""); + if (!entry->command) { + free(entry->title); + free(entry); + goto cleanup; + } + + sprintf(entry->key, "%d", i); + + entry->num = i; + entry->menu = menu; + entry->type = BOOTMENU_TYPE_UEFI_MAINTENANCE; + entry->next = NULL; + + if (!iter) + menu->first = entry; + else + iter->next = entry; + + iter = entry; + i++; + } + } + /* Add U-Boot console entry at the end */ if (i <= MAX_COUNT - 1) { entry = malloc(sizeof(struct bootmenu_entry)); @@ -585,6 +625,13 @@ static enum bootmenu_ret bootmenu_show(int delay) if (menu_get_choice(menu, &choice) == 1) { iter = choice; + if (iter->type == BOOTMENU_TYPE_UEFI_MAINTENANCE) { + efi_bootmenu_show_maintenance_menu(); + menu_destroy(menu); + bootmenu_destroy(bootmenu); + return BOOTMENU_RET_UPDATED; + } + /* last entry is U-Boot console or Quit */ if (iter->num == iter->menu->count - 1) { menu_destroy(menu); @@ -674,6 +721,7 @@ int do_bootmenu(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { char *delay_str = NULL; int delay = 10; + int ret; #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) delay = CONFIG_BOOTDELAY; @@ -688,7 +736,13 @@ int do_bootmenu(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (delay_str) delay = (int)simple_strtol(delay_str, NULL, 10); - bootmenu_show(delay); + while (1) { + ret = bootmenu_show(delay); + delay = -1; + if (ret != BOOTMENU_RET_UPDATED) + break; + } + return 0; } diff --git a/include/efi_loader.h b/include/efi_loader.h index ce22660d5b..7b100ca030 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -226,6 +226,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 + /* Key identifying current memory map */ extern efi_uintn_t efi_memory_map_key; @@ -312,6 +315,9 @@ 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 const efi_guid_t efi_guid_text_output_protocol; extern char __efi_runtime_start[], __efi_runtime_stop[]; extern char __efi_runtime_rel_start[], __efi_runtime_rel_stop[]; @@ -869,6 +875,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 * @@ -1004,4 +1012,33 @@ 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, + struct efi_simple_text_output_protocol *cout, + u16 *buf, efi_uintn_t count, efi_console_filter_func filer_func, + int row, int col); + +efi_status_t efi_bootmenu_get_unused_bootoption(u16 *buf, + efi_uintn_t buf_size, u32 *index); +efi_status_t efi_bootmenu_append_bootorder(u16 index); + +efi_status_t efi_disk_get_device_name(struct efi_block_io *this, char *buf, int size); + #endif /* _EFI_LOADER_H */ diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index befed7144e..fd900a23c7 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -77,6 +77,7 @@ obj-$(CONFIG_EFI_TCG2_PROTOCOL) += efi_tcg2.o obj-$(CONFIG_EFI_RISCV_BOOT_PROTOCOL) += efi_riscv.o obj-$(CONFIG_EFI_LOAD_FILE2_INITRD) += efi_load_initrd.o obj-$(CONFIG_EFI_SIGNATURE_SUPPORT) += efi_signature.o +obj-$(CONFIG_CMD_BOOTMENU) += efi_bootmenu_maintenance.o EFI_VAR_SEED_FILE := $(subst $\",,$(CONFIG_EFI_VAR_SEED_FILE)) $(obj)/efi_var_seed.o: $(srctree)/$(EFI_VAR_SEED_FILE) diff --git a/lib/efi_loader/efi_bootmenu_maintenance.c b/lib/efi_loader/efi_bootmenu_maintenance.c new file mode 100644 index 0000000000..2ce5a47b10 --- /dev/null +++ b/lib/efi_loader/efi_bootmenu_maintenance.c @@ -0,0 +1,1116 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Menu-driven UEFI Boot Variable maintenance + * + * Copyright (c) 2022 Masahisa Kojima, Linaro Limited + */ + +#define LOG_CATEGORY LOGC_EFI + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct efi_simple_text_input_protocol *cin; +static struct efi_simple_text_output_protocol *cout; + +#define EFI_BOOTMENU_ENTRY_NUM_MAX 99 +#define EFI_BOOTMENU_FILE_PATH_MAX 512 +#define EFI_BOOTMENU_BOOT_NAME_MAX 32 +#define EFI_BOOT_ORDER_MAX_SIZE_IN_DECIMAL 6 + +typedef efi_status_t (*efi_bootmenu_entry_func)(void *data, bool *exit); + +/** + * struct efi_bootmenu_entry - menu entry structure + * + * @num: menu entry index + * @title: title of entry + * @key: unique key + * @bootmgr_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 efi_bootmenu_entry { + u32 num; + u16 *title; + char key[6]; + struct efi_bootmenu *bootmgr_menu; + struct efi_bootmenu_entry *next; + efi_bootmenu_entry_func func; + void *data; +}; + +/** + * struct efi_bootmenu - bootmgr menu structure + * + * @delay: delay for autoboot + * @active: active menu entry index + * @count: total count of menu entry + * @first: pointer to the first menu entry + */ +struct efi_bootmenu { + int delay; + int active; + int count; + struct efi_bootmenu_entry *first; +}; + +struct efi_bootmenu_item { + u16 *title; + efi_bootmenu_entry_func func; + void *data; +}; + +struct efi_bootmenu_boot_selection_data { + u16 bootorder_index; + void *load_option; + int *selected; +}; + +struct efi_bootmenu_boot_option { + struct efi_simple_file_system_protocol *current_volume; + struct efi_device_path *dp_volume; + u16 *current_path; + u16 *boot_name; + bool file_selected; +}; + +static const struct efi_device_path END = { + .type = DEVICE_PATH_TYPE_END, + .sub_type = DEVICE_PATH_SUB_TYPE_END, + .length = sizeof(END), +}; + +struct efi_bootmenu_volume_entry_data { + struct efi_bootmenu_boot_option *bo; + struct efi_simple_file_system_protocol *v; + struct efi_device_path *dp; +}; + +struct efi_bootmenu_file_entry_data { + struct efi_bootmenu_boot_option *bo; + struct efi_file_info *f; +}; + +static efi_status_t efi_bootmenu_process_boot_selected(void *data, bool *exit); +static efi_status_t efi_bootmenu_process_add_boot_option(void *data, bool *exit); +static efi_status_t efi_bootmenu_process_delete_boot_option(void *data, bool *exit); +static efi_status_t efi_bootmenu_process_change_boot_order(void *data, bool *exit); + +static struct efi_bootmenu_item maintenance_menu_items[] = { + {u"Add Boot Option", efi_bootmenu_process_add_boot_option}, + {u"Delete Boot Option", efi_bootmenu_process_delete_boot_option}, + {u"Change Boot Order", efi_bootmenu_process_change_boot_order}, + {u"Quit", NULL}, +}; + +static void efi_bootmenu_print_entry(void *data) +{ + struct efi_bootmenu_entry *entry = data; + int reverse = (entry->bootmgr_menu->active == entry->num); + + /* TODO: support scroll or page for many entries */ + + /* + * Move cursor to line where the entry will be drown (entry->count) + * First 3 lines contain bootmgr menu header + one empty line + * For the last "Quit" entry, add one empty line + */ + if (entry->num == (entry->bootmgr_menu->count - 1)) + printf(ANSI_CURSOR_POSITION, entry->num + 5, 1); + else + printf(ANSI_CURSOR_POSITION, entry->num + 4, 1); + + puts(" "); + + if (reverse) + puts(ANSI_COLOR_REVERSE); + + printf("%ls", entry->title); + + if (reverse) + puts(ANSI_COLOR_RESET); +} + +static void efi_bootmenu_display_statusline(struct menu *m) +{ + struct efi_bootmenu_entry *entry; + struct efi_bootmenu *bootmgr_menu; + + if (menu_default_choice(m, (void *)&entry) < 0) + return; + + bootmgr_menu = entry->bootmgr_menu; + + printf(ANSI_CURSOR_POSITION, 1, 1); + puts(ANSI_CLEAR_LINE); + printf(ANSI_CURSOR_POSITION, 2, 1); + puts(" *** U-Boot EFI Boot Manager ***"); + puts(ANSI_CLEAR_LINE_TO_END); + printf(ANSI_CURSOR_POSITION, 3, 1); + puts(ANSI_CLEAR_LINE); + + /* First 3 lines are bootmgr_menu header + 2 empty lines between entries */ + printf(ANSI_CURSOR_POSITION, bootmgr_menu->count + 5, 1); + puts(ANSI_CLEAR_LINE); + printf(ANSI_CURSOR_POSITION, bootmgr_menu->count + 6, 1); + puts(" Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit"); + puts(ANSI_CLEAR_LINE_TO_END); + printf(ANSI_CURSOR_POSITION, bootmgr_menu->count + 7, 1); + puts(ANSI_CLEAR_LINE); +} + +static char *efi_bootmenu_choice_entry(void *data) +{ + int i; + int esc = 0; + struct efi_bootmenu_entry *iter; + enum bootmenu_key key = KEY_NONE; + struct efi_bootmenu *bootmgr_menu = data; + + while (1) { + if (bootmgr_menu->delay >= 0) { + /* Autoboot was not stopped */ + bootmenu_autoboot_loop((struct bootmenu_data *)bootmgr_menu, &key, &esc); + } else { + /* Some key was pressed, so autoboot was stopped */ + bootmenu_loop((struct bootmenu_data *)bootmgr_menu, &key, &esc); + } + + if (bootmgr_menu->delay == 0) + key = KEY_QUIT; + + switch (key) { + case KEY_UP: + if (bootmgr_menu->active > 0) + --bootmgr_menu->active; + /* no menu key selected, regenerate menu */ + return NULL; + case KEY_DOWN: + if (bootmgr_menu->active < bootmgr_menu->count - 1) + ++bootmgr_menu->active; + /* no menu key selected, regenerate menu */ + return NULL; + case KEY_SELECT: + iter = bootmgr_menu->first; + for (i = 0; i < bootmgr_menu->active; ++i) + iter = iter->next; + return iter->key; + case KEY_QUIT: + /* Quit by choosing the last entry */ + iter = bootmgr_menu->first; + while (iter->next) + iter = iter->next; + return iter->key; + default: + break; + } + } + + /* never happens */ + debug("bootmgr menu: this should not happen"); + return NULL; +} + +static void efi_bootmenu_destroy(struct efi_bootmenu *bootmgr_menu) +{ + struct efi_bootmenu_entry *next; + struct efi_bootmenu_entry *iter = bootmgr_menu->first; + + while (iter) { + next = iter->next; + free(iter); + iter = next; + } + free(bootmgr_menu); +} + +/** + * efi_bootmenu_process_common() - main handler for uefi bootmgr menu + * + * Construct the structures required to show the menu, then handle + * the user input intracting with u-boot menu functions. + * + * @items: pointer to the structure of each menu entry + * @count: the number of menu entry + * @delay: delay for autoboot/autoselect + * Return: status code + */ +static efi_status_t efi_bootmenu_process_common(struct efi_bootmenu_item *items, + int count, int delay) +{ + u32 i; + bool exit = false; + efi_status_t ret; + struct menu *menu; + void *choice = NULL; + struct efi_bootmenu_entry *entry; + struct efi_bootmenu *bootmgr_menu; + struct efi_bootmenu_entry *iter = NULL; + + if (count > EFI_BOOTMENU_ENTRY_NUM_MAX) + return EFI_OUT_OF_RESOURCES; + + bootmgr_menu = calloc(1, sizeof(struct efi_bootmenu)); + if (!bootmgr_menu) + return EFI_OUT_OF_RESOURCES; + + bootmgr_menu->delay = delay; + bootmgr_menu->active = 0; + bootmgr_menu->first = NULL; + + for (i = 0; i < count; i++) { + entry = calloc(1, sizeof(struct efi_bootmenu_entry)); + if (!entry) { + ret = EFI_LOAD_ERROR; + goto out; + } + + entry->num = i; + entry->title = items->title; + snprintf(entry->key, sizeof(entry->key), "%04X", i); + entry->bootmgr_menu = bootmgr_menu; + entry->func = items->func; + entry->data = items->data; + entry->next = NULL; + + if (!iter) + bootmgr_menu->first = entry; + else + iter->next = entry; + + iter = entry; + items++; + } + bootmgr_menu->count = count; + + menu = menu_create(NULL, 0, 1, efi_bootmenu_display_statusline, + efi_bootmenu_print_entry, efi_bootmenu_choice_entry, + bootmgr_menu); + if (!menu) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + + for (entry = bootmgr_menu->first; entry; entry = entry->next) { + if (!menu_item_add(menu, entry->key, entry)) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + } + + menu_default_set(menu, bootmgr_menu->first->key); + + while (!exit) { + puts(ANSI_CURSOR_HIDE); + puts(ANSI_CLEAR_CONSOLE); + printf(ANSI_CURSOR_POSITION, 1, 1); + + if (menu_get_choice(menu, &choice)) { + entry = choice; + if (entry->func) + ret = entry->func(entry->data, &exit); + + /* last entry "Quit" is selected, exit this menu */ + if (entry->num == (entry->bootmgr_menu->count - 1)) { + ret = EFI_ABORTED; + break; + } + } + } + +out: + menu_destroy(menu); + efi_bootmenu_destroy(bootmgr_menu); + + puts(ANSI_CLEAR_CONSOLE); + printf(ANSI_CURSOR_POSITION, 1, 1); + puts(ANSI_CURSOR_SHOW); + + return ret; +} + +static efi_status_t efi_bootmenu_show_boot_selection(u16 *bootorder, efi_uintn_t count, + int *selected) +{ + u32 i; + efi_status_t ret; + efi_uintn_t size; + void *load_option; + struct efi_load_option lo; + u16 varname[] = u"Boot####"; + struct efi_bootmenu_item *menu_item, *iter; + + menu_item = calloc(count + 1, sizeof(struct efi_bootmenu_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 (lo.attributes & LOAD_OPTION_ACTIVE) { + struct efi_bootmenu_boot_selection_data *info; + + info = calloc(1, sizeof(struct efi_bootmenu_boot_selection_data)); + if (!info) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + info->bootorder_index = i; + info->load_option = load_option; + info->selected = selected; + iter->title = lo.label; + iter->func = efi_bootmenu_process_boot_selected; + iter->data = info; + iter++; + } + } + + /* add "Quit" entry */ + iter->title = u"Quit"; + iter->func = NULL; + iter->data = NULL; + count += 1; + + ret = efi_bootmenu_process_common(menu_item, count, -1); + +out: + iter = menu_item; + for (i = 0; i < count - 1; i++, iter++) { + free(((struct efi_bootmenu_boot_selection_data *)iter->data)->load_option); + free(iter->data); + } + + free(menu_item); + + return ret; +} + +static efi_status_t efi_bootmenu_process_boot_selected(void *data, bool *exit) +{ + struct efi_bootmenu_boot_selection_data *info = data; + + *exit = true; + + if (info) + *info->selected = info->bootorder_index; + + return EFI_SUCCESS; +} + +static efi_status_t efi_bootmenu_volume_selected(void *data, bool *exit) +{ + struct efi_bootmenu_volume_entry_data *info = data; + + *exit = true; + + if (info) { + info->bo->current_volume = info->v; + info->bo->dp_volume = info->dp; + } + + return EFI_SUCCESS; +} + +static efi_status_t efi_bootmenu_file_selected(void *data, bool *exit) +{ + struct efi_bootmenu_file_entry_data *info = data; + + *exit = true; + + if (!info) + return EFI_INVALID_PARAMETER; + + if (u16_strncmp(info->f->file_name, u".", 1) == 0 && + u16_strlen(info->f->file_name) == 1) { + /* stay current path */ + } else if (u16_strncmp(info->f->file_name, u"..", 2) == 0 && + u16_strlen(info->f->file_name) == 2) { + u32 i; + int len = u16_strlen(info->bo->current_path); + + for (i = len - 2; i > 0; i--) { + if (info->bo->current_path[i] == u'\\') + break; + } + + if (i == 0) + info->bo->current_path[0] = u'\0'; + else + info->bo->current_path[i + 1] = u'\0'; + } else { + size_t new_len; + + new_len = u16_strlen(info->bo->current_path) + + u16_strlen(info->f->file_name) + 1; + if (new_len >= EFI_BOOTMENU_FILE_PATH_MAX) { + /* TODO: show error notification to user */ + log_err("file path is too long\n"); + return EFI_INVALID_PARAMETER; + } + u16_strlcat(info->bo->current_path, info->f->file_name, EFI_BOOTMENU_FILE_PATH_MAX); + if (info->f->attribute & EFI_FILE_DIRECTORY) { + if (new_len + 1 >= EFI_BOOTMENU_FILE_PATH_MAX) { + log_err("file path is too long\n"); + return EFI_INVALID_PARAMETER; + } + u16_strlcat(info->bo->current_path, u"\\", EFI_BOOTMENU_FILE_PATH_MAX); + } else { + info->bo->file_selected = true; + } + } + return EFI_SUCCESS; +} + +static efi_status_t efi_bootmenu_select_volume(struct efi_bootmenu_boot_option *bo) +{ + 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 efi_simple_file_system_protocol *v; + struct efi_bootmenu_item *menu_item, *iter; + + 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; + + menu_item = calloc(count + 1, sizeof(struct efi_bootmenu_item)); + if (!menu_item) { + ret = EFI_OUT_OF_RESOURCES; + goto out1; + } + + iter = menu_item; + for (i = 0; i < count; i++) { + u16 *dev_name, *p; + struct efi_block_io *block_io; + char buf[BOOTMENU_DEVICE_NAME_MAX]; + struct efi_bootmenu_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 efi_bootmenu_volume_entry_data)); + if (!info) { + ret = EFI_OUT_OF_RESOURCES; + goto out2; + } + + efi_disk_get_device_name(block_io, buf, BOOTMENU_DEVICE_NAME_MAX); + dev_name = calloc(1, (strlen(buf) + 1) * sizeof(u16)); + if (!dev_name) { + free(info); + ret = EFI_OUT_OF_RESOURCES; + goto out2; + } + p = dev_name; + utf8_utf16_strncpy(&p, buf, strlen(buf)); + + info->v = v; + info->dp = device_path; + info->bo = bo; + iter->title = dev_name; + iter->func = efi_bootmenu_volume_selected; + iter->data = info; + iter++; + } + + iter->title = u16_strdup(u"Quit"); + iter->func = NULL; + iter->data = NULL; + count += 1; + + ret = efi_bootmenu_process_common(menu_item, count, -1); + +out2: + iter = menu_item; + for (i = 0; i < count; i++) { + struct efi_bootmenu_volume_entry_data *p; + + p = (struct efi_bootmenu_volume_entry_data *)(iter->data); + free(iter->title); + free(p); + iter++; + } + + free(menu_item); + +out1: + efi_free_pool(volume_handles); + + return ret; +} + +static efi_status_t efi_bootmenu_select_file(struct efi_bootmenu_boot_option *bo, + struct efi_file_handle *root) +{ + char *buf; + u32 i; + char *dir_buf; + efi_uintn_t len; + efi_status_t ret; + efi_uintn_t size; + u32 count = 0; + struct efi_file_handle *f; + struct efi_file_info *ptr; + struct efi_bootmenu_item *menu_item, *iter; + + buf = calloc(1, EFI_BOOTMENU_FILE_PATH_MAX); + if (!buf) + return EFI_OUT_OF_RESOURCES; + + while (!bo->file_selected) { + size = 0; + count = 0; + + ret = efi_file_open_int(root, &f, bo->current_path, EFI_FILE_MODE_READ, 0); + if (ret != EFI_SUCCESS) + return ret; + + /* calculate directory information total size */ + for (;;) { + len = EFI_BOOTMENU_FILE_PATH_MAX; + ret = efi_file_read_int(f, &len, buf); + if (ret != EFI_SUCCESS || len == 0) + break; + + size += len; + count++; + } + + dir_buf = calloc(1, size); + if (!dir_buf) { + efi_file_close_int(f); + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + menu_item = calloc(count + 1, sizeof(struct efi_bootmenu_item)); + if (!menu_item) { + efi_file_close_int(f); + free(dir_buf); + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + /* read directory and construct menu structure */ + efi_file_setpos_int(f, 0); + iter = menu_item; + ptr = (struct efi_file_info *)dir_buf; + for (i = 0; i < count; i++) { + int name_len; + u16 *name; + struct efi_bootmenu_file_entry_data *info; + + len = size; + ret = efi_file_read_int(f, &len, ptr); + if (ret != EFI_SUCCESS || len == 0) + goto err; + + if (ptr->attribute & EFI_FILE_DIRECTORY) { + /* append u'/' at the end of directory name */ + name_len = u16_strsize(ptr->file_name) + sizeof(u16); + name = calloc(1, name_len); + if (!name) { + ret = EFI_OUT_OF_RESOURCES; + goto err; + } + u16_strcpy(name, ptr->file_name); + name[u16_strlen(ptr->file_name)] = u'/'; + } else { + name_len = u16_strsize(ptr->file_name); + name = calloc(1, name_len); + if (!name) { + ret = EFI_OUT_OF_RESOURCES; + goto err; + } + u16_strcpy(name, ptr->file_name); + } + + info = calloc(1, sizeof(struct efi_bootmenu_file_entry_data)); + if (!info) { + ret = EFI_OUT_OF_RESOURCES; + goto err; + } + info->f = ptr; + info->bo = bo; + iter->title = name; + iter->func = efi_bootmenu_file_selected; + iter->data = info; + iter++; + + size -= len; + ptr = (struct efi_file_info *)((char *)ptr + len); + } + + /* add "Quit" entry */ + iter->title = u"Quit"; + iter->func = NULL; + iter->data = NULL; + count += 1; + + ret = efi_bootmenu_process_common(menu_item, count, -1); +err: + efi_file_close_int(f); + iter = menu_item; + for (i = 0; i < count - 1; i++, iter++) { + free(iter->title); + free(iter->data); + } + + free(dir_buf); + free(menu_item); + + if (ret != EFI_SUCCESS) + break; + } + +out: + free(buf); + return ret; +} + +static efi_status_t efi_bootmenu_boot_add_enter_name(struct efi_bootmenu_boot_option *bo) +{ + efi_status_t ret; + + printf(ANSI_CURSOR_POSITION, 2, 1); + puts(" *** U-Boot EFI Boot Manager Menu ***"); + printf(ANSI_CURSOR_POSITION, 4, 1); + puts(" enter name:"); + + printf(ANSI_CURSOR_POSITION, 8, 1); + puts(" ENTER to complete, ESC/CTRL+C to quit"); + + ret = efi_console_get_u16_string(cin, cout, bo->boot_name, + EFI_BOOTMENU_BOOT_NAME_MAX, NULL, 4, 15); + + return ret; +} + +static efi_status_t allow_decimal(struct efi_input_key *key) +{ + if (u'0' <= key->unicode_char && key->unicode_char <= u'9') + return EFI_SUCCESS; + + return EFI_INVALID_PARAMETER; +} + +static efi_status_t efi_bootmenu_change_boot_order(int selected, int max, int *new) +{ + efi_status_t ret; + u16 new_order[EFI_BOOT_ORDER_MAX_SIZE_IN_DECIMAL] = {0}; + + printf(ANSI_CURSOR_POSITION, 2, 1); + puts(" *** U-Boot EFI Boot Manager Menu ***"); + printf(ANSI_CURSOR_POSITION, 4, 1); + printf(" current boot order : %d", selected); + + printf(ANSI_CURSOR_POSITION, 6, 1); + printf(" new boot order(0 - %4d): ", max); + + printf(ANSI_CURSOR_POSITION, 8, 1); + puts(" ENTER to complete, ESC/CTRL+C to quit"); + + printf(ANSI_CURSOR_POSITION, 6, 29); + puts(ANSI_CURSOR_SHOW); + + for (;;) { + memset(new_order, 0, sizeof(new_order)); + ret = efi_console_get_u16_string(cin, cout, new_order, 6, allow_decimal, 6, 29); + if (ret == EFI_SUCCESS) { + int i; + int val = 0; + + for (i = 0; + i < u16_strnlen(new_order, EFI_BOOT_ORDER_MAX_SIZE_IN_DECIMAL - 1); + i++) + val = (val * 10) + (new_order[i] - u'0'); + + if (val > max) + continue; + + *new = val; + return EFI_SUCCESS; + } else { + return ret; + } + } +} + +static efi_status_t efi_bootmenu_select_file_handler(struct efi_bootmenu_boot_option *bo) +{ + efi_status_t ret; + struct efi_file_handle *root; + + bo->file_selected = false; + + while (!bo->file_selected) { + bo->current_volume = NULL; + memset(bo->current_path, 0, sizeof(bo->current_path)); + + ret = efi_bootmenu_select_volume(bo); + if (ret != EFI_SUCCESS) + return ret; + + if (!bo->current_volume) + return EFI_INVALID_PARAMETER; + + ret = efi_open_volume_int(bo->current_volume, &root); + if (ret != EFI_SUCCESS) + return ret; + + ret = efi_bootmenu_select_file(bo, root); + if (ret != EFI_SUCCESS) + return ret; + } + + ret = efi_bootmenu_boot_add_enter_name(bo); + + return ret; +} + +efi_status_t efi_bootmenu_get_unused_bootoption(u16 *buf, + efi_uintn_t buf_size, u32 *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; +} + +static efi_status_t efi_bootmenu_set_boot_option(u16 *var_name, 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(var_name, &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, p, false); + free(p); + + return ret; +} + +efi_status_t efi_bootmenu_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; +} + +static efi_status_t efi_bootmenu_process_add_boot_option(void *data, bool *exit) +{ + u32 index; + u16 var_name[9]; + char *buf = NULL; + efi_status_t ret; + char *iter = NULL; + efi_uintn_t dp_size, fp_size; + struct efi_bootmenu_boot_option bo; + struct efi_device_path_file_path *fp; + + ret = efi_bootmenu_get_unused_bootoption(var_name, sizeof(var_name), + &index); + if (ret != EFI_SUCCESS) + return ret; + + bo.current_path = calloc(1, EFI_BOOTMENU_FILE_PATH_MAX); + if (!bo.current_path) + goto out; + + bo.boot_name = calloc(1, EFI_BOOTMENU_BOOT_NAME_MAX * sizeof(u16)); + if (!bo.boot_name) + goto out; + + ret = efi_bootmenu_select_file_handler(&bo); + if (ret != EFI_SUCCESS) + goto out; + + dp_size = efi_dp_size(bo.dp_volume); + fp_size = sizeof(struct efi_device_path) + + ((u16_strlen(bo.current_path) + 1) * sizeof(u16)); + buf = calloc(1, dp_size + fp_size + sizeof(END)); + if (!buf) + goto out; + + iter = buf; + memcpy(iter, bo.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.current_path); + iter += fp_size; + *((struct efi_device_path *)iter) = END; + + ret = efi_bootmenu_set_boot_option(var_name, (struct efi_device_path *)buf, + bo.boot_name, NULL); + if (ret != EFI_SUCCESS) + goto out; + + efi_bootmenu_append_bootorder((u16)index); + if (ret != EFI_SUCCESS) + goto out; + +out: + free(buf); + free(bo.boot_name); + free(bo.current_path); + + return ret; +} + +static efi_status_t delete_boot_option(u16 *bootorder, u16 index, efi_uintn_t size) +{ + u16 var_name[9]; + efi_status_t ret; + efi_uintn_t num; + + efi_create_indexed_name(var_name, sizeof(var_name), + "Boot", bootorder[index]); + ret = efi_set_variable_int(var_name, &efi_global_variable_guid, + 0, 0, NULL, false); + if (ret != EFI_SUCCESS) { + log_err("delete boot option(%ls) failed\n", var_name); + 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; +} + +static efi_status_t efi_bootmenu_process_delete_boot_option(void *data, bool *exit) +{ + int selected; + u16 *bootorder; + efi_status_t ret; + efi_uintn_t num, size; + + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + if (!bootorder) { + ret = EFI_NOT_FOUND; + return ret; + } + + num = size / sizeof(u16); + ret = efi_bootmenu_show_boot_selection(bootorder, num, &selected); + if (ret == EFI_SUCCESS) + ret = delete_boot_option(bootorder, selected, size); + + free(bootorder); + + return ret; +} + +static efi_status_t efi_bootmenu_process_change_boot_order(void *data, bool *exit) +{ + int selected; + int new_order; + efi_status_t ret; + efi_uintn_t num, size; + u16 *bootorder = NULL; + u16 *new_bootorder = NULL; + + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + if (!bootorder) + return EFI_NOT_FOUND; + + num = size / sizeof(u16); + ret = efi_bootmenu_show_boot_selection(bootorder, num, &selected); + if (ret != EFI_SUCCESS) + goto out; + + ret = efi_bootmenu_change_boot_order(selected, num - 1, &new_order); + if (ret != EFI_SUCCESS) + goto out; + + new_bootorder = calloc(1, size); + if (!new_bootorder) + goto out; + + memcpy(new_bootorder, bootorder, size); + if (selected > new_order) { + new_bootorder[new_order] = bootorder[selected]; + memcpy(&new_bootorder[new_order + 1], &bootorder[new_order], + (selected - new_order) * sizeof(u16)); + } else if (selected < new_order) { + new_bootorder[new_order] = bootorder[selected]; + memcpy(&new_bootorder[selected], &bootorder[selected + 1], + (new_order - selected) * sizeof(u16)); + } else { + /* nothing to change */ + goto out; + } + 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); +out: + free(new_bootorder); + free(bootorder); + + return ret; +} + +static efi_status_t efi_bootmenu_init(void) +{ + efi_status_t ret; + struct efi_handler *handler; + + 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; + + ret = efi_search_protocol(efi_root, &efi_guid_text_output_protocol, &handler); + if (ret != EFI_SUCCESS) + return ret; + + ret = efi_protocol_open(handler, (void **)&cout, efi_root, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + return ret; + + return ret; +} + +efi_status_t efi_bootmenu_show_maintenance_menu(void) +{ + efi_status_t ret; + + ret = efi_bootmenu_init(); + if (ret != EFI_SUCCESS) + return ret; + + return efi_bootmenu_process_common(maintenance_menu_items, + ARRAY_SIZE(maintenance_menu_items), + -1); +} 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 ba68a15017..f5002e1c99 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -5,6 +5,7 @@ * Copyright (c) 2016 Alexander Graf */ +#include #include #include #include @@ -1312,3 +1313,83 @@ 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 + * @cout: protocol interface to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL + * @buf: buffer to store user input string in UTF16 + * @size: buffer size including NULL terminator + * @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, + struct efi_simple_text_output_protocol *cout, + u16 *buf, efi_uintn_t size, + 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, row, col); + puts(ANSI_CLEAR_LINE_TO_END); + puts(ANSI_CURSOR_SHOW); + + 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, row, col); + ret = EFI_CALL(cout->output_string(cout, buf)); + if (ret != EFI_SUCCESS) + return ret; + + puts(ANSI_CLEAR_LINE_TO_END); + continue; + } else if (key.unicode_char == u'\r') { + if (len == 0) /* no user input */ + continue; + + 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 >= (size - 1)) + continue; + + buf[len] = key.unicode_char; + len++; + printf(ANSI_CURSOR_POSITION, row, col); + ret = EFI_CALL(cout->output_string(cout, buf)); + if (ret != EFI_SUCCESS) + return ret; + } +} diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index c905c12abc..4963fefd86 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -587,3 +587,14 @@ efi_status_t efi_disk_register(void) return EFI_SUCCESS; } + +efi_status_t efi_disk_get_device_name(struct efi_block_io *this, char *buf, int size) +{ + struct efi_disk_obj *diskobj; + + diskobj = container_of(this, struct efi_disk_obj, ops); + + snprintf(buf, size, "%s%d:%d", diskobj->ifname, diskobj->dev_index, diskobj->part); + + 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 Thu Mar 24 13:54: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: 553919 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:1248:0:0:0:0 with SMTP id z8csp4439120mag; Thu, 24 Mar 2022 06:56:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyR52fBsdO2TqS1pyBAMKDOj2dX4DYpLgh4bOMDIiVOaMeFrYIAoBVwRPozY/dINIW4xIjr X-Received: by 2002:a17:906:a1c2:b0:6d6:d54d:4fb1 with SMTP id bx2-20020a170906a1c200b006d6d54d4fb1mr6019478ejb.490.1648130191961; Thu, 24 Mar 2022 06:56:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648130191; cv=none; d=google.com; s=arc-20160816; b=R651y0KY8WbNedTS4JPILyByEWQ+2KmiRO0sNsYGsL1/BrhSD+yTPlu5wICQFZCaiz hazzd61IYD0YQupeW9tyk/b4aQeyO9ldEmoGFQRZ/bEb/KnosPkZKB0xUwRmTSJ7wl1a JaVqC3AD0nONk+0CBTCKFhkaxSMm/+zTfe3aIqAZDHy/NH6FXlwWooAESYRpLieQzU2K 1S8tn5MVNMXq+qwvDVb3NYN8YSsBSzGcp22Tc7SWmvgqnXP0t1dDEu6UEVv9DWZ6fQYw B/+/BOrfTPxU3vXJy63IPRi3p76zHWG425yLgLmb0w2FtOoGMtxnr8H1mwD9AMSMGqvO EQJQ== 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=pFOOErQDOBkVcMwyhyfisM8W5vYktBskj+N5U35cHwM=; b=buE6G+FA+NTWZARCF28r8sXyMbCXa9eYm8HKa/4wrmvI8RoVflePCygCPXZrkyu63u xgQuHpjNP6IgWJdJF+KO9U4SR/XfHLKTjSPid7FH+1v6o6WneZZNDGR4x2KyoZmKxVeV zciWRL6SlppouXir8VWEQzXKmbZh+3PwLFYj05mKK/EO4JXarIuxaEnvSchVwpa7Zlt3 vp2sBgGRqowMuuWvRk4DtbuRHRz60GQ9U7lNLi5IY1qDfjfLXi6/i2K0OcBOrB7WVaDf zbakVMyrV2XGTlouqIvaWOOzkLtRNORS/l3oeYyium0q8AaXOMSsfGo4qPnqYHms7rgd zP5w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=SOpWq3jv; 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 og10-20020a1709071dca00b006df76385df5si14858029ejc.661.2022.03.24.06.56.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:56:31 -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=SOpWq3jv; 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 27541840D8; Thu, 24 Mar 2022 14:55:28 +0100 (CET) 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="SOpWq3jv"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 0E5D4840C3; Thu, 24 Mar 2022 14:55:15 +0100 (CET) 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-x530.google.com (mail-pg1-x530.google.com [IPv6:2607:f8b0:4864:20::530]) (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 ED4A8840C6 for ; Thu, 24 Mar 2022 14:55:09 +0100 (CET) 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-x530.google.com with SMTP id k14so3919771pga.0 for ; Thu, 24 Mar 2022 06:55: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=pFOOErQDOBkVcMwyhyfisM8W5vYktBskj+N5U35cHwM=; b=SOpWq3jvrSFrQ9jWjPWkShYVWcqpHpBw846ncpJ8AOdL9tvm5HsrGiIRyMZd1xjfYz bgljbl3EUAK//udTHsppeIjIO2i3g9U6sbNHv/G2ynyeQvvBbJCpJXcCWuaMpq4hTJTF sVtcJiwq5IxK4cIkcuzEh+ryt2LoJztqGK0NZG4VKE8j6dl4yiQv+v9IVxAa5ktEDVAk O0zqblv1mjlsK/M7fpBUpzjfYkPBZb69oa0PURpPZWvRm7mQSMy4gxF2e0AH7MIFeczS IHq+USqtIR6U0WTSBoQF/7GtRIWh5zhyr+aXQlWSC1GvMGh8C9Z1vGx5SwNzXArz/gFi bflQ== 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=pFOOErQDOBkVcMwyhyfisM8W5vYktBskj+N5U35cHwM=; b=2bLuaeWKTGNnXIqNB3QSZxHUDOvgX++eigwKLZLIAdpV2/oA9mIWC/nX0Bj+Fr06fM qaAMTrFPYEJ0KttX34idKG0XRsdqcnJIkYunhD2IaFmwk4yApZp1YfO07vrFVn7t03wR OX5IXGVeG2zvoVBzXaJZcPqKN1G4CIB96oNtTDU3pi3swC6TAG03dhRUTUlYrqyT21d0 Ia56y1fAQB4Oo8B5AmFrxacAolFC33TtC8muZ4ql7F2vyXA4F1iiXck004n4qsiwLFxN jXsNG1y/6b5vLKSM2sO39CqX9jVyLWQ7HZt8Z4LAjXQyrZ7SQiaFZS1FSUt/LxjJjSgJ xoyw== X-Gm-Message-State: AOAM530NJpYTolg5Y1WIawzo4DDM0IOYthxVeW7P7l+GTQeXUZVd6k11 mQ7VOTZ+J8XDFt51aa74mOLU1AmTIQQtSw== X-Received: by 2002:aa7:92cf:0:b0:4fa:3b47:7408 with SMTP id k15-20020aa792cf000000b004fa3b477408mr5460281pfa.72.1648130108100; Thu, 24 Mar 2022 06:55:08 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id p15-20020a056a000a0f00b004f7c63cba5asm3974609pfh.21.2022.03.24.06.55.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:55:07 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima Subject: [PATCH v4 10/11] bootmenu: add removable media entries Date: Thu, 24 Mar 2022 22:54:42 +0900 Message-Id: <20220324135443.1571-11-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220324135443.1571-1-masahisa.kojima@linaro.org> References: <20220324135443.1571-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.5 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. Depending on the system hardware setup, some devices may not exist at a later system boot, so invalid BOOT#### variable must be deleted. Signed-off-by: Masahisa Kojima --- Newly created in v4 cmd/bootmenu.c | 78 +++++++++++++ include/efi_loader.h | 22 ++++ lib/efi_loader/efi_bootmenu_maintenance.c | 128 ++++++++++++++++++++++ 3 files changed, 228 insertions(+) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 458eb90b63..7357cfeae5 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -304,6 +304,74 @@ static int prepare_uefi_bootorder_entry(struct bootmenu_data *menu, return 1; } +static efi_status_t prepare_media_device_entry(void) +{ + u32 i; + efi_status_t ret; + efi_uintn_t count; + efi_handle_t *volume_handles = NULL; + struct efi_bootmenu_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 efi_bootmenu_media_boot_option)); + if (!opt) + goto out; + + /* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */ + ret = efi_bootmenu_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 = efi_bootmenu_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 = efi_bootmenu_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 = efi_bootmenu_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; +} + static int prepare_distro_boot_entry(struct bootmenu_data *menu, struct bootmenu_entry **current, unsigned short int *index) @@ -408,6 +476,16 @@ static struct bootmenu_data *bootmenu_create(int delay) goto cleanup; if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { + if (i < MAX_DYNAMIC_ENTRY) { + /* + * UEFI specification requires booting from removal media using + * a architecture-specific default image name such as BOOTAA64.EFI. + */ + ret = prepare_media_device_entry(); + if (ret != EFI_SUCCESS) + goto cleanup; + } + if (i < MAX_DYNAMIC_ENTRY) { ret = prepare_uefi_bootorder_entry(menu, &iter, &i); if (ret < 0 && ret != -ENOENT) diff --git a/include/efi_loader.h b/include/efi_loader.h index 7b100ca030..c326dfdaf2 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -926,6 +926,22 @@ struct efi_signature_store { struct x509_certificate; struct pkcs7_message; +/** + * struct efi_bootmenu_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 efi_bootmenu_media_boot_option { + void *lo; + efi_uintn_t size; + bool exist; +}; + bool efi_signature_lookup_digest(struct efi_image_regions *regs, struct efi_signature_store *db, bool dbx); @@ -1038,6 +1054,12 @@ efi_status_t efi_console_get_u16_string efi_status_t efi_bootmenu_get_unused_bootoption(u16 *buf, efi_uintn_t buf_size, u32 *index); efi_status_t efi_bootmenu_append_bootorder(u16 index); +efi_status_t efi_bootmenu_enumerate_boot_option( + struct efi_bootmenu_media_boot_option *opt, + efi_handle_t *volume_handles, efi_status_t count); +efi_status_t efi_bootmenu_delete_invalid_boot_option( + struct efi_bootmenu_media_boot_option *opt, + efi_status_t count); efi_status_t efi_disk_get_device_name(struct efi_block_io *this, char *buf, int size); diff --git a/lib/efi_loader/efi_bootmenu_maintenance.c b/lib/efi_loader/efi_bootmenu_maintenance.c index 2ce5a47b10..3a64cf767a 100644 --- a/lib/efi_loader/efi_bootmenu_maintenance.c +++ b/lib/efi_loader/efi_bootmenu_maintenance.c @@ -24,6 +24,8 @@ static struct efi_simple_text_output_protocol *cout; #define EFI_BOOTMENU_FILE_PATH_MAX 512 #define EFI_BOOTMENU_BOOT_NAME_MAX 32 #define EFI_BOOT_ORDER_MAX_SIZE_IN_DECIMAL 6 +#define BOOTMENU_AUTO_ADD_OPTION_DATA "bootmenu" +#define BOOTMENU_AUTO_ADD_OPTION_DATA_U16 u"bootmenu" typedef efi_status_t (*efi_bootmenu_entry_func)(void *data, bool *exit); @@ -1114,3 +1116,129 @@ efi_status_t efi_bootmenu_show_maintenance_menu(void) ARRAY_SIZE(maintenance_menu_items), -1); } + +efi_status_t efi_bootmenu_enumerate_boot_option( + struct efi_bootmenu_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++) { + u16 *dev_name, *p; + struct efi_load_option lo; + struct efi_block_io *block_io; + 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_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; + + efi_disk_get_device_name(block_io, buf, BOOTMENU_DEVICE_NAME_MAX); + 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); + /* + * To identify the boot option that automatically added by + * the bootmenu, optional_data has special string. + * optional_data will be converted into u16 string + * in efi_serialize_load_option(). + */ + lo.optional_data = BOOTMENU_AUTO_ADD_OPTION_DATA; + 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; + } + free(dev_name); + } + +out: + return ret; +} + +efi_status_t efi_bootmenu_delete_invalid_boot_option( + struct efi_bootmenu_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_NOT_FOUND; + + 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, &tmp); + if (ret != EFI_SUCCESS) + goto next; + + if (u16_strncmp((u16 *)lo.optional_data, BOOTMENU_AUTO_ADD_OPTION_DATA_U16, + u16_strlen(BOOTMENU_AUTO_ADD_OPTION_DATA_U16)) == 0) { + for (j = 0; j < count; j++) { + if (memcmp(opt[j].lo, load_option, size) == 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; +} From patchwork Thu Mar 24 13:54: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: 553921 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:1248:0:0:0:0 with SMTP id z8csp4439417mag; Thu, 24 Mar 2022 06:56:55 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy6VR8qYg/holZjOmHejBHc5rvXGopuWFXqgBVfxrdHkm6/Kmbp1XMra9eJAehyF8jHC3gH X-Received: by 2002:a17:906:2991:b0:6cf:6b24:e92f with SMTP id x17-20020a170906299100b006cf6b24e92fmr5830000eje.748.1648130215477; Thu, 24 Mar 2022 06:56:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648130215; cv=none; d=google.com; s=arc-20160816; b=kDD8PZFo1xBdVUGgScrkF4o4J2RZHRnw7cJ9c5uqc+edQ10Y8CpAF4MMduAXpb7VJZ yQrlwhK5O/6F2EHsUE6Znh3qoT1XiJdROC/KunGSv//3SR4jYZL3dydXUPvVnBzoCntV 0fdXLCaIQQNeYxmJ/fCtFlWPv7YoeHwNo18Xnqq19g2I7O797F5QAY+751LkmLm1ZjWL on/bPR5bHFavNkr4JLJCC4COf/pgI49vxnQ7BjjXdeAawx4r/BjjBEwRi+A/TFrQlwcq 8Arp374pZCfST9Xy9U3OjOR0HzNgtaivDnftte2OWOU5CD7w2cqA+KdA2tlT4LAE3inz +VSA== 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=rl8GREhCACmisHRJxBZCyWw8xh2tt89HWErYawvvy/w=; b=xgtRYy+g2RjNaDehIIJg28FAH9l8qM5vwbEfv600XoDWT/+WHz9Ue3HSoUlVmyecyu a5xaqp8WFBqiXN5NHpRnCH+jLmJ4hZuMYD4nPXzFW5kSqGFN4uVu9ziOw1Pf9AtdYBGp Jw/2uA9V/zXs0XIM3t0XZBS3apA8+L5TjY6JEKLd5AjYEg0txi2vBfoNSI0v6A5K7Arm zA4b8VKOK5mXZJ6dxTyP9cTQBBow1tPr1oO4UGW5CQj6BIvV5LajeNUNbL1PRLjbuC1a Fi1s59pogZTowF1w1QAZQDA9zg9l6xtuYm4kVRaleDW6tjo6T88tw1IsN2sDIOp33NaN 2Q6A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=bkvmrEwc; 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 f23-20020a170906391700b006df76385f07si6919673eje.935.2022.03.24.06.56.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:56:55 -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=bkvmrEwc; 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 9EC24840E2; Thu, 24 Mar 2022 14:55:34 +0100 (CET) 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="bkvmrEwc"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 81C6F840C3; Thu, 24 Mar 2022 14:55:17 +0100 (CET) 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-x530.google.com (mail-pg1-x530.google.com [IPv6:2607:f8b0:4864:20::530]) (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 80D1D840D6 for ; Thu, 24 Mar 2022 14:55:12 +0100 (CET) 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-x530.google.com with SMTP id q19so3899807pgm.6 for ; Thu, 24 Mar 2022 06:55: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=rl8GREhCACmisHRJxBZCyWw8xh2tt89HWErYawvvy/w=; b=bkvmrEwce04U2qtocaZb+a79Pz1CUtPDeHUMBNgDEKQfTiZ6+2XfUsN1UHMkX+7y6y Sx8//911Fd67PKpuNIX+rlFAhmmDu8MMUROaSgO3lq7rT9XjbtT+bmhXkGTGeqx2Fn39 cugRh37jD/HMMKa3MSURvEk8IUtrpjCvdf3xj2pKEYjg0FeXXFWLhV/vZrmhOoqocG3z CVrpqaeCq8GoBqnqbfFZySAjAgK1S+99M0Pi9m2LCBSzi5c3iaMEp4h88Q+mhf0+kK4x wRQwpVPZgqd/L+XwJ0phMVtCE/p+YkYz3a2dqKPHiDtTE+2KfzA3q+xkzMTrFvf19Pkn VQ2w== 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=rl8GREhCACmisHRJxBZCyWw8xh2tt89HWErYawvvy/w=; b=LiQV5Lbz2bR+4VzkQii30kLYNNUyB5RAvGEXOWzHM3WVTjUWOpj2JMMCE3jLH30eZ0 AXn817P6dB/sLlIgja461la69WAZ2zVYi3ONSewvIlAr6JqDikFd7CM69VvtSQvdvy0/ iha+2aPmVs5MXCI9h6p2p9muXaOsz3RqZQ5xkcWiU4nEc0HrMs/8wEqmNjteW2VyROC5 qA1N5DFoJ/Clo72k9CVxzvaSXe5fmj7nfxaQFHS/AHUR1dXmQdyku5Mhp/cHdRZ2w9UM 16hIZmE78ntbkhbTlwkGY6s7tgO/Qywz7R3fwcCCIfjfWM3GSgWSByvc7S0aARiy89S7 daOw== X-Gm-Message-State: AOAM530Q8ymkSTV1gtdePYqP1U2SaWFVqKq4LL63O1sTAsHJHXAvi3jx WhoxdrDfCltGZVHoa/eBV/bss9HaeEpdVw== X-Received: by 2002:a05:6a00:2485:b0:4f6:b5c5:ee8e with SMTP id c5-20020a056a00248500b004f6b5c5ee8emr5132637pfv.21.1648130110782; Thu, 24 Mar 2022 06:55:10 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id p15-20020a056a000a0f00b004f7c63cba5asm3974609pfh.21.2022.03.24.06.55.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Mar 2022 06:55:10 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Masahisa Kojima Subject: [PATCH v4 11/11] doc:bootmenu: add UEFI boot variable and distro boot support Date: Thu, 24 Mar 2022 22:54:43 +0900 Message-Id: <20220324135443.1571-12-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220324135443.1571-1-masahisa.kojima@linaro.org> References: <20220324135443.1571-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.5 at phobos.denx.de X-Virus-Status: Clean The bootmenu enumerates the UEFI boot variable and distro boot (boot_targets) for boot device selection. Signed-off-by: Masahisa Kojima --- Newly created in v4 doc/usage/bootmenu.rst | 65 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/doc/usage/bootmenu.rst b/doc/usage/bootmenu.rst index 1f094ad6ed..dc1d22062b 100644 --- a/doc/usage/bootmenu.rst +++ b/doc/usage/bootmenu.rst @@ -93,3 +93,68 @@ When you intend to use the bootmenu on a color frame buffer console, make sure to additionally define:: CONFIG_CFB_CONSOLE_ANSI=y + +UEFI boot variable enumeration +============================== + +The bootmenu automatically generates the UEFI boot variable("BOOT####") +in order of "BootOrder". When the user selects the UEFI boot +variable entry, bootmenu sets the selected boot variable index +to "BootNext", then call the uefi boot manager with the command +"bootefi bootmgr". + +The bootmenu automatically enumerates the possible bootable +media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. + +The bootmenu prints the EFI_LOAD_OPTION.Description[] as title +of the entry together with "UEFI" prefix and BOOT#### variable name. + +Example bootmenu is as below:: + + *** U-Boot Boot Menu *** + + UEFI BOOT0000 : mmc0:1 + UEFI BOOT0001 : mmc0:2 + UEFI BOOT0002 : debian + UEFI BOOT0003 : nvme0:1 + UEFI BOOT0004 : ubuntu + UEFI BOOT0005 : nvme0:2 + UEFI BOOT0006 : usb0:2 + +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" + +distro boot command enumeration +=============================== + +The bootmenu also automatically generates the entries for +distro boot command. The bootmenu shows the devices in boot_targets +environment variable. +When the user selects the distro boot command entry, the bootmenu +runs the command defined in "bootcmd_xxx" environment variable. +As an example, if user selects "usb0" entry, bootmenu runs the +command defined in "bootcmd_usb0". + +Example boot_targets:: + + usb0, scsi0, nvme0, dhcp + +Example bootmenu is as below:: + + *** U-Boot Boot Menu *** + + distro_boot : usb0 + distro_boot : scsi0 + distro_boot : nvme0 + distro_boot : dhcp + +Disable to enter the U-Boot console +=================================== + +To improve the product security, U-Boot console can be disabled by:: + + CONFIG_CMD_BOOTMENU_ENTER_UBOOT_CONSOLE=n