From patchwork Mon Sep 7 05:34:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358574 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=Gf1LUwux; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlH7t1nWHz9sSP for ; Mon, 7 Sep 2020 15:36:08 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id AD4A7824A9; Mon, 7 Sep 2020 07:35:56 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Gf1LUwux"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 84415824AE; Mon, 7 Sep 2020 07:35:50 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x443.google.com (mail-pf1-x443.google.com [IPv6:2607:f8b0:4864:20::443]) (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 D7872824A9 for ; Mon, 7 Sep 2020 07:35:42 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pf1-x443.google.com with SMTP id b124so8013809pfg.13 for ; Sun, 06 Sep 2020 22:35: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 :mime-version:content-transfer-encoding; bh=Zi7aKf5qP1b8ddwIytuFsCexeq9zKmRYaMwNeAo9Vpk=; b=Gf1LUwuxOhto/YfB3DFECJTgq65AUTiflBI5n9HmmePYLB2Zcn6W0RLOOvzVP71BP2 N40sGahDmBjmO1p6wp+uWSUWai+GOvqgSt05pE/qJozYo2BgGSV6M3Q1qV2zQUTeY121 Xs/C9glqiWI58Q2oQQexFUjFnNOZgwWAclzI1QtVLlyA83g/OOyfm06A5M7uIn2MO/Ld J3DVugAqVu4hcX2IsQyJLEtseJULJ1FStXSTUwIzid0yQ99KcoRcx80+PFTM3XuzjLFC SWdVgWeWSsUur5s7pXTotGFSVrDAjwO8HE2L7t2EK0EwAEO8uFnGYqKgymdb7BPyXlwi 3CXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Zi7aKf5qP1b8ddwIytuFsCexeq9zKmRYaMwNeAo9Vpk=; b=oURNSsOxrAfQ2FXrm9tyBTzpUFyNauVPlxZ70ric9XHsimiTAYwHpzYkJyhy5YI14D UGxMwgfJ7mQORUH6vVU8yo4jzBE4nsoOLA5e82Q6v1xD2vzl3hF+DGegefDKTsSkR2sL V9ouCaEvDfOKVuWv1poYd45nbEkFBI/dF+59nPCAnoMfWOEJTVHsb1KM+BTTmAbA1o95 jYiyS/aBC5GK9QWVUnkif2tB58Rpddt+sIre+oVgQQ6PMmxC76ajqi2oaxAiQoNZdwTE 96jtsxJ6NH9mIiA14phQbUlQRE5cP/byDQhIi359/mAaiTkO2VXlN01AxCvE2AHHc1J4 IKlw== X-Gm-Message-State: AOAM532NUAS3/09mKLx8+rpjWTgp2a06f0TOd8al0fcpP//oU8sCtzNV 1qmwuwLF2ufucjkIaq3Bdt69WA== X-Google-Smtp-Source: ABdhPJzNPPFQz+Qj7abMXOyeu55PmxSUnuocHCq7H/W4VZL+Vg4z5MfRuCOUCqwbE7s6I/8lCKmGTg== X-Received: by 2002:a63:146:: with SMTP id 67mr2178495pgb.331.1599456941250; Sun, 06 Sep 2020 22:35:41 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.35.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:35:40 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 01/17] dfu: rename dfu_tftp_write() to dfu_write_by_name() Date: Mon, 7 Sep 2020 14:34:10 +0900 Message-Id: <20200907053426.1675646-2-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean This function is essentially independent from tftp, and will also be utilised in implementing UEFI capsule update in a later commit. So just give it a more generic name. In addition, a new configuration option, CONFIG_DFU_ALT, was introduced so that the file will be compiled with different options, particularly one added in a later commit. Signed-off-by: AKASHI Takahiro --- common/update.c | 5 +++-- drivers/dfu/Kconfig | 5 +++++ drivers/dfu/Makefile | 2 +- drivers/dfu/{dfu_tftp.c => dfu_alt.c} | 17 ++++++++++++-- include/dfu.h | 32 +++++++++++++-------------- 5 files changed, 40 insertions(+), 21 deletions(-) rename drivers/dfu/{dfu_tftp.c => dfu_alt.c} (67%) diff --git a/common/update.c b/common/update.c index 36b6b7523d50..39946776d74f 100644 --- a/common/update.c +++ b/common/update.c @@ -324,8 +324,9 @@ got_update_file: } } else if (fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE)) { - ret = dfu_tftp_write(fit_image_name, update_addr, - update_size, interface, devstring); + ret = dfu_write_by_name(fit_image_name, update_addr, + update_size, interface, + devstring); if (ret) return ret; } diff --git a/drivers/dfu/Kconfig b/drivers/dfu/Kconfig index 0eec00ba734d..78f901ff348a 100644 --- a/drivers/dfu/Kconfig +++ b/drivers/dfu/Kconfig @@ -14,8 +14,13 @@ config DFU_OVER_TFTP depends on NET if DFU +config DFU_ALT + bool + default n + config DFU_TFTP bool "DFU via TFTP" + select DFU_ALT select DFU_OVER_TFTP help This option allows performing update of DFU-managed medium with data diff --git a/drivers/dfu/Makefile b/drivers/dfu/Makefile index 0d7925c083ef..cc7de1d3ed9b 100644 --- a/drivers/dfu/Makefile +++ b/drivers/dfu/Makefile @@ -9,5 +9,5 @@ obj-$(CONFIG_$(SPL_)DFU_MTD) += dfu_mtd.o obj-$(CONFIG_$(SPL_)DFU_NAND) += dfu_nand.o obj-$(CONFIG_$(SPL_)DFU_RAM) += dfu_ram.o obj-$(CONFIG_$(SPL_)DFU_SF) += dfu_sf.o -obj-$(CONFIG_$(SPL_)DFU_TFTP) += dfu_tftp.o +obj-$(CONFIG_$(SPL_)DFU_ALT) += dfu_alt.o obj-$(CONFIG_$(SPL_)DFU_VIRT) += dfu_virt.o diff --git a/drivers/dfu/dfu_tftp.c b/drivers/dfu/dfu_alt.c similarity index 67% rename from drivers/dfu/dfu_tftp.c rename to drivers/dfu/dfu_alt.c index ffae4bb54f80..5b1b13d7170d 100644 --- a/drivers/dfu/dfu_tftp.c +++ b/drivers/dfu/dfu_alt.c @@ -10,8 +10,21 @@ #include #include -int dfu_tftp_write(char *dfu_entity_name, unsigned int addr, unsigned int len, - char *interface, char *devstring) +/** + * dfu_write_by_name() - write data to DFU medium + * @dfu_entity_name: Name of DFU entity to write + * @addr: Address of data buffer to write + * @len: Number of bytes + * @interface: Destination DFU medium (e.g. "mmc") + * @devstring: Instance number of destination DFU medium (e.g. "1") + * + * This function is storing data received on DFU supported medium which + * is specified by @dfu_entity_name. + * + * Return: 0 - on success, error code - otherwise + */ +int dfu_write_by_name(char *dfu_entity_name, unsigned int addr, + unsigned int len, char *interface, char *devstring) { char *s, *sb; int alt_setting_num, ret; diff --git a/include/dfu.h b/include/dfu.h index 84abdc79acd1..cecfbd76597b 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -494,27 +494,27 @@ static inline int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr, #endif /** - * dfu_tftp_write() - write TFTP data to DFU medium + * dfu_write_by_name() - write data to DFU medium + * @dfu_entity_name: Name of DFU entity to write + * @addr: Address of data buffer to write + * @len: Number of bytes + * @interface: Destination DFU medium (e.g. "mmc") + * @devstring: Instance number of destination DFU medium (e.g. "1") * - * This function is storing data received via TFTP on DFU supported medium. + * This function is storing data received on DFU supported medium which + * is specified by @dfu_entity_name. * - * @dfu_entity_name: name of DFU entity to write - * @addr: address of data buffer to write - * @len: number of bytes - * @interface: destination DFU medium (e.g. "mmc") - * @devstring: instance number of destination DFU medium (e.g. "1") - * - * Return: 0 on success, otherwise error code + * Return: 0 - on success, error code - otherwise */ -#if CONFIG_IS_ENABLED(DFU_TFTP) -int dfu_tftp_write(char *dfu_entity_name, unsigned int addr, unsigned int len, - char *interface, char *devstring); +#if CONFIG_IS_ENABLED(DFU_ALT) +int dfu_write_by_name(char *dfu_entity_name, unsigned int addr, + unsigned int len, char *interface, char *devstring); #else -static inline int dfu_tftp_write(char *dfu_entity_name, unsigned int addr, - unsigned int len, char *interface, - char *devstring) +static inline int dfu_write_by_name(char *dfu_entity_name, unsigned int addr, + unsigned int len, char *interface, + char *devstring) { - puts("TFTP write support for DFU not available!\n"); + puts("write support for DFU not available!\n"); return -ENOSYS; } #endif From patchwork Mon Sep 7 05:34:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358575 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=FOYOR5Me; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlH8Q1KwHz9sSP for ; Mon, 7 Sep 2020 15:36:35 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 4713A824CE; Mon, 7 Sep 2020 07:36:04 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="FOYOR5Me"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 0CC4E824BE; Mon, 7 Sep 2020 07:35:55 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1041.google.com (mail-pj1-x1041.google.com [IPv6:2607:f8b0:4864:20::1041]) (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 5F39F824A9 for ; Mon, 7 Sep 2020 07:35:45 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pj1-x1041.google.com with SMTP id gf14so5914364pjb.5 for ; Sun, 06 Sep 2020 22:35:45 -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=gqY/srhD03OZnQsaQHroe9Z7PgmuG4jHelGJ5Q907Fk=; b=FOYOR5Merpq9h8upFyhoEHzuuwgLNkyaUHnS4jCd//u5Pj4BTU52AUGLW/lN9EnYU9 POLmOMbIFF1Fbqc4OR2Kujs0f75RDrCaOY0/bKpsP2TBS/b7vLa0anZW3XMHHT2QVhoY N+owubPgjSiJwhsb+uGfYcGJ9IQgqf35cO+KCCpm8/x9FKUNwzaZCjnjlbMqBp7FiWXC pC857G+MTY+A5ueFccIDISlPRyCM9Ge4LkE32D0NL5jHdzxPZ1h5NxKqhdYy6CvOBzKJ 8a0eCTqqMuqUrO3+flbXg+plrWy+2efMY22lboRbCDQJYgM8KbklZkCIHJZZNRkXYC2E IdLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gqY/srhD03OZnQsaQHroe9Z7PgmuG4jHelGJ5Q907Fk=; b=VNevUfMkoM1T56W5EnwlJ9X2b0i3gqEUePq4nMAzJ64kE3Ri5rJytqmvts7oaOT6y9 mmVM4tYmwpqNxI09P6uys9oceexOyhK/Yam7kwaAZoaRsIDCrZMYubsPgWx/B0lIbJTX VVr8LKLSgLJ2M3QLPoFH/+/aKG8+rRINoE9QqoPJB8wEzq1eyg2AzdgHcYJo0KjaooHF +RXvrO6vFBkCmpIKqIZ9svbNxWQNl/6A2cb5s8g1JUSSK+Oij8eo9K+Iv4Q3qyOfX/vC DoVc2TqdsmBvG4L0jmcKcHb8OihziJwNA1JZn+BVWN+u4VpFIK/97f/Nur5XbqaT9Taw m0RA== X-Gm-Message-State: AOAM533PWO9nuqXnmitPvpG+yKg8elehehCGNDZgp2Z4r+kWnyc9Hy0t eVbtOcQFv5pDlmdxTPO/IdfHOA== X-Google-Smtp-Source: ABdhPJxaPzjqtMa1K5wb24hY57Ak+dXcc3TuOIYxbf+RijMMJFzA3aIDOZxTcOL1rvY6NNbxoj4uAA== X-Received: by 2002:a17:90a:ad48:: with SMTP id w8mr18996586pjv.179.1599456944300; Sun, 06 Sep 2020 22:35:44 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.35.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:35:43 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 02/17] dfu: modify an argument type for an address Date: Mon, 7 Sep 2020 14:34:11 +0900 Message-Id: <20200907053426.1675646-3-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean The range of an addressable pointer can go beyond 'integer'. So change the argument type to a void pointer. Signed-off-by: AKASHI Takahiro Reviewed-by: Heinrich Schuchardt --- common/update.c | 3 ++- drivers/dfu/dfu_alt.c | 6 +++--- include/dfu.h | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/common/update.c b/common/update.c index 39946776d74f..8dd6ee8b7ddb 100644 --- a/common/update.c +++ b/common/update.c @@ -324,7 +324,8 @@ got_update_file: } } else if (fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE)) { - ret = dfu_write_by_name(fit_image_name, update_addr, + ret = dfu_write_by_name(fit_image_name, + (void *)update_addr, update_size, interface, devstring); if (ret) diff --git a/drivers/dfu/dfu_alt.c b/drivers/dfu/dfu_alt.c index 5b1b13d7170d..7528806cd163 100644 --- a/drivers/dfu/dfu_alt.c +++ b/drivers/dfu/dfu_alt.c @@ -23,14 +23,14 @@ * * Return: 0 - on success, error code - otherwise */ -int dfu_write_by_name(char *dfu_entity_name, unsigned int addr, +int dfu_write_by_name(char *dfu_entity_name, void *addr, unsigned int len, char *interface, char *devstring) { char *s, *sb; int alt_setting_num, ret; struct dfu_entity *dfu; - debug("%s: name: %s addr: 0x%x len: %d device: %s:%s\n", __func__, + debug("%s: name: %s addr: 0x%p len: %d device: %s:%s\n", __func__, dfu_entity_name, addr, len, interface, devstring); ret = dfu_init_env_entities(interface, devstring); @@ -69,7 +69,7 @@ int dfu_write_by_name(char *dfu_entity_name, unsigned int addr, goto done; } - ret = dfu_write_from_mem_addr(dfu, (void *)(uintptr_t)addr, len); + ret = dfu_write_from_mem_addr(dfu, (void *)addr, len); done: dfu_free_entities(); diff --git a/include/dfu.h b/include/dfu.h index cecfbd76597b..2299a83a3d94 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -507,10 +507,10 @@ static inline int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr, * Return: 0 - on success, error code - otherwise */ #if CONFIG_IS_ENABLED(DFU_ALT) -int dfu_write_by_name(char *dfu_entity_name, unsigned int addr, +int dfu_write_by_name(char *dfu_entity_name, void *addr, unsigned int len, char *interface, char *devstring); #else -static inline int dfu_write_by_name(char *dfu_entity_name, unsigned int addr, +static inline int dfu_write_by_name(char *dfu_entity_name, void *addr, unsigned int len, char *interface, char *devstring) { From patchwork Mon Sep 7 05:34:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358576 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=C9xVToSd; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlH8l60wsz9sSP for ; Mon, 7 Sep 2020 15:36:55 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 4737C824DC; Mon, 7 Sep 2020 07:36:16 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="C9xVToSd"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 202D9824AE; Mon, 7 Sep 2020 07:35:56 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1044.google.com (mail-pj1-x1044.google.com [IPv6:2607:f8b0:4864:20::1044]) (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 478F7824AE for ; Mon, 7 Sep 2020 07:35:53 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pj1-x1044.google.com with SMTP id a9so2930826pjg.1 for ; Sun, 06 Sep 2020 22:35:53 -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=cx6hY3daU+eiUbIq+eoZJ2Z9CmqEP9Hy6+vKyLqsvsM=; b=C9xVToSd1Ltyxn6uxbGEGK6DI818HjYpD4hxJ3CHcvmBNRyiTFYDWsrOHEfq8gxXec klwrNo40RNoiEbdjnPC/7wsbwimAwxwx9/ook3gnWc/MEQw3+fa987xAYyizLRocIAd2 FKMitj5pXXacN2X4lXb9vSZm/xbWYS+TyctKgRKRnPW4/8nLvF15sULAPOEmOuqTqfxv 1M5uGUyPnm0+N2h9iVsDP3O7vjUyhXWqg06MIRcHsPYND24yCtsWbjoe8cKRz744PX3J eVSA5TKSZZddDmgpm5UySeTtq7SFCDl2KBraj70iYSI5aSmcK78GnSVVyRKqs03jnaPz i65w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cx6hY3daU+eiUbIq+eoZJ2Z9CmqEP9Hy6+vKyLqsvsM=; b=f2249K8RPFOdNthHCeaQGSg6yvkhJtGx70t/VOvcLaocSQBmGUPz5GA3q0sXpKka7e euZJFvxNaXwUgIPFtMEbNCqCzeDmRGTSICMTMRwUTgdrZhg4JTy9JwbHY8mhlzxeJ5rO /LAFHnydSuNb+7XxkGs5ScqgZgD51tpZW/rMya1/SZUC9PvBrJll6b9eS6MtfEL3IOR6 Ia6BpQvVgT1EA3OrAghBa1d5eDIIGQuG5X8YUaSOCaOk5NeQKZ7rKp7miNvLl4wptx7H 5vsubOd4e1HhoX4cw24vhHI//dba87Gmj6sYv5flRSQ/9nrHaRgdLIZ54khYAOsL3B64 WuPg== X-Gm-Message-State: AOAM533WjqogRNgA447fR5DWO50S0cT1v9WF6ejyymZ1tUGNDzNGplD3 hH0B47I3Jqzh0zRdycYKe7ddkA== X-Google-Smtp-Source: ABdhPJwjG1l6iADxX+H/V8YH/eVA1/rr2gID7ryqaQGYlwrwB3lgiKXBxDKe3WGVkkKQAa96W6yh1g== X-Received: by 2002:a17:90b:803:: with SMTP id bk3mr19102322pjb.57.1599456947222; Sun, 06 Sep 2020 22:35:47 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.35.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:35:46 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 03/17] common: update: add a generic interface for FIT image Date: Mon, 7 Sep 2020 14:34:12 +0900 Message-Id: <20200907053426.1675646-4-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean The main purpose of this patch is to separate a generic interface for updating firmware using DFU drivers from "auto-update" via tftp. This function will also be used in implementing UEFI capsule update in a later commit. Signed-off-by: AKASHI Takahiro --- common/Kconfig | 15 ++++++++++ common/Makefile | 3 +- common/update.c | 71 +++++++++++++++++++++++++++++++++++++++++++++ drivers/dfu/Kconfig | 1 + include/image.h | 12 ++++++++ 5 files changed, 100 insertions(+), 2 deletions(-) diff --git a/common/Kconfig b/common/Kconfig index c58f08ba91bf..36998e382bda 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -1050,9 +1050,15 @@ endmenu menu "Update support" +config UPDATE_COMMON + bool + default n + select DFU_ALT + config UPDATE_TFTP bool "Auto-update using fitImage via TFTP" depends on FIT + select UPDATE_COMMON help This option allows performing update of NOR with data in fitImage sent via TFTP boot. @@ -1067,6 +1073,15 @@ config UPDATE_TFTP_MSEC_MAX default 100 depends on UPDATE_TFTP +config UPDATE_FIT + bool "Firmware update using fitImage" + depends on FIT + depends on DFU + select UPDATE_COMMON + help + This option allows performing update of DFU-capable storage with + data in fitImage. + config ANDROID_AB bool "Android A/B updates" default n diff --git a/common/Makefile b/common/Makefile index 2e7a090588d9..bcf352d01652 100644 --- a/common/Makefile +++ b/common/Makefile @@ -53,8 +53,7 @@ obj-$(CONFIG_LCD_ROTATION) += lcd_console_rotation.o obj-$(CONFIG_LCD_DT_SIMPLEFB) += lcd_simplefb.o obj-$(CONFIG_LYNXKDI) += lynxkdi.o obj-$(CONFIG_MENU) += menu.o -obj-$(CONFIG_UPDATE_TFTP) += update.o -obj-$(CONFIG_DFU_TFTP) += update.o +obj-$(CONFIG_UPDATE_COMMON) += update.o obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o obj-$(CONFIG_CMDLINE) += cli_readline.o cli_simple.o diff --git a/common/update.c b/common/update.c index 8dd6ee8b7ddb..808be0880dfd 100644 --- a/common/update.c +++ b/common/update.c @@ -29,6 +29,7 @@ #include #include +#ifdef CONFIG_DFU_TFTP /* env variable holding the location of the update file */ #define UPDATE_FILE_ENV "updatefile" @@ -98,6 +99,7 @@ static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr) return rv; } +#endif /* CONFIG_DFU_TFTP */ #ifdef CONFIG_MTD_NOR_FLASH static int update_flash_protect(int prot, ulong addr_first, ulong addr_last) @@ -231,6 +233,7 @@ static int update_fit_getparams(const void *fit, int noffset, ulong *addr, return 0; } +#ifdef CONFIG_DFU_TFTP int update_tftp(ulong addr, char *interface, char *devstring) { char *filename, *env_addr, *fit_image_name; @@ -337,3 +340,71 @@ next_node: return ret; } +#endif /* CONFIG_DFU_UPDATE */ + +#ifdef CONFIG_UPDATE_FIT +/** + * fit_update - update storage with FIT image + * @fit: Pointer to FIT image + * + * Update firmware on storage using FIT image as input. + * The storage area to be update will be identified by the name + * in FIT and matching it to "dfu_alt_info" variable. + * + * Return: 0 - on success, non-zero - otherwise + */ +int fit_update(const void *fit) +{ + char *fit_image_name; + ulong update_addr, update_fladdr, update_size; + int images_noffset, ndepth, noffset; + int ret = 0; + + if (!fit) + return -EINVAL; + + if (!fit_check_format((void *)fit)) { + printf("Bad FIT format of the update file, aborting auto-update\n"); + return -EINVAL; + } + + /* process updates */ + images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); + + ndepth = 0; + noffset = fdt_next_node(fit, images_noffset, &ndepth); + while (noffset >= 0 && ndepth > 0) { + if (ndepth != 1) + goto next_node; + + fit_image_name = (char *)fit_get_name(fit, noffset, NULL); + printf("Processing update '%s' :", fit_image_name); + + if (!fit_image_verify(fit, noffset)) { + printf("Error: invalid update hash, aborting\n"); + ret = 1; + goto next_node; + } + + printf("\n"); + if (update_fit_getparams(fit, noffset, &update_addr, + &update_fladdr, &update_size)) { + printf("Error: can't get update parameters, aborting\n"); + ret = 1; + goto next_node; + } + + if (fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE)) { + ret = dfu_write_by_name(fit_image_name, + (void *)update_addr, + update_size, NULL, NULL); + if (ret) + return ret; + } +next_node: + noffset = fdt_next_node(fit, noffset, &ndepth); + } + + return ret; +} +#endif /* CONFIG_UPDATE_FIT */ diff --git a/drivers/dfu/Kconfig b/drivers/dfu/Kconfig index 78f901ff348a..ce0c42c7df9c 100644 --- a/drivers/dfu/Kconfig +++ b/drivers/dfu/Kconfig @@ -22,6 +22,7 @@ config DFU_TFTP bool "DFU via TFTP" select DFU_ALT select DFU_OVER_TFTP + select UPDATE_COMMON help This option allows performing update of DFU-managed medium with data sent via TFTP boot. diff --git a/include/image.h b/include/image.h index 9a5a87dbf870..35b8b7c3d84f 100644 --- a/include/image.h +++ b/include/image.h @@ -1592,4 +1592,16 @@ struct fit_loadable_tbl { .handler = _handler, \ } +/** + * fit_update - update storage with FIT image + * @fit: Pointer to FIT image + * + * Update firmware on storage using FIT image as input. + * The storage area to be update will be identified by the name + * in FIT and matching it to "dfu_alt_info" variable. + * + * Return: 0 on success, non-zero otherwise + */ +int fit_update(const void *fit); + #endif /* __IMAGE_H__ */ From patchwork Mon Sep 7 05:34:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358578 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=N5B9+0C3; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlH9B3689z9sSP for ; Mon, 7 Sep 2020 15:37:18 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 49B40824A9; Mon, 7 Sep 2020 07:36:22 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="N5B9+0C3"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 041AC824D5; Mon, 7 Sep 2020 07:36:08 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x644.google.com (mail-pl1-x644.google.com [IPv6:2607:f8b0:4864:20::644]) (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 B971C824AE for ; Mon, 7 Sep 2020 07:35:56 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pl1-x644.google.com with SMTP id j7so1142672plk.11 for ; Sun, 06 Sep 2020 22:35: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 :mime-version:content-transfer-encoding; bh=0AfYMcPf+ZnAOcOuxNgaIkD5zAmRUz9pGnONGECo7aA=; b=N5B9+0C3vRu0HwPizeNk2cBv9MQUX66KfsUu2rG7JVavOr5grH8HNqy/93PU1//ixv A7XfIGdfW8Z31b90tfdWqT2svXkxPtsYTD3PkqYhm4gjM4bvS+HU7gFrOohE2PvNiOmA 0gcB1YBYcU08Fi7K5ngcaQRgV1SR7ehmmaS9cyZIbMyQcotbabWlymlJfoThwuUhVHIp uFuJaOLi4TP2UFEhSXkTQuKtGEAtkpSbBZmnUugm4fUVrmfZtjdtxi8Kz67wK46s1oyu +rSy+XWIExQA/OJPJmhoHjKm0UlxEEamLI+J1lbS71zHaTm6PeymkbMNoVcrh1Ow6Yn4 SRLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0AfYMcPf+ZnAOcOuxNgaIkD5zAmRUz9pGnONGECo7aA=; b=lPDKfrzGC5wuZdJsuB8vEa2zlZ6Or5iAlJ7BEep7Umo/yq5K+1QraZoRwc1I8f4cN4 qqqfhVpmJ+fpFytwPTziuZPmYwVEWdxKD7+iqRinDy+NBAcaea31qybIBb/CWGKV8BS6 uvkLDQm6I1uUJ/MccZqUlyeXuIR+8iuXk2v6FdlFdQnsKt3xxsXN8oGkAoUNsNOAS5In fAqMVWfn9rXYoKBFZ7421eaKALDUNqlBz/U9FZmMrfMCqi/EZrPSsWKmBEqrU0v6V9SP 0QfJ0aHwiAD2gRZ4jTKhMSEEcfMWqGv1jomlfvKRpK0r6SG5jOTBWUr9ihkIjez1X/j0 02WQ== X-Gm-Message-State: AOAM530NxluOr4Uf0jUK+jRO7AZc2uu5oaHtWOjB1diXm/hXKmNCGaTF qsOD7WJ8kClJbhtv3W2YZfJw6w== X-Google-Smtp-Source: ABdhPJwYr3vIe4bHC2oysa/Ms0j+/z3ioqONR6yxNfT9vb0caPoiSSxeE3PvLIrgaPHcwybJD26nmA== X-Received: by 2002:a17:90b:510:: with SMTP id r16mr18849602pjz.75.1599456949969; Sun, 06 Sep 2020 22:35:49 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.35.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:35:49 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 04/17] dfu: export dfu_list Date: Mon, 7 Sep 2020 14:34:13 +0900 Message-Id: <20200907053426.1675646-5-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean This variable will be utilized to enumerate all dfu entities for UEFI capsule firmware update in a later commit. Signed-off-by: AKASHI Takahiro --- drivers/dfu/dfu.c | 2 +- include/dfu.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/dfu/dfu.c b/drivers/dfu/dfu.c index a298c2c43999..501a60b34400 100644 --- a/drivers/dfu/dfu.c +++ b/drivers/dfu/dfu.c @@ -18,7 +18,7 @@ #include #include -static LIST_HEAD(dfu_list); +LIST_HEAD(dfu_list); static int dfu_alt_num; static int alt_num_cnt; static struct hash_algo *dfu_hash_algo; diff --git a/include/dfu.h b/include/dfu.h index 2299a83a3d94..015d1bf895d0 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -158,6 +158,9 @@ struct dfu_entity { unsigned int inited:1; }; +struct list_head; +extern struct list_head dfu_list; + #ifdef CONFIG_SET_DFU_ALT_INFO /** * set_dfu_alt_info() - set dfu_alt_info environment variable From patchwork Mon Sep 7 05:34:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358577 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=XSC1ZvKo; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlH920KlLz9sSP for ; Mon, 7 Sep 2020 15:37:09 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id C9D39824E5; Mon, 7 Sep 2020 07:36:17 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="XSC1ZvKo"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id A2C67824B0; Mon, 7 Sep 2020 07:35:57 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x442.google.com (mail-pf1-x442.google.com [IPv6:2607:f8b0:4864:20::442]) (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 5A549824B0 for ; Mon, 7 Sep 2020 07:35:54 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pf1-x442.google.com with SMTP id o20so8031773pfp.11 for ; Sun, 06 Sep 2020 22:35:54 -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=RLp5/bu3pTVrD3QOKMVF0Ts93sSOEwfySaNe5LHxTEA=; b=XSC1ZvKoU/07o4VRQtGS/TUmfClUmdY6RGKYsux85b2J921Fz5ZxSrJLTQglvuTOx7 IIJCLJUT0iAM+yF1AsQ4wid5BJR+l/VIB85JbP8nM68pM0sjRXQ6C4smOcR8phJi7ws9 rsqjZSVpRLYPg15rKIzwJKt4t8Xx9u9f7d4+Iir0RNwvvi1H538ZVLput5W1wnbjkCAi cqW6YeImBKPDNarkpRW0HmUi/G9a9GkwRvMwjq6H+oIEJFt5XLo7Q/G4ST70ttIiJx/d C5oQFk7Q1DkGfiVEyKZaMuPdsQ+HGDcYl8zPT/DQSmR8ohcJtj0FK00dB0Kr8crQAjFw i9XQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RLp5/bu3pTVrD3QOKMVF0Ts93sSOEwfySaNe5LHxTEA=; b=EB5a/GgAGfYpg1Vn7BajnyOEon0mJikD3BvDn0IBg/36TdSnLa6weRvcuQEPLV9ffa YaVglYe4kfP5+oXOlDN+qeCZh6HAiPDP7zVh7lTmVIBmu8M+xY8ItUwzNpYb/49/Q9i6 bQ8CXgsR48WDDzHKjhHEKzIV63TmHuhUKl8ir8dnefDkqIcw8ytuuLJ+XQh/XYQro5xj 8+nxYqsCC/gnKBur+rZq2yGXnT9ksOsiB9gJMjLkGryZf2iqm9WV63SXX682O4cK7+MA 9BYHEjimfdVkp0elVsQRy0TIrLRNBtPZJQkVnjGG6tHDToHk7LQzWPphln33imUwimTH CRAA== X-Gm-Message-State: AOAM533iDBMPTao/AnMTXNcZ63nXd9ncB9G6wDBcB9h8LX4tRBLXZdBB aHsOiTp73/hNK8NqYpzRW3fulA== X-Google-Smtp-Source: ABdhPJzCITxkYB/aC5lEBMlVYcPyr6NgYDVoAA/dx8BDZpibjrqut6qdqLoYCWjuN0wnEfE1XrNjtw== X-Received: by 2002:aa7:9084:0:b029:13c:1611:658c with SMTP id i4-20020aa790840000b029013c1611658cmr17717324pfa.9.1599456952875; Sun, 06 Sep 2020 22:35:52 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.35.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:35:52 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 05/17] efi_loader: add option to initialise EFI subsystem early Date: Mon, 7 Sep 2020 14:34:14 +0900 Message-Id: <20200907053426.1675646-6-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean If this option, CONFIG_EFI_SETUP_EARLY, is enabled, the initialisation of UEFI subsystem will be done as part of U-Boot initialisation. Please note that this option won't be enabled explicitly by users, instead, should be enabled implicitly by other configuration options. Specifically, this feature will be utilised in implementing capsule-on-disk feature. Signed-off-by: AKASHI Takahiro --- common/board_r.c | 6 ++++++ lib/efi_loader/Kconfig | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/common/board_r.c b/common/board_r.c index 9b2fec701a55..0391a1b6acb7 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -72,6 +72,9 @@ #if defined(CONFIG_GPIO_HOG) #include #endif +#ifdef CONFIG_EFI_SETUP_EARLY +#include +#endif DECLARE_GLOBAL_DATA_PTR; @@ -877,6 +880,9 @@ static init_fnc_t init_sequence_r[] = { #endif #if defined(CONFIG_PRAM) initr_mem, +#endif +#ifdef CONFIG_EFI_SETUP_EARLY + (init_fnc_t)efi_init_obj_list, #endif run_main_loop, }; diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index bad1a29ba804..cbd8fe8c0ad2 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -27,6 +27,10 @@ config EFI_LOADER if EFI_LOADER +config EFI_SETUP_EARLY + bool + default n + choice prompt "Store for non-volatile UEFI variables" default EFI_VARIABLE_FILE_STORE From patchwork Mon Sep 7 05:34:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358581 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=LFzm5Qr+; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlHBF1Bnfz9sSn for ; Mon, 7 Sep 2020 15:38:13 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 0D556824F6; Mon, 7 Sep 2020 07:36:35 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="LFzm5Qr+"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 94A22824D7; Mon, 7 Sep 2020 07:36:15 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1041.google.com (mail-pj1-x1041.google.com [IPv6:2607:f8b0:4864:20::1041]) (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 8C0FA824C9 for ; Mon, 7 Sep 2020 07:35:57 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pj1-x1041.google.com with SMTP id b16so6137875pjp.0 for ; Sun, 06 Sep 2020 22:35:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=DCcGfqr5MYYQCRkQTNmZjCmHMsSXVjigLUWJwnUQhnc=; b=LFzm5Qr+CrPS/jtX33Z8PwpWfJa9UyYi4E2b8KseKKg9+YfyZ+PTyU4Mtmzw03mjQF vf6gFLmyxENOdEKAPtXK/qafUP5nggAT5zn0AkXgNeH2jabHveYfF+7A0ZpL4tKNLRzO YhcPmwB6+Qk0kygvsXqhWA9HOdz4Q5OPxERi30rz7d3PQR6MRHJFrAxWMs72IuVYkHuR ufyL8GJCTHZ1gTG9RBgakDutabzm9n/xKsV4gPZpTgo0Lp2Tsaa8+kQF794a+pH3ipHi rRCOqnpVfTf4UYloYIZEUC3e20/jLnTHWa7ZW4y9EhlTA0m8n2w/mNXSIRK6yECr1W+z dGfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=DCcGfqr5MYYQCRkQTNmZjCmHMsSXVjigLUWJwnUQhnc=; b=YaNMidnHFfpwXeVcuFVfPbVqQbn892D6CBNjKRMO+738c5NMeWhPNrbqM6DNbHKUeo Iusfl3rZcgIISy9DBWjTrZ30igQq++EdHqQdGbI94iiv+cHy08na6YHovH0w6AeVE3jl HzBDkrhRP5cQj7aS4a80m1aU+UZXczQ5AcuQ9hsd7GyUOmEsABsgxGlotpit5d2mCaCY TreSlcHvuO+Ni6wvGFNj5Q4xxCpGIOk808eQgFGq3mUk1PRUwvDZNUNd60rJXu9S1l1e aRyNLXVVUrv0eWCf27ZwfdSdKCgJCB7DRaF6/U8Kufa3w7XZZwM/5JrI10n1N05a30om PYOQ== X-Gm-Message-State: AOAM531/Sx1+Eh0JvpMZW1xJBVVNP66r4ZN/LzyOO/To4UgbplBgeIdk wJJdzSOrKyVOqlQBNYXCojH09Q== X-Google-Smtp-Source: ABdhPJyUHh5Yp9jQXKtDlZA7Ku4I4vlBH3VCqupCwum5sMASizcPkb3x9soH5HMgt9w+rHPRJ2+c/A== X-Received: by 2002:a17:902:968d:: with SMTP id n13mr18365341plp.260.1599456955884; Sun, 06 Sep 2020 22:35:55 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.35.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:35:55 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 06/17] efi_loader: add efi_create_indexed_name() Date: Mon, 7 Sep 2020 14:34:15 +0900 Message-Id: <20200907053426.1675646-7-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean This function will be used from several places in UEFI subsystem to generate some specific form of utf-16 variable name. For example, L"Capsule0001" Signed-off-by: AKASHI Takahiro --- include/efi_loader.h | 3 +++ lib/efi_loader/efi_setup.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/include/efi_loader.h b/include/efi_loader.h index 0baa1d2324c8..a4a123c149fd 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -803,6 +803,9 @@ bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp, /* runtime implementation of memcpy() */ void efi_memcpy_runtime(void *dest, const void *src, size_t n); +/* commonly used helper function */ +u16 *efi_create_indexed_name(u16 *buffer, const u16 *name, unsigned int index); + #else /* CONFIG_IS_ENABLED(EFI_LOADER) */ /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */ diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 6196c0a06cd7..a09a7b607e11 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -230,3 +231,32 @@ out: efi_obj_list_initialized = ret; return ret; } + +/** + * efi_create_indexed_name - create a string name with an index + * @buffer: Buffer + * @name: Name string + * @index: Index + * + * Create a utf-16 string with @name, appending @index. + * For example, L"Capsule0001" + * This function is expected to be called only from several places + * in EFI subsystem. A caller should ensure that the buffer have + * enough space for a resulting string, including L"\0". + * No strict check against the length will be done here. + * + * Return: A pointer to the next position after the created string + * in @buffer, or NULL otherwise + */ +u16 *efi_create_indexed_name(u16 *buffer, const u16 *name, unsigned int index) +{ + u16 *p; + char index_buf[5]; + + u16_strcpy(buffer, name); + p = buffer + utf16_strnlen(name, SIZE_MAX); + sprintf(index_buf, "%04X", index); + utf8_utf16_strcpy(&p, index_buf); + + return p; +} From patchwork Mon Sep 7 05:34:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358579 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=O+Oj7kjU; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlH9S4ZZlz9sSP for ; Mon, 7 Sep 2020 15:37:32 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id C58F7824EB; Mon, 7 Sep 2020 07:36:23 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=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="O+Oj7kjU"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 32742824D5; Mon, 7 Sep 2020 07:36:09 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x643.google.com (mail-pl1-x643.google.com [IPv6:2607:f8b0:4864:20::643]) (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 9B301824D2 for ; Mon, 7 Sep 2020 07:36:05 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pl1-x643.google.com with SMTP id q3so2097932plr.13 for ; Sun, 06 Sep 2020 22:36:05 -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=MxuD4NP5njmaefzYfHfwJNSrVFNG71gKqAIIhXPRpVg=; b=O+Oj7kjUb4DGfFVHADi75+F8ujaq3egd1i7w9n6zfD/DWw2ZuHZzWmmVpLzYMkU+HL WCkcsYgf6VbzqM5s36QgfVU8iVwU87AmFUwdopsU+/j5DgZI630Zt2aaj9hJPoKhxFCi YrLe2SxW0o0iqOpRsoD8PLEaNTtjYWtUx87K2uJSA5wfPUKC62nxHsCHSmSB06R2TByb kzWGdBDt6rouL1shpiKEWNwavDodbdfQKs0/MuBMW7X1xcSpDvRL/qBLCuoWsorep2+x w0vlX1LcZg30gOZBh+JjCriv9x9czNZh5rr0t4rxIj2Ihv+N5ZkvvR/S1OoWRt8/HBya ZHQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=MxuD4NP5njmaefzYfHfwJNSrVFNG71gKqAIIhXPRpVg=; b=eDGCXKJ7P+i/6nl71El4m/Z+7Tr0fQfuio31ZkjAeutYo/KX0hbs6Kngx5aI1ajnjF rylL2fsOmyZBySjkoqzgrnVEU22h6BgrU0AKKsvz2tGdJYBDYyGcanH3aSVYO17dWZ8d fVG8k9iNUd82nZXAK7hpbY4zVZ2OObYa+7CnsXEwX+ANRhACDPaiHZ7z1WXSQDhngQSP zC7NzF/4me5KPjWE/Pz21WK3bdIKOzcSxESTbQ8X2d8t7ihiyf8/Z/Zwz96oqnGevv9y CBLj9nVabRo9yIigvw2m7fa16OFjuKjBsMjVIr45ezU6jwmeObmCXoEvAQLhotWxQuLA 0Cdg== X-Gm-Message-State: AOAM531ZJ/8dTY0AV28fzLg1KNRr8WcwoQpLBXYlpzOiwK9kwJVCctTC 6fc4mgM53w+OJ67Xtdryi+6+Yw== X-Google-Smtp-Source: ABdhPJxVW2+fxEv/oqjDdkjRRWiXyOnZhCmHXe8f2oDRu9aoO5W9lXEH/TEEnEcJTsrUTDNQsOBOpg== X-Received: by 2002:a17:90a:aa89:: with SMTP id l9mr15812705pjq.226.1599456959040; Sun, 06 Sep 2020 22:35:59 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.35.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:35:58 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 07/17] efi_loader: define UpdateCapsule api Date: Mon, 7 Sep 2020 14:34:16 +0900 Message-Id: <20200907053426.1675646-8-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean In this commit, skeleton functions for capsule-related API's are added under CONFIG_EFI_UPDATE_CAPSULE configuration. Detailed implementation for a specific capsule type will be added in the succeeding patches. Signed-off-by: AKASHI Takahiro --- include/efi_api.h | 12 +++ include/efi_loader.h | 13 +++ lib/efi_loader/Kconfig | 11 +++ lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_capsule.c | 165 +++++++++++++++++++++++++++++++++++ lib/efi_loader/efi_runtime.c | 104 ++++++++++++---------- lib/efi_loader/efi_setup.c | 64 +++++++++++--- 7 files changed, 316 insertions(+), 54 deletions(-) create mode 100644 lib/efi_loader/efi_capsule.c diff --git a/include/efi_api.h b/include/efi_api.h index 5744f6aed86d..c128a0a66ce8 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -217,6 +217,10 @@ enum efi_reset_type { #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000 #define CAPSULE_FLAGS_INITIATE_RESET 0x00040000 +#define EFI_CAPSULE_REPORT_GUID \ + EFI_GUID(0x39b68c46, 0xf7fb, 0x441b, 0xb6, 0xec, \ + 0x16, 0xb0, 0xf6, 0x98, 0x21, 0xf3) + struct efi_capsule_header { efi_guid_t capsule_guid; u32 header_size; @@ -224,6 +228,14 @@ struct efi_capsule_header { u32 capsule_image_size; } __packed; +struct efi_capsule_result_variable_header { + u32 variable_total_size; + u32 reserved; + efi_guid_t capsule_guid; + struct efi_time capsule_processed; + efi_status_t capsule_status; +} __packed; + #define EFI_RT_SUPPORTED_GET_TIME 0x0001 #define EFI_RT_SUPPORTED_SET_TIME 0x0002 #define EFI_RT_SUPPORTED_GET_WAKEUP_TIME 0x0004 diff --git a/include/efi_loader.h b/include/efi_loader.h index a4a123c149fd..ca50e1c2a18b 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -208,6 +208,8 @@ extern const efi_guid_t efi_guid_cert_type_pkcs7; /* GUID of RNG protocol */ extern const efi_guid_t efi_guid_rng_protocol; +/* GUID of capsule update result */ +extern const efi_guid_t efi_guid_capsule_report; extern unsigned int __efi_runtime_start, __efi_runtime_stop; extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; @@ -806,6 +808,17 @@ void efi_memcpy_runtime(void *dest, const void *src, size_t n); /* commonly used helper function */ u16 *efi_create_indexed_name(u16 *buffer, const u16 *name, unsigned int index); +/* Capsule update */ +efi_status_t EFIAPI efi_update_capsule( + struct efi_capsule_header **capsule_header_array, + efi_uintn_t capsule_count, + u64 scatter_gather_list); +efi_status_t EFIAPI efi_query_capsule_caps( + struct efi_capsule_header **capsule_header_array, + efi_uintn_t capsule_count, + u64 *maximum_capsule_size, + u32 *reset_type); + #else /* CONFIG_IS_ENABLED(EFI_LOADER) */ /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */ diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index cbd8fe8c0ad2..ee9ebe348ad9 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -93,6 +93,17 @@ config EFI_SET_TIME Provide the SetTime() runtime service at boottime. This service can be used by an EFI application to adjust the real time clock. +config EFI_HAVE_CAPSULE_SUPPORT + bool + +config EFI_RUNTIME_UPDATE_CAPSULE + bool "UpdateCapsule() runtime service" + default n + select EFI_HAVE_CAPSULE_SUPPORT + help + Select this option if you want to use UpdateCapsule and + QueryCapsuleCapabilities API's. + config EFI_DEVICE_PATH_TO_TEXT bool "Device path to text protocol" default y diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 9bad1d159b03..c7d231f0e57d 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -23,6 +23,7 @@ endif obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o obj-y += efi_bootmgr.o obj-y += efi_boottime.o +obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o obj-y += efi_console.o obj-y += efi_device_path.o obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c new file mode 100644 index 000000000000..02a8435cd3d1 --- /dev/null +++ b/lib/efi_loader/efi_capsule.c @@ -0,0 +1,165 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * EFI Capsule + * + * Copyright (c) 2018 Linaro Limited + * Author: AKASHI Takahiro + */ + +#include +#include +#include +#include +#include +#include + +const efi_guid_t efi_guid_capsule_report = EFI_CAPSULE_REPORT_GUID; + +/** + * get_last_capsule - get the last capsule index + * + * Retrieve the index of the capsule invoked last time from "CapsuleLast" + * variable. + * + * Return: + * * > 0 - the last capsule index invoked + * * 0xffff - on error, or no capsule invoked yet + */ +static __maybe_unused unsigned int get_last_capsule(void) +{ + u16 value16[11]; /* "CapsuleXXXX": non-null-terminated */ + char value[11], *p; + efi_uintn_t size; + unsigned long index = 0xffff; + efi_status_t ret; + + size = sizeof(value16); + ret = efi_get_variable_int(L"CapsuleLast", &efi_guid_capsule_report, + NULL, &size, value16, NULL); + if (ret != EFI_SUCCESS || u16_strncmp(value16, L"Capsule", 7)) + goto err; + + p = value; + utf16_utf8_strcpy(&p, value16); + strict_strtoul(&value[7], 16, &index); +err: + return index; +} + +/** + * set_capsule_result - set a result variable + * @capsule: Capsule + * @return_status: Return status + * + * Create and set a result variable, "CapsuleXXXX", for the capsule, + * @capsule. + */ +static __maybe_unused +void set_capsule_result(int index, struct efi_capsule_header *capsule, + efi_status_t return_status) +{ + u16 variable_name16[12]; + struct efi_capsule_result_variable_header result; + struct efi_time time; + efi_status_t ret; + + efi_create_indexed_name(variable_name16, L"Capsule", index); + + result.variable_total_size = sizeof(result); + result.capsule_guid = capsule->capsule_guid; + ret = EFI_CALL((*efi_runtime_services.get_time)(&time, NULL)); + if (ret == EFI_SUCCESS) + memcpy(&result.capsule_processed, &time, sizeof(time)); + else + memset(&result.capsule_processed, 0, sizeof(time)); + result.capsule_status = return_status; + ret = efi_set_variable(variable_name16, &efi_guid_capsule_report, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(result), &result); + if (ret) + printf("EFI: creating %ls failed\n", variable_name16); +} + +/** + * efi_update_capsule() - process information from operating system + * @capsule_header_array: Array of virtual address pointers + * @capsule_count: Number of pointers in capsule_header_array + * @scatter_gather_list: Array of physical address pointers + * + * This function implements the UpdateCapsule() runtime service. + * + * See the Unified Extensible Firmware Interface (UEFI) specification for + * details. + * + * Return: status code + */ +efi_status_t EFIAPI efi_update_capsule( + struct efi_capsule_header **capsule_header_array, + efi_uintn_t capsule_count, + u64 scatter_gather_list) +{ + struct efi_capsule_header *capsule; + unsigned int i; + efi_status_t ret; + + EFI_ENTRY("%p, %lu, %llu\n", capsule_header_array, capsule_count, + scatter_gather_list); + + if (!capsule_count) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + + ret = EFI_UNSUPPORTED; + for (i = 0, capsule = *capsule_header_array; i < capsule_count; + i++, capsule = *(++capsule_header_array)) { + } +out: + return EFI_EXIT(ret); +} + +/** + * efi_query_capsule_caps() - check if capsule is supported + * @capsule_header_array: Array of virtual pointers + * @capsule_count: Number of pointers in capsule_header_array + * @maximum_capsule_size: Maximum capsule size + * @reset_type: Type of reset needed for capsule update + * + * This function implements the QueryCapsuleCapabilities() runtime service. + * + * See the Unified Extensible Firmware Interface (UEFI) specification for + * details. + * + * Return: status code + */ +efi_status_t EFIAPI efi_query_capsule_caps( + struct efi_capsule_header **capsule_header_array, + efi_uintn_t capsule_count, + u64 *maximum_capsule_size, + u32 *reset_type) +{ + struct efi_capsule_header *capsule __attribute__((unused)); + unsigned int i; + efi_status_t ret; + + EFI_ENTRY("%p, %lu, %p, %p\n", capsule_header_array, capsule_count, + maximum_capsule_size, reset_type); + + if (!maximum_capsule_size) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + + *maximum_capsule_size = U64_MAX; + *reset_type = EFI_RESET_COLD; + + ret = EFI_SUCCESS; + for (i = 0, capsule = *capsule_header_array; i < capsule_count; + i++, capsule = *(++capsule_header_array)) { + /* TODO */ + } +out: + return EFI_EXIT(ret); +} diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c index dea2b4e5eeab..58b37200fc28 100644 --- a/lib/efi_loader/efi_runtime.c +++ b/lib/efi_loader/efi_runtime.c @@ -133,6 +133,10 @@ efi_status_t efi_init_runtime_supported(void) #ifdef CONFIG_EFI_HAVE_RUNTIME_RESET rt_table->runtime_services_supported |= EFI_RT_SUPPORTED_RESET_SYSTEM; #endif + if (IS_ENABLED(CONFIG_EFI_RUNTIME_UPDATE_CAPSULE)) + rt_table->runtime_services_supported |= + (EFI_RT_SUPPORTED_UPDATE_CAPSULE | + EFI_RT_SUPPORTED_QUERY_CAPSULE_CAPABILITIES); ret = efi_install_configuration_table(&efi_rt_properties_table_guid, rt_table); @@ -435,6 +439,50 @@ efi_status_t __weak __efi_runtime EFIAPI efi_set_time(struct efi_time *time) return EFI_UNSUPPORTED; } +/** + * efi_update_capsule_unsupported() - process information from operating system + * + * This function implements the UpdateCapsule() runtime service. + * + * See the Unified Extensible Firmware Interface (UEFI) specification for + * details. + * + * @capsule_header_array: pointer to array of virtual pointers + * @capsule_count: number of pointers in capsule_header_array + * @scatter_gather_list: pointer to array of physical pointers + * Returns: status code + */ +efi_status_t __efi_runtime EFIAPI efi_update_capsule_unsupported( + struct efi_capsule_header **capsule_header_array, + efi_uintn_t capsule_count, + u64 scatter_gather_list) +{ + return EFI_UNSUPPORTED; +} + +/** + * efi_query_capsule_caps_unsupported() - check if capsule is supported + * + * This function implements the QueryCapsuleCapabilities() runtime service. + * + * See the Unified Extensible Firmware Interface (UEFI) specification for + * details. + * + * @capsule_header_array: pointer to array of virtual pointers + * @capsule_count: number of pointers in capsule_header_array + * @maximum_capsule_size: maximum capsule size + * @reset_type: type of reset needed for capsule update + * Returns: status code + */ +efi_status_t __efi_runtime EFIAPI efi_query_capsule_caps_unsupported( + struct efi_capsule_header **capsule_header_array, + efi_uintn_t capsule_count, + u64 *maximum_capsule_size, + u32 *reset_type) +{ + return EFI_UNSUPPORTED; +} + /** * efi_is_runtime_service_pointer() - check if pointer points to runtime table * @@ -458,6 +506,13 @@ void efi_runtime_detach(void) efi_runtime_services.reset_system = efi_reset_system; efi_runtime_services.get_time = efi_get_time; efi_runtime_services.set_time = efi_set_time; + if (IS_ENABLED(CONFIG_EFI_RUNTIME_UPDATE_CAPSULE)) { + /* won't support at runtime */ + efi_runtime_services.update_capsule = + efi_update_capsule_unsupported; + efi_runtime_services.query_capsule_caps = + efi_query_capsule_caps_unsupported; + } /* Update CRC32 */ efi_update_table_header_crc32(&efi_runtime_services.hdr); @@ -866,50 +921,6 @@ static efi_status_t __efi_runtime EFIAPI efi_unimplemented(void) return EFI_UNSUPPORTED; } -/** - * efi_update_capsule() - process information from operating system - * - * This function implements the UpdateCapsule() runtime service. - * - * See the Unified Extensible Firmware Interface (UEFI) specification for - * details. - * - * @capsule_header_array: pointer to array of virtual pointers - * @capsule_count: number of pointers in capsule_header_array - * @scatter_gather_list: pointer to arry of physical pointers - * Returns: status code - */ -efi_status_t __efi_runtime EFIAPI efi_update_capsule( - struct efi_capsule_header **capsule_header_array, - efi_uintn_t capsule_count, - u64 scatter_gather_list) -{ - return EFI_UNSUPPORTED; -} - -/** - * efi_query_capsule_caps() - check if capsule is supported - * - * This function implements the QueryCapsuleCapabilities() runtime service. - * - * See the Unified Extensible Firmware Interface (UEFI) specification for - * details. - * - * @capsule_header_array: pointer to array of virtual pointers - * @capsule_count: number of pointers in capsule_header_array - * @maximum_capsule_size: maximum capsule size - * @reset_type: type of reset needed for capsule update - * Returns: status code - */ -efi_status_t __efi_runtime EFIAPI efi_query_capsule_caps( - struct efi_capsule_header **capsule_header_array, - efi_uintn_t capsule_count, - u64 *maximum_capsule_size, - u32 *reset_type) -{ - return EFI_UNSUPPORTED; -} - struct efi_runtime_services __efi_runtime_data efi_runtime_services = { .hdr = { .signature = EFI_RUNTIME_SERVICES_SIGNATURE, @@ -927,7 +938,12 @@ struct efi_runtime_services __efi_runtime_data efi_runtime_services = { .set_variable = efi_set_variable, .get_next_high_mono_count = (void *)&efi_unimplemented, .reset_system = &efi_reset_system_boottime, +#ifdef CONFIG_EFI_RUNTIME_UPDATE_CAPSULE .update_capsule = efi_update_capsule, .query_capsule_caps = efi_query_capsule_caps, +#else + .update_capsule = efi_update_capsule_unsupported, + .query_capsule_caps = efi_query_capsule_caps_unsupported, +#endif .query_variable_info = efi_query_variable_info, }; diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index a09a7b607e11..75926c77e61d 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -101,9 +101,9 @@ static efi_status_t efi_init_secure_boot(void) ret = efi_set_variable_int(L"SignatureSupport", &efi_global_variable_guid, + EFI_VARIABLE_READ_ONLY | EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS | - EFI_VARIABLE_READ_ONLY, + EFI_VARIABLE_RUNTIME_ACCESS, sizeof(signature_types), &signature_types, false); if (ret != EFI_SUCCESS) @@ -118,6 +118,53 @@ static efi_status_t efi_init_secure_boot(void) } #endif /* CONFIG_EFI_SECURE_BOOT */ +/** + * efi_init_capsule - initialize capsule update state + * + * Return: status code + */ +static efi_status_t efi_init_capsule(void) +{ + efi_status_t ret = EFI_SUCCESS; + + if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_UPDATE)) { + ret = efi_set_variable_int(L"CapsuleMax", + &efi_guid_capsule_report, + EFI_VARIABLE_READ_ONLY | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + 22, L"CapsuleFFFF", false); + if (ret != EFI_SUCCESS) + printf("EFI: cannot initialize CapsuleMax variable\n"); + } + + return ret; +} + +/** + * efi_init_os_indications() - indicate supported features for OS requests + * + * Set the OsIndicationsSupported variable. + * + * Return: status code + */ +static efi_status_t efi_init_os_indications(void) +{ + u64 os_indications_supported = 0; + + if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)) + os_indications_supported |= + EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED; + + return efi_set_variable_int(L"OsIndicationsSupported", + &efi_global_variable_guid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_READ_ONLY, + sizeof(os_indications_supported), + &os_indications_supported, false); +} + /** * efi_init_obj_list() - Initialize and populate EFI object list * @@ -125,7 +172,6 @@ static efi_status_t efi_init_secure_boot(void) */ efi_status_t efi_init_obj_list(void) { - u64 os_indications_supported = 0; /* None */ efi_status_t ret = EFI_SUCCESS; /* Initialize once only */ @@ -163,13 +209,7 @@ efi_status_t efi_init_obj_list(void) goto out; /* Indicate supported features */ - ret = efi_set_variable_int(L"OsIndicationsSupported", - &efi_global_variable_guid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS | - EFI_VARIABLE_READ_ONLY, - sizeof(os_indications_supported), - &os_indications_supported, false); + ret = efi_init_os_indications(); if (ret != EFI_SUCCESS) goto out; @@ -222,6 +262,10 @@ efi_status_t efi_init_obj_list(void) if (ret != EFI_SUCCESS) goto out; + ret = efi_init_capsule(); + if (ret != EFI_SUCCESS) + goto out; + /* Initialize EFI runtime services */ ret = efi_reset_system_init(); if (ret != EFI_SUCCESS) From patchwork Mon Sep 7 05:34:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358584 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=A7Gs/Pyx; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlHCW16Vkz9sSP for ; Mon, 7 Sep 2020 15:39:19 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 0648582512; Mon, 7 Sep 2020 07:36:47 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="A7Gs/Pyx"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id CB1F0824EB; Mon, 7 Sep 2020 07:36:22 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,T_SPF_HELO_TEMPERROR,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from mail-pl1-x643.google.com (mail-pl1-x643.google.com [IPv6:2607:f8b0:4864:20::643]) (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 BF9C4824AE for ; Mon, 7 Sep 2020 07:36:08 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pl1-x643.google.com with SMTP id j7so1142877plk.11 for ; Sun, 06 Sep 2020 22:36:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=anrEO6+RgYS2kk07tY26R/81TBy0o2kchlAn9HN2Gv0=; b=A7Gs/PyxTGEY2dbgu+CmLp2BMN3pEvxiUCWqmJdRmMw9GsRm130rVW9AnwW1yFJUIi nonHH9t4YUJIGKgoQ1EFPKgksfbB6rHuQL5qZ3N2+2YJJ+yIYpwi+CccAU4iSWAX0iBR gxAkTOfJPwlZg04KYt5QK0rJcMxijoyqWFwF7PYIYO+VW2c1ckiwOMllhFddJvqeliXd dSEB/Dibse5fCg8Sjnw1L1e7/jjBHOEtLS+HCX7EBMBzTY9vC6tl9kPiowo3I23ujbye 1tq1zttyMUQ4GJ9AZKF+8lBLaH6TYGw/BgUE71qx9d55x7DcG9ORjcrlukiZcU+hmTDH rYUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=anrEO6+RgYS2kk07tY26R/81TBy0o2kchlAn9HN2Gv0=; b=Bei0ECE/DAUBXVvGQ7f/7e25Ii/U6cY3FQroXQp1UfhmsFgMq7WKykg7RLeylvA5CY PqOd6UJ1mT0I73AVbr6TwNznaFIYNdFSzspg2vTemFgS6BYMd3Y+n97SekTcH40ekWfL 68vmNX8/tsRzo9qUj8s7g9PKuvhHSPI7yU+dQ4Y/1a1amNz9PwGeVSIxVM3JvC2i8gGP iwLhJWgwI0eJWFa4gzR98bM57wZGTvKVc0NqmzHMLQjWC8bkR0khTre01VB0xeCnDoXH t2h7eGAUfGqiQG9Ylx30tEDVIzY4X4XGiOnGzugvi6Fk93wAfGR9UBI+SUuFPozOyibl XU0w== X-Gm-Message-State: AOAM532lAWF16y6sFAFeRGr4QwiUJjvRD+0APTwKRFqK8hjg1FYBZbqr gSKiPcacVnfTg4bEwmYYfCd+KQ== X-Google-Smtp-Source: ABdhPJzsW/U5Ucmxnbh3rIK+ZeM58Ed4UCvrS+DdwbdHXrKLPdu39BqqDykuwsfP/ztsxWy6xSAbuA== X-Received: by 2002:a17:90b:1245:: with SMTP id gx5mr17717082pjb.193.1599456962144; Sun, 06 Sep 2020 22:36:02 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.35.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:36:01 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 08/17] efi_loader: capsule: add capsule_on_disk support Date: Mon, 7 Sep 2020 14:34:17 +0900 Message-Id: <20200907053426.1675646-9-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean Capsule data can be loaded into the system either via UpdateCapsule runtime service or files on a file system (of boot device). The latter case is called "capsules on disk", and actual updates will take place at the next boot time. In this commit, we will support capsule on disk mechanism. Please note that U-Boot itself has no notion of "boot device" and all the capsule files to be executed will be detected only if they are located in a specific directory, \EFI\UpdateCapsule, on a device that is identified as a boot device by "BootXXXX" variables. Signed-off-by: AKASHI Takahiro --- common/main.c | 4 + include/efi_loader.h | 9 + lib/efi_loader/Kconfig | 22 ++ lib/efi_loader/efi_capsule.c | 498 +++++++++++++++++++++++++++++++++++ lib/efi_loader/efi_setup.c | 8 + 5 files changed, 541 insertions(+) diff --git a/common/main.c b/common/main.c index 4b3cd302c3e2..ae5bcdb32f8b 100644 --- a/common/main.c +++ b/common/main.c @@ -16,6 +16,7 @@ #include #include #include +#include static void run_preboot_environment_command(void) { @@ -53,6 +54,9 @@ void main_loop(void) if (IS_ENABLED(CONFIG_UPDATE_TFTP)) update_tftp(0UL, NULL, NULL); + if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY)) + efi_launch_capsules(); + s = bootdelay_process(); if (cli_process_fdt(&s)) cli_secure_boot_cmd(s); diff --git a/include/efi_loader.h b/include/efi_loader.h index ca50e1c2a18b..157c560034fc 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -819,6 +819,11 @@ efi_status_t EFIAPI efi_query_capsule_caps( u64 *maximum_capsule_size, u32 *reset_type); +#define EFI_CAPSULE_DIR L"\\EFI\\UpdateCapsule\\" + +/* Hook at initialization */ +efi_status_t efi_launch_capsules(void); + #else /* CONFIG_IS_ENABLED(EFI_LOADER) */ /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */ @@ -835,6 +840,10 @@ static inline void efi_set_bootdev(const char *dev, const char *devnr, const char *path) { } static inline void efi_net_set_dhcp_ack(void *pkt, int len) { } static inline void efi_print_image_infos(void *pc) { } +static inline efi_status_t efi_launch_capsules(void) +{ + return EFI_SUCCESS; +} #endif /* CONFIG_IS_ENABLED(EFI_LOADER) */ diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index ee9ebe348ad9..6e35cbe64c7f 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -104,6 +104,28 @@ config EFI_RUNTIME_UPDATE_CAPSULE Select this option if you want to use UpdateCapsule and QueryCapsuleCapabilities API's. +config EFI_CAPSULE_ON_DISK + bool "Enable capsule-on-disk support" + select EFI_HAVE_CAPSULE_SUPPORT + default n + help + Select this option if you want to use capsule-on-disk feature, + that is, capsules can be fetched and executed from files + under a specific directory on UEFI system partition instead of + via UpdateCapsule API. + +config EFI_CAPSULE_ON_DISK_EARLY + bool "Initiate capsule-on-disk at U-Boot boottime" + depends on EFI_CAPSULE_ON_DISK + default y + select EFI_SETUP_EARLY + help + Normally, without this option enabled, capsules will be + executed only at the first time of invoking one of efi command. + If this option is enabled, capsules will be enforced to be + executed as part of U-Boot initialisation so that they will + surely take place whatever is set to distro_bootcmd. + config EFI_DEVICE_PATH_TO_TEXT bool "Device path to text protocol" default y diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 02a8435cd3d1..2259bfbf3d19 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -11,10 +11,16 @@ #include #include #include +#include #include const efi_guid_t efi_guid_capsule_report = EFI_CAPSULE_REPORT_GUID; +#ifdef CONFIG_EFI_CAPSULE_ON_DISK +/* for file system access */ +static struct efi_file_handle *bootdev_root; +#endif + /** * get_last_capsule - get the last capsule index * @@ -163,3 +169,495 @@ efi_status_t EFIAPI efi_query_capsule_caps( out: return EFI_EXIT(ret); } + +#ifdef CONFIG_EFI_CAPSULE_ON_DISK +/** + * get_dp_device - retrieve a device path from boot variable + * @boot_var: Boot variable name + * @device_dp Device path + * + * Retrieve a device patch from boot variable, @boot_var. + * + * Return: status code + */ +static efi_status_t get_dp_device(u16 *boot_var, + struct efi_device_path **device_dp) +{ + void *buf = NULL; + efi_uintn_t size; + struct efi_load_option lo; + struct efi_device_path *file_dp; + efi_status_t ret; + + size = 0; + ret = efi_get_variable_int(boot_var, &efi_global_variable_guid, + NULL, &size, NULL, NULL); + if (ret == EFI_BUFFER_TOO_SMALL) { + buf = malloc(size); + if (!buf) + return EFI_OUT_OF_RESOURCES; + ret = efi_get_variable_int(boot_var, &efi_global_variable_guid, + NULL, &size, buf, NULL); + } + if (ret != EFI_SUCCESS) + return ret; + + efi_deserialize_load_option(&lo, buf, &size); + + if (lo.attributes & LOAD_OPTION_ACTIVE) { + efi_dp_split_file_path(lo.file_path, device_dp, &file_dp); + efi_free_pool(file_dp); + + ret = EFI_SUCCESS; + } else { + ret = EFI_NOT_FOUND; + } + + free(buf); + + return ret; +} + +/** + * device_is_present_and_system_part - check if a device exists + * @dp Device path + * + * Check if a device pointed to by the device path, @dp, exists and is + * located in UEFI system partition. + * + * Return: true - yes, false - no + */ +static bool device_is_present_and_system_part(struct efi_device_path *dp) +{ + efi_handle_t handle; + + handle = efi_dp_find_obj(dp, NULL); + if (!handle) + return false; + + return efi_disk_is_system_part(handle); +} + +/** + * find_boot_device - identify the boot device + * + * Identify the boot device from boot-related variables as UEFI + * specification describes and put its handle into bootdev_root. + * + * Return: status code + */ +static efi_status_t find_boot_device(void) +{ + char boot_var[9]; + u16 boot_var16[9], *p, bootnext, *boot_order = NULL; + efi_uintn_t size; + int i, num; + struct efi_simple_file_system_protocol *volume; + struct efi_device_path *boot_dev = NULL; + efi_status_t ret; + + /* find active boot device in BootNext */ + bootnext = 0; + size = sizeof(bootnext); + ret = efi_get_variable_int(L"BootNext", + (efi_guid_t *)&efi_global_variable_guid, + NULL, &size, &bootnext, NULL); + if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) { + /* BootNext does exist here */ + if (ret == EFI_BUFFER_TOO_SMALL || size != sizeof(u16)) { + printf("BootNext must be 16-bit integer\n"); + goto skip; + } + sprintf((char *)boot_var, "Boot%04X", bootnext); + p = boot_var16; + utf8_utf16_strcpy(&p, boot_var); + + ret = get_dp_device(boot_var16, &boot_dev); + if (ret == EFI_SUCCESS) { + if (device_is_present_and_system_part(boot_dev)) { + goto out; + } else { + efi_free_pool(boot_dev); + boot_dev = NULL; + } + } + } + +skip: + /* find active boot device in BootOrder */ + size = 0; + ret = efi_get_variable_int(L"BootOrder", &efi_global_variable_guid, + NULL, &size, NULL, NULL); + if (ret == EFI_BUFFER_TOO_SMALL) { + boot_order = malloc(size); + if (!boot_order) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + ret = efi_get_variable_int(L"BootOrder", + &efi_global_variable_guid, + NULL, &size, boot_order, NULL); + } + if (ret != EFI_SUCCESS) + goto out; + + /* check in higher order */ + num = size / sizeof(u16); + for (i = 0; i < num; i++) { + sprintf((char *)boot_var, "Boot%04X", boot_order[i]); + p = boot_var16; + utf8_utf16_strcpy(&p, boot_var); + ret = get_dp_device(boot_var16, &boot_dev); + if (ret != EFI_SUCCESS) + continue; + + if (device_is_present_and_system_part(boot_dev)) + break; + + efi_free_pool(boot_dev); + boot_dev = NULL; + } +out: + if (boot_dev) { + u16 *path_str; + + path_str = efi_dp_str(boot_dev); + EFI_PRINT("EFI Capsule: bootdev is %ls\n", path_str); + efi_free_pool(path_str); + + volume = efi_fs_from_path(boot_dev); + if (!volume) + ret = EFI_DEVICE_ERROR; + else + ret = EFI_CALL(volume->open_volume(volume, + &bootdev_root)); + efi_free_pool(boot_dev); + } else { + ret = EFI_NOT_FOUND; + } + free(boot_order); + + return ret; +} + +/** + * efi_capsule_scan_dir - traverse a capsule directory in boot device + * @files: Array of file names + * @num: Number of elements in @files + * + * Traverse a capsule directory in boot device. + * Called by initialization code, and returns an array of capsule file + * names in @files. + * + * Return: status code + */ +static efi_status_t efi_capsule_scan_dir(u16 ***files, unsigned int *num) +{ + struct efi_file_handle *dirh; + struct efi_file_info *dirent; + efi_uintn_t dirent_size, tmp_size; + unsigned int count; + u16 **tmp_files; + efi_status_t ret; + + ret = find_boot_device(); + if (ret == EFI_NOT_FOUND) { + EFI_PRINT("EFI Capsule: bootdev is not set\n"); + *num = 0; + return EFI_SUCCESS; + } else if (ret != EFI_SUCCESS) { + return EFI_DEVICE_ERROR; + } + + /* count capsule files */ + ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh, + EFI_CAPSULE_DIR, + EFI_FILE_MODE_READ, 0)); + if (ret != EFI_SUCCESS) { + *num = 0; + return EFI_SUCCESS; + } + + dirent_size = 256; + dirent = malloc(dirent_size); + if (!dirent) + return EFI_OUT_OF_RESOURCES; + + count = 0; + while (1) { + tmp_size = dirent_size; + ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent)); + if (ret == EFI_BUFFER_TOO_SMALL) { + dirent = realloc(dirent, tmp_size); + if (!dirent) { + ret = EFI_OUT_OF_RESOURCES; + goto err; + } + dirent_size = tmp_size; + ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent)); + } + if (ret != EFI_SUCCESS) + goto err; + if (!tmp_size) + break; + + if (!(dirent->attribute & EFI_FILE_DIRECTORY) && + u16_strcmp(dirent->file_name, L".") && + u16_strcmp(dirent->file_name, L"..")) + count++; + } + + ret = EFI_CALL((*dirh->setpos)(dirh, 0)); + if (ret != EFI_SUCCESS) + goto err; + + /* make a list */ + tmp_files = malloc(count * sizeof(*files)); + if (!tmp_files) { + ret = EFI_OUT_OF_RESOURCES; + goto err; + } + + count = 0; + while (1) { + tmp_size = dirent_size; + ret = EFI_CALL((*dirh->read)(dirh, &tmp_size, dirent)); + if (ret != EFI_SUCCESS) + goto err; + if (!tmp_size) + break; + + if (!(dirent->attribute & EFI_FILE_DIRECTORY) && + u16_strcmp(dirent->file_name, L".") && + u16_strcmp(dirent->file_name, L"..")) + tmp_files[count++] = u16_strdup(dirent->file_name); + } + /* ignore an error */ + EFI_CALL((*dirh->close)(dirh)); + + /* in ascii order */ + /* FIXME: u16 version of strcasecmp */ + qsort(tmp_files, count, sizeof(*tmp_files), + (int (*)(const void *, const void *))strcasecmp); + *files = tmp_files; + *num = count; + ret = EFI_SUCCESS; +err: + free(dirent); + + return ret; +} + +/** + * efi_capsule_read_file - read in a capsule file + * @filename: File name + * @capsule: Pointer to buffer for capsule + * + * Read a capsule file and put its content in @capsule. + * + * Return: status code + */ +static efi_status_t efi_capsule_read_file(const u16 *filename, + struct efi_capsule_header **capsule) +{ + struct efi_file_handle *dirh, *fh; + struct efi_file_info *file_info = NULL; + struct efi_capsule_header *buf = NULL; + efi_uintn_t size; + efi_status_t ret; + + ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh, + EFI_CAPSULE_DIR, + EFI_FILE_MODE_READ, 0)); + if (ret != EFI_SUCCESS) + return ret; + ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename, + EFI_FILE_MODE_READ, 0)); + /* ignore an error */ + EFI_CALL((*dirh->close)(dirh)); + if (ret != EFI_SUCCESS) + return ret; + + /* file size */ + size = 0; + ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid, + &size, file_info)); + if (ret == EFI_BUFFER_TOO_SMALL) { + file_info = malloc(size); + if (!file_info) { + ret = EFI_OUT_OF_RESOURCES; + goto err; + } + ret = EFI_CALL((*fh->getinfo)(fh, &efi_file_info_guid, + &size, file_info)); + } + if (ret != EFI_SUCCESS) + goto err; + size = file_info->file_size; + free(file_info); + buf = malloc(size); + if (!buf) { + ret = EFI_OUT_OF_RESOURCES; + goto err; + } + + /* fetch data */ + ret = EFI_CALL((*fh->read)(fh, &size, buf)); + if (ret == EFI_SUCCESS) { + if (size >= buf->capsule_image_size) { + *capsule = buf; + } else { + free(buf); + ret = EFI_INVALID_PARAMETER; + } + } else { + free(buf); + } +err: + EFI_CALL((*fh->close)(fh)); + + return ret; +} + +/** + * efi_capsule_delete_file - delete a capsule file + * @filename: File name + * + * Delete a capsule file from capsule directory. + * + * Return: status code + */ +static efi_status_t efi_capsule_delete_file(const u16 *filename) +{ + struct efi_file_handle *dirh, *fh; + efi_status_t ret; + + ret = EFI_CALL((*bootdev_root->open)(bootdev_root, &dirh, + EFI_CAPSULE_DIR, + EFI_FILE_MODE_READ, 0)); + if (ret != EFI_SUCCESS) + return ret; + ret = EFI_CALL((*dirh->open)(dirh, &fh, (u16 *)filename, + EFI_FILE_MODE_READ, 0)); + /* ignore an error */ + EFI_CALL((*dirh->close)(dirh)); + + ret = EFI_CALL((*fh->delete)(fh)); + + return ret; +} + +/** + * efi_capsule_scan_done - reset a scan help function + * + * Reset a scan help function + */ +static void efi_capsule_scan_done(void) +{ + EFI_CALL((*bootdev_root->close)(bootdev_root)); + bootdev_root = NULL; +} + +/** + * arch_efi_load_capsule_drivers - initialize capsule drivers + * + * Architecture or board specific initialization routine + * + * Return: status code + */ +efi_status_t __weak arch_efi_load_capsule_drivers(void) +{ + return EFI_SUCCESS; +} + +/** + * efi_launch_capsule - launch capsules + * + * Launch all the capsules in system at boot time. + * Called by efi init code + * + * Return: status codde + */ +efi_status_t efi_launch_capsules(void) +{ + u64 os_indications; + efi_uintn_t size; + struct efi_capsule_header *capsule = NULL; + u16 **files; + unsigned int nfiles, index, i; + u16 variable_name16[12]; + efi_status_t ret; + + size = sizeof(os_indications); + ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid, + NULL, &size, &os_indications, NULL); + if (ret != EFI_SUCCESS || + !(os_indications + & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED)) + return EFI_SUCCESS; + + index = get_last_capsule(); + + /* Load capsule drivers */ + ret = arch_efi_load_capsule_drivers(); + if (ret != EFI_SUCCESS) + return ret; + + /* + * Find capsules on disk. + * All the capsules are collected at the beginning because + * capsule files will be removed instantly. + */ + nfiles = 0; + files = NULL; + ret = efi_capsule_scan_dir(&files, &nfiles); + if (ret != EFI_SUCCESS) + return ret; + if (!nfiles) + return EFI_SUCCESS; + + /* Launch capsules */ + for (i = 0, ++index; i < nfiles; i++, index++) { + EFI_PRINT("capsule from %ls ...\n", files[i]); + if (index > 0xffff) + index = 0; + ret = efi_capsule_read_file(files[i], &capsule); + if (ret == EFI_SUCCESS) { + ret = EFI_CALL(efi_update_capsule(&capsule, 1, 0)); + if (ret != EFI_SUCCESS) + printf("EFI Capsule update failed at %ls\n", + files[i]); + + free(capsule); + } else { + printf("EFI: reading capsule failed: %ls\n", + files[i]); + } + /* create CapsuleXXXX */ + set_capsule_result(index, capsule, ret); + + /* delete a capsule either in case of success or failure */ + ret = efi_capsule_delete_file(files[i]); + if (ret != EFI_SUCCESS) + printf("EFI: deleting a capsule file failed: %ls\n", + files[i]); + } + efi_capsule_scan_done(); + + for (i = 0; i < nfiles; i++) + free(files[i]); + free(files); + + /* CapsuleLast */ + efi_create_indexed_name(variable_name16, L"Capsule", index - 1); + efi_set_variable_int(L"CapsuleLast", &efi_guid_capsule_report, + EFI_VARIABLE_READ_ONLY | + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + 22, variable_name16, false); + + return ret; +} +#endif /* CONFIG_EFI_CAPSULE_ON_DISK */ diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 75926c77e61d..2830a7094489 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -156,6 +156,10 @@ static efi_status_t efi_init_os_indications(void) os_indications_supported |= EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED; + if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK)) + os_indications_supported |= + EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED; + return efi_set_variable_int(L"OsIndicationsSupported", &efi_global_variable_guid, EFI_VARIABLE_BOOTSERVICE_ACCESS | @@ -271,6 +275,10 @@ efi_status_t efi_init_obj_list(void) if (ret != EFI_SUCCESS) goto out; + /* Execute capsules after reboot */ + if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK) && + !IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY)) + ret = efi_launch_capsules(); out: efi_obj_list_initialized = ret; return ret; From patchwork Mon Sep 7 05:34:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358580 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=RhU+2fAt; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlH9r5J2Dz9sSn for ; Mon, 7 Sep 2020 15:37:52 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id BB76C824F0; Mon, 7 Sep 2020 07:36:24 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=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="RhU+2fAt"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 74B07824D5; Mon, 7 Sep 2020 07:36:13 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1044.google.com (mail-pj1-x1044.google.com [IPv6:2607:f8b0:4864:20::1044]) (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 E64F0824D3 for ; Mon, 7 Sep 2020 07:36:06 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pj1-x1044.google.com with SMTP id u3so2691036pjr.3 for ; Sun, 06 Sep 2020 22:36:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=pfzS9a249CGCsTB62oWKa+nEqo4kbxAX5xW5fvW6X+k=; b=RhU+2fAts9l6/ZpY/+9ZOQRwauiaYn5WA3iPbohlfNB3imGuBNNr451QG3NnFlczmh i1iMJmUtpgvOMwBQAJnid1zuIDuh9xmrJQm1Tfp7csMcz/zJZFxlaSWNfSkVobZpXaOa KmQ/mw0InXnfEFw8uamNCG5BvMEIem1laOn78i+HgnWVuJoCOMB922OADSeoQtQWK8Mo fO+/zanofWOGmJeZUU7mxz8Zz4A/ESs3ZOWdHHhBiP64J/F1Dzf1fhmH/pqSttoUWrFX m6MrFj8Kv7mGhkMfM3gqsLuZUyPAwN5NENI6foF6RBw7Zh389ABjaq6pGsJYHgxsImMZ 5HCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pfzS9a249CGCsTB62oWKa+nEqo4kbxAX5xW5fvW6X+k=; b=FgoZR4bbZiglefHUJmTGIzZI2leoBkY62xeV2/qhzO1h+OKEp5T2dXEAgJ9cLflh75 SX4XH42q5Ey41vrAsCioQHmnRJEUlB2m4sRxZ1PjsESTGRiQZ/JGgqSc5Np97IbT3FK9 d+kxjGEKkgre8hUxfgOi44HJEqPhWEVPISLh61pdANwtzbZLTgXEgWyd73s5HwpYNzk6 STKJaJIjMKLC9dbTXEmPAtyMPCIlF/oRAV45sSmgqf1EjSZ29x93G5KQSP0fuCYYyxle RANJxefsbnPcPw4bGy1InX/pX6sYx6//QlS2svfBeV1SJYXJvn4CaiEGPPEtvLMtRPhg PNJQ== X-Gm-Message-State: AOAM530htkaxQFom79V3fDN6VoDfsUyyxPsGxGS2k1CjaND2HdKxEucK nqW2gdnDH1bNjoiZ3zotRcNTvA== X-Google-Smtp-Source: ABdhPJwUvhnTpo+a3tMEW/ie0ryZp0gpW8bVhfC4XqbNSDGqxJy7DqylK9m9zCj6fIbHiYjZkA/oCg== X-Received: by 2002:a17:90a:a787:: with SMTP id f7mr18994001pjq.103.1599456965474; Sun, 06 Sep 2020 22:36:05 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.36.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:36:04 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 09/17] efi_loader: capsule: add memory range capsule definitions Date: Mon, 7 Sep 2020 14:34:18 +0900 Message-Id: <20200907053426.1675646-10-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean Memory range capsule gives us a way to notify that some memory regions should be left untouched across the next reset. See UEFI specification, section 8.5.3. Since how we should handle this kind of capsule is totally up to the system, no implementation will be added in this commit. Signed-off-by: AKASHI Takahiro --- include/efi_api.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/include/efi_api.h b/include/efi_api.h index c128a0a66ce8..7a2a087c60ed 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -221,6 +221,10 @@ enum efi_reset_type { EFI_GUID(0x39b68c46, 0xf7fb, 0x441b, 0xb6, 0xec, \ 0x16, 0xb0, 0xf6, 0x98, 0x21, 0xf3) +#define EFI_MEMORY_RANGE_CAPSULE_GUID \ + EFI_GUID(0xde9f0ec, 0x88b6, 0x428f, 0x97, 0x7a, \ + 0x25, 0x8f, 0x1d, 0xe, 0x5e, 0x72) + struct efi_capsule_header { efi_guid_t capsule_guid; u32 header_size; @@ -236,6 +240,19 @@ struct efi_capsule_result_variable_header { efi_status_t capsule_status; } __packed; +struct efi_memory_range { + efi_physical_addr_t address; + u64 length; +}; + +struct efi_memory_range_capsule { + struct efi_capsule_header *header; + /* EFI_MEMORY_TYPE: 0x80000000-0xFFFFFFFF */ + enum efi_mem_type os_requested_memory_type; + u64 number_of_memory_ranges; + struct efi_memory_range memory_ranges[]; +} __packed; + #define EFI_RT_SUPPORTED_GET_TIME 0x0001 #define EFI_RT_SUPPORTED_SET_TIME 0x0002 #define EFI_RT_SUPPORTED_GET_WAKEUP_TIME 0x0004 From patchwork Mon Sep 7 05:34:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358582 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=bEPqrHPs; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlHBc3T50z9sSP for ; Mon, 7 Sep 2020 15:38:32 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id E7DAD82481; Mon, 7 Sep 2020 07:36:39 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="bEPqrHPs"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id A5AB0824E3; Mon, 7 Sep 2020 07:36:17 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1042.google.com (mail-pj1-x1042.google.com [IPv6:2607:f8b0:4864:20::1042]) (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 06E3B824B1 for ; Mon, 7 Sep 2020 07:36:09 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pj1-x1042.google.com with SMTP id s2so5918963pjr.4 for ; Sun, 06 Sep 2020 22:36: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 :mime-version:content-transfer-encoding; bh=Da2DY5HU7hJsjo0FFM8SkprrSPPm4hQl1Tk/Ru3MqeM=; b=bEPqrHPsVCIxRU8QKhCmbDXMnihcqU+sprR4+ldqPWI7IOjdeCEOTChFRlBfD67k87 4fCGWL3dA9yiwOwSOV5Cu0zQQrYjyzVhCkya6gPC/yvJS4elV6/m3GzE/CvUQ9KtArCn u1CnPPF2crxM12wRCKfjYn8uE8RZBRh3/BjMglTBkcEPIwI2TklG3Adp1/5k+gjF0b9j Pql414m4h8uTSPfbWk/gjunnKOSRRmXd4l5RUHoYTHLLjB8qRISHm/1JDR8GAbCE3G2w UIsj/SMnDb839rur53uBneMKrbxM+cXEucIP+x9OT9/l7f+8ZHMr40XbGMVvj0MI5zzs NSbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Da2DY5HU7hJsjo0FFM8SkprrSPPm4hQl1Tk/Ru3MqeM=; b=izxjdWfkR1FcP85BcjreUqT79vNCnLt4x1AebD3U9NO6xDnrwgS/u/TSQ3SMGUUdvR k+U8cPsBZbpp04uifgTyKrz9IcY2EHGtbKQ9jqC8l4i0GkOoHSt2+UlvE/Zc4Yni7YKD POqXLFnX9DiJkIcic4lhTDFuY4bpxOEIUbrNOP1xhiATdWBwz7rU/yQmCpQmMzAkunSb lcckjeJ+Of8rYtiufSlvpGiUQMJ1aRdKxnovrCVHDq+nheNU70L269Tn5MXuZTiSiY5z byHX1N2yRQFx3BxRg7zfxjCOgwGkAg3FCHSUEuuO0GeQGQta6kSoR44eNjc3QCT8DnxL HWSw== X-Gm-Message-State: AOAM532I5A5xuWWB+Qe6Hbw/o70cXDgZvrXS6kmXSy1A8jC37bT/w/BR xVOER6IfBM1TglSTlSYASR0pSg== X-Google-Smtp-Source: ABdhPJxhQCdHo9fVHM+cu1DyMdFD6BIoIuhjRoPI3rRaRdXh53OTb8UkQZQbMui+2rfF4ajoSnqqJw== X-Received: by 2002:a17:90a:cc17:: with SMTP id b23mr19078877pju.32.1599456968326; Sun, 06 Sep 2020 22:36:08 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.36.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:36:07 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 10/17] efi_loader: capsule: support firmware update Date: Mon, 7 Sep 2020 14:34:19 +0900 Message-Id: <20200907053426.1675646-11-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean A capsule tagged with the guid, EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID, is handled as a firmware update object. What efi_update_capsule() basically does is to load any firmware management protocol (or fmp) drivers contained in a capsule, find out an appropriate fmp driver and then invoke its set_image() interface against each binary in a capsule. In this commit, however, loading drivers is not supported. The result of applying a capsule is set to be stored in "CapsuleXXXX" variable, but its implementation is deferred to a fmp driver. Signed-off-by: AKASHI Takahiro --- include/efi_api.h | 129 +++++++++++++++++++ include/efi_loader.h | 2 + lib/efi_loader/Kconfig | 8 ++ lib/efi_loader/efi_capsule.c | 238 ++++++++++++++++++++++++++++++++++- lib/efi_loader/efi_setup.c | 4 + 5 files changed, 380 insertions(+), 1 deletion(-) diff --git a/include/efi_api.h b/include/efi_api.h index 7a2a087c60ed..966bc6e590bf 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -217,6 +217,9 @@ enum efi_reset_type { #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000 #define CAPSULE_FLAGS_INITIATE_RESET 0x00040000 +#define CAPSULE_SUPPORT_AUTHENTICATION 0x0000000000000001 +#define CAPSULE_SUPPORT_DEPENDENCY 0x0000000000000002 + #define EFI_CAPSULE_REPORT_GUID \ EFI_GUID(0x39b68c46, 0xf7fb, 0x441b, 0xb6, 0xec, \ 0x16, 0xb0, 0xf6, 0x98, 0x21, 0xf3) @@ -225,6 +228,10 @@ enum efi_reset_type { EFI_GUID(0xde9f0ec, 0x88b6, 0x428f, 0x97, 0x7a, \ 0x25, 0x8f, 0x1d, 0xe, 0x5e, 0x72) +#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID \ + EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ + 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) + struct efi_capsule_header { efi_guid_t capsule_guid; u32 header_size; @@ -253,6 +260,33 @@ struct efi_memory_range_capsule { struct efi_memory_range memory_ranges[]; } __packed; +struct efi_firmware_management_capsule_header { + u32 version; + u16 embedded_driver_count; + u16 payload_item_count; + u64 item_offset_list[]; +} __packed; + +struct efi_firmware_management_capsule_image_header { + u32 version; + efi_guid_t update_image_type_id; + u8 update_image_index; + u8 reserved[3]; + u32 update_image_size; + u32 update_vendor_code_size; + u64 update_hardware_instance; + u64 image_capsule_support; +} __packed; + +struct efi_capsule_result_variable_fmp { + u16 version; + u8 payload_index; + u8 update_image_index; + efi_guid_t update_image_type_id; + // u16 capsule_file_name[]; + // u16 capsule_target[]; +} __packed; + #define EFI_RT_SUPPORTED_GET_TIME 0x0001 #define EFI_RT_SUPPORTED_SET_TIME 0x0002 #define EFI_RT_SUPPORTED_GET_WAKEUP_TIME 0x0004 @@ -1808,4 +1842,99 @@ struct efi_signature_list { /* struct efi_signature_data signatures[...][signature_size]; */ } __attribute__((__packed__)); +/* + * Firmware management protocol + */ +#define EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID \ + EFI_GUID(0x86c77a67, 0x0b97, 0x4633, 0xa1, 0x87, \ + 0x49, 0x10, 0x4d, 0x06, 0x85, 0xc7) + +#define IMAGE_ATTRIBUTE_IMAGE_UPDATABLE 0x0000000000000001 +#define IMAGE_ATTRIBUTE_RESET_REQUIRED 0x0000000000000002 +#define IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED 0x0000000000000004 +#define IMAGE_ATTRIBUTE_IN_USE 0x0000000000000008 +#define IMAGE_ATTRIBUTE_UEFI_IMAGE 0x0000000000000010 +#define IMAGE_ATTRIBUTE_DEPENDENCY 0x0000000000000020 + +#define IMAGE_COMPATIBILITY_CHECK_SUPPORTED 0x0000000000000001 + +#define IMAGE_UPDATABLE_VALID 0x0000000000000001 +#define IMAGE_UPDATABLE_INVALID 0x0000000000000002 +#define IMAGE_UPDATABLE_INVALID_TYPE 0x0000000000000004 +#define IMAGE_UPDATABLE_INVALID_OLLD 0x0000000000000008 +#define IMAGE_UPDATABLE_VALID_WITH_VENDOR_CODE 0x0000000000000010 + +#define PACKAGE_ATTRIBUTE_VERSION_UPDATABLE 0x0000000000000001 +#define PACKAGE_ATTRIBUTE_RESET_REQUIRED 0x0000000000000002 +#define PACKAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED 0x0000000000000004 + +#define EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION 4 + +typedef struct efi_firmware_image_dependencies { + u8 dependencies[0]; +} efi_firmware_image_dep_t; + +struct efi_firmware_image_descriptor { + u8 image_index; + efi_guid_t image_type_id; + u64 image_id; + u16 *image_id_name; + u32 version; + u16 *version_name; + efi_uintn_t size; + u64 attributes_supported; + u64 attributes_setting; + u64 compatibilities; + u32 lowest_supported_image_version; + u32 last_attempt_version; + u32 last_attempt_status; + u64 hardware_instance; + efi_firmware_image_dep_t *dependencies; +}; + +struct efi_firmware_management_protocol { + efi_status_t (EFIAPI *get_image_info)( + struct efi_firmware_management_protocol *this, + efi_uintn_t *image_info_size, + struct efi_firmware_image_descriptor *image_info, + u32 *descriptor_version, + u8 *descriptor_count, + efi_uintn_t *descriptor_size, + u32 *package_version, + u16 **package_version_name); + efi_status_t (EFIAPI *get_image)( + struct efi_firmware_management_protocol *this, + u8 image_index, + void *image, + efi_uintn_t *image_size); + efi_status_t (EFIAPI *set_image)( + struct efi_firmware_management_protocol *this, + u8 image_index, + const void *image, + efi_uintn_t image_size, + const void *vendor_code, + efi_status_t (*progress)(efi_uintn_t completion), + u16 **abort_reason); + efi_status_t (EFIAPI *check_image)( + struct efi_firmware_management_protocol *this, + u8 image_index, + const void *image, + efi_uintn_t *image_size, + u32 *image_updatable); + efi_status_t (EFIAPI *get_package_info)( + struct efi_firmware_management_protocol *this, + u32 *package_version, + u16 **package_version_name, + u32 *package_version_name_maxlen, + u64 *attributes_supported, + u64 *attributes_setting); + efi_status_t (EFIAPI *set_package_info)( + struct efi_firmware_management_protocol *this, + const void *image, + efi_uintn_t *image_size, + const void *vendor_code, + u32 package_version, + const u16 *package_version_name); +}; + #endif diff --git a/include/efi_loader.h b/include/efi_loader.h index 157c560034fc..9adc7e857b93 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -210,6 +210,8 @@ extern const efi_guid_t efi_guid_cert_type_pkcs7; extern const efi_guid_t efi_guid_rng_protocol; /* GUID of capsule update result */ extern const efi_guid_t efi_guid_capsule_report; +/* GUID of firmware management protocol */ +extern const efi_guid_t efi_guid_firmware_management_protocol; extern unsigned int __efi_runtime_start, __efi_runtime_stop; extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 6e35cbe64c7f..98bbf6d4ca27 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -126,6 +126,14 @@ config EFI_CAPSULE_ON_DISK_EARLY executed as part of U-Boot initialisation so that they will surely take place whatever is set to distro_bootcmd. +config EFI_CAPSULE_FIRMWARE_MANAGEMENT + bool "Capsule: Firmware Management Protocol" + depends on EFI_HAVE_CAPSULE_SUPPORT + default y + help + Select this option if you want to enable capsule-based + firmware update using Firmware Management Protocol. + config EFI_DEVICE_PATH_TO_TEXT bool "Device path to text protocol" default y diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 2259bfbf3d19..2015929e3708 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -15,6 +15,10 @@ #include const efi_guid_t efi_guid_capsule_report = EFI_CAPSULE_REPORT_GUID; +static const efi_guid_t efi_guid_firmware_management_capsule_id = + EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; +const efi_guid_t efi_guid_firmware_management_protocol = + EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID; #ifdef CONFIG_EFI_CAPSULE_ON_DISK /* for file system access */ @@ -88,6 +92,218 @@ void set_capsule_result(int index, struct efi_capsule_header *capsule, printf("EFI: creating %ls failed\n", variable_name16); } +#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT +/** + * efi_fmp_find - search for Firmware Management Protocol drivers + * @image_type: Image type guid + * @instance: Instance number + * @handles: Handles of FMP drivers + * @no_handles: Number of handles + * + * Search for Firmware Management Protocol drivers, matching the image + * type, @image_type and the machine instance, @instance, from the list, + * @handles. + * + * Return: + * * Protocol instance - on success + * * NULL - on failure + */ +static struct efi_firmware_management_protocol * +efi_fmp_find(efi_guid_t *image_type, u64 instance, efi_handle_t *handles, + efi_uintn_t no_handles) +{ + efi_handle_t *handle; + struct efi_firmware_management_protocol *fmp; + struct efi_firmware_image_descriptor *image_info, *desc; + efi_uintn_t info_size, descriptor_size; + u32 descriptor_version; + u8 descriptor_count; + u32 package_version; + u16 *package_version_name; + bool found = false; + int i, j; + efi_status_t ret; + + for (i = 0, handle = handles; i < no_handles; i++, handle++) { + ret = EFI_CALL(efi_handle_protocol( + *handle, + &efi_guid_firmware_management_protocol, + (void **)&fmp)); + if (ret != EFI_SUCCESS) + continue; + + /* get device's image info */ + info_size = 0; + image_info = NULL; + descriptor_version = 0; + descriptor_count = 0; + descriptor_size = 0; + package_version = 0; + package_version_name = NULL; + ret = EFI_CALL(fmp->get_image_info(fmp, &info_size, + image_info, + &descriptor_version, + &descriptor_count, + &descriptor_size, + &package_version, + &package_version_name)); + if (ret != EFI_BUFFER_TOO_SMALL) + goto skip; + + image_info = malloc(info_size); + if (!image_info) + goto skip; + + ret = EFI_CALL(fmp->get_image_info(fmp, &info_size, + image_info, + &descriptor_version, + &descriptor_count, + &descriptor_size, + &package_version, + &package_version_name)); + if (ret != EFI_SUCCESS) + goto skip; + + /* matching */ + for (j = 0, desc = image_info; j < descriptor_count; + j++, desc = (void *)desc + descriptor_size) { + EFI_PRINT("+++ desc[%d] index: %d, name: %ls\n", + j, desc->image_index, desc->image_id_name); + if (!guidcmp(&desc->image_type_id, image_type) && + (!instance || + !desc->hardware_instance || + (descriptor_version >= 3 && + desc->hardware_instance == instance))) + found = true; + } + +skip: + efi_free_pool(package_version_name); + free(image_info); + EFI_CALL(efi_close_protocol( + (efi_handle_t)fmp, + &efi_guid_firmware_management_protocol, + NULL, NULL)); + if (found) + return fmp; + } + + return NULL; +} + +/** + * efi_capsule_update_firmware - update firmware from capsule + * @capsule_data: Capsule + * + * Update firmware, using a capsule, @capsule_data. Loading any FMP + * drivers embedded in a capsule is not supported. + * + * Return: status code + */ +static efi_status_t efi_capsule_update_firmware( + struct efi_capsule_header *capsule_data) +{ + struct efi_firmware_management_capsule_header *capsule; + struct efi_firmware_management_capsule_image_header *image; + size_t capsule_size; + void *image_binary, *vendor_code; + efi_handle_t *handles; + efi_uintn_t no_handles; + int item; + struct efi_firmware_management_protocol *fmp; + u16 *abort_reason; + efi_status_t ret = EFI_SUCCESS; + + /* sanity check */ + if (capsule_data->header_size < sizeof(*capsule) || + capsule_data->header_size >= capsule_data->capsule_image_size) + return EFI_INVALID_PARAMETER; + + capsule = (void *)capsule_data + capsule_data->header_size; + capsule_size = capsule_data->capsule_image_size + - capsule_data->header_size; + + if (capsule->version != 0x00000001) + return EFI_INVALID_PARAMETER; + + /* Drivers */ + /* TODO: support loading drivers */ + + handles = NULL; + ret = EFI_CALL(efi_locate_handle_buffer( + BY_PROTOCOL, + &efi_guid_firmware_management_protocol, + NULL, &no_handles, (efi_handle_t **)&handles)); + if (ret != EFI_SUCCESS) + return EFI_UNSUPPORTED; + + /* Payload */ + for (item = capsule->embedded_driver_count; + item < capsule->embedded_driver_count + + capsule->payload_item_count; item++) { + /* sanity check */ + if ((capsule->item_offset_list[item] + sizeof(*image) + >= capsule_size)) { + printf("EFI: A capsule has not enough size of data\n"); + ret = EFI_INVALID_PARAMETER; + goto out; + } + + image = (void *)capsule + capsule->item_offset_list[item]; + + if (image->version != 0x00000001 && + image->version != 0x00000002 && + image->version != 0x00000003) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + + /* find a device for update firmware */ + /* TODO: should we pass index as well, or nothing but type? */ + fmp = efi_fmp_find(&image->update_image_type_id, + image->version == 0x1 ? 0 : + image->update_hardware_instance, + handles, no_handles); + if (!fmp) { + printf("EFI Capsule: driver not found for firmware type: %pUl, hardware instance: %lld\n", + &image->update_image_type_id, + image->version == 0x1 ? 0 : + image->update_hardware_instance); + ret = EFI_UNSUPPORTED; + goto out; + } + + /* do it */ + image_binary = (void *)image + sizeof(*image); + vendor_code = image_binary + image->update_image_size; + + abort_reason = NULL; + ret = EFI_CALL(fmp->set_image(fmp, image->update_image_index, + image_binary, + image->update_image_size, + vendor_code, NULL, + &abort_reason)); + if (ret != EFI_SUCCESS) { + printf("EFI Capsule: firmware update failed: %ls\n", + abort_reason); + efi_free_pool(abort_reason); + goto out; + } + } + +out: + efi_free_pool(handles); + + return ret; +} +#else +static efi_status_t efi_capsule_update_firmware( + struct efi_capsule_header *capsule_data) +{ + return EFI_UNSUPPORTED; +} +#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT */ + /** * efi_update_capsule() - process information from operating system * @capsule_header_array: Array of virtual address pointers @@ -118,9 +334,29 @@ efi_status_t EFIAPI efi_update_capsule( goto out; } - ret = EFI_UNSUPPORTED; + ret = EFI_SUCCESS; for (i = 0, capsule = *capsule_header_array; i < capsule_count; i++, capsule = *(++capsule_header_array)) { + /* sanity check */ + if (capsule->header_size < sizeof(*capsule) || + capsule->capsule_image_size < sizeof(*capsule)) { + printf("EFI: A capsule has not enough size of data\n"); + continue; + } + + EFI_PRINT("Capsule[%d] (guid:%pUl)\n", + i, &capsule->capsule_guid); + if (!guidcmp(&capsule->capsule_guid, + &efi_guid_firmware_management_capsule_id)) { + ret = efi_capsule_update_firmware(capsule); + } else { + printf("EFI: not support capsule type: %pUl\n", + &capsule->capsule_guid); + ret = EFI_UNSUPPORTED; + } + + if (ret != EFI_SUCCESS) + goto out; } out: return EFI_EXIT(ret); diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 2830a7094489..34dd65e30385 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -160,6 +160,10 @@ static efi_status_t efi_init_os_indications(void) os_indications_supported |= EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED; + if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT)) + os_indications_supported |= + EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED; + return efi_set_variable_int(L"OsIndicationsSupported", &efi_global_variable_guid, EFI_VARIABLE_BOOTSERVICE_ACCESS | From patchwork Mon Sep 7 05:34:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358585 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=gs29WH+w; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlHCv3156z9sSP for ; Mon, 7 Sep 2020 15:39:39 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 2C9A582513; Mon, 7 Sep 2020 07:36:48 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="gs29WH+w"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id CFC18824E1; Mon, 7 Sep 2020 07:36:23 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1042.google.com (mail-pj1-x1042.google.com [IPv6:2607:f8b0:4864:20::1042]) (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 AE142824B1 for ; Mon, 7 Sep 2020 07:36:17 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pj1-x1042.google.com with SMTP id s2so5919018pjr.4 for ; Sun, 06 Sep 2020 22:36:17 -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=W1rPc1cDNodKZN1hxoGoa0l0XvrQyP+gi13zWtivER0=; b=gs29WH+wj1owBdjOX35y01vuOrmaFZAge1wCG5bQfkIQMcmaL7lwA4/xS9+8rKUhnk Jw6m4dWxT28Y58Ztnb1dIVktqPWzxIIODeUWR23dS0mTmvL5yp/uRTxeNT5JrpATeePR VAVyDj804prYRnpqgNUJbxeF1hUY78Km4IdMF8CK9/5lz1a7I3xJWJaxpAS/raECY8x1 bq6/bObiPtRxIxFAodqWk9wYPlnHSNHTOx4XqnYjFryywaDXJKyLueAZBBh8Qwu094nm vowdWKQtvOWfKQU7GJkaEMtv6wMVHy8c8lnHzwv1ecXZbH/y6IO7RsEUpREYIVngmH7f qKnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=W1rPc1cDNodKZN1hxoGoa0l0XvrQyP+gi13zWtivER0=; b=pU6MQohFlcvOeRJhDFSpMONvOSx0Gwq0tFYnHUxmsXxAx4Q3XJEMC7U0sG6i0a7I3H zr+0skgtR9dBaBCrEhsrpXy3YoT+a02cDCqQrL2o/6iqsfFdElSeUEzpzhmSfD9clTJr 6oED+dlrxhBLBX74hph9mMGw00Vb7gnzOS/1nsnd3kMEVeKNU6OALTBoepKCsS9UidJu 7P7V/s0LOTp+Mk5DtwGJkHx3AmztqKtzuRUHkVg8FWW4NZmfuP810FfQeupOR+b/HNnk 1o1z7SleYeKvXmXo74d3zQxUVKRnQwEABku7u6K1Eh+LNpMsyv1neCIXTeFtZAfvBYly p8Dg== X-Gm-Message-State: AOAM532dVNn5hvZ+zZgpxBSa6/RO/mJuNlblGlZLoM3otYHnMDvSaesQ 0DxCE/hcqX0v6iZmH6q0gmJb6w== X-Google-Smtp-Source: ABdhPJz+O0lYJVntRGvp+B8+tw+NxZtIttyWyYek12lR4Ka6QBMKs9OlGSm0x2OhFQexlLPhInSknQ== X-Received: by 2002:a17:90a:fb52:: with SMTP id iq18mr18978911pjb.207.1599456971245; Sun, 06 Sep 2020 22:36:11 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.36.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:36:10 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 11/17] efi_loader: add firmware management protocol for FIT image Date: Mon, 7 Sep 2020 14:34:20 +0900 Message-Id: <20200907053426.1675646-12-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean In this commit, a very simple firmware management protocol driver is implemented. It will take a common FIT image firmware in a capsule file and apply the data using dfu backend storage drivers via update_fit() interface. So "dfu_alt_info" variable should be properly set to specify a device and location to be updated. Please read README.dfu. Fit image is a common file format for firmware update on U-Boot, and this protocol works neatly just as a wrapper for one. Signed-off-by: AKASHI Takahiro --- include/efi_api.h | 4 + include/efi_loader.h | 2 + lib/efi_loader/Kconfig | 11 ++ lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_capsule.c | 12 +- lib/efi_loader/efi_firmware.c | 291 ++++++++++++++++++++++++++++++++++ 6 files changed, 320 insertions(+), 1 deletion(-) create mode 100644 lib/efi_loader/efi_firmware.c diff --git a/include/efi_api.h b/include/efi_api.h index 966bc6e590bf..071d0ba866c7 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -1849,6 +1849,10 @@ struct efi_signature_list { EFI_GUID(0x86c77a67, 0x0b97, 0x4633, 0xa1, 0x87, \ 0x49, 0x10, 0x4d, 0x06, 0x85, 0xc7) +#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ + EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ + 0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) + #define IMAGE_ATTRIBUTE_IMAGE_UPDATABLE 0x0000000000000001 #define IMAGE_ATTRIBUTE_RESET_REQUIRED 0x0000000000000002 #define IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED 0x0000000000000004 diff --git a/include/efi_loader.h b/include/efi_loader.h index 9adc7e857b93..6959f62b80a9 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -810,6 +810,8 @@ void efi_memcpy_runtime(void *dest, const void *src, size_t n); /* commonly used helper function */ u16 *efi_create_indexed_name(u16 *buffer, const u16 *name, unsigned int index); +extern const struct efi_firmware_management_protocol efi_fmp_fit; + /* Capsule update */ efi_status_t EFIAPI efi_update_capsule( struct efi_capsule_header **capsule_header_array, diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 98bbf6d4ca27..bc12f0afb4aa 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -134,6 +134,17 @@ config EFI_CAPSULE_FIRMWARE_MANAGEMENT Select this option if you want to enable capsule-based firmware update using Firmware Management Protocol. +config EFI_CAPSULE_FIRMWARE_FIT + bool "FMP driver for FIT image" + depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT + depends on FIT + select UPDATE_FIT + select DFU + default n + help + Select this option if you want to enable firmware management protocol + driver for FIT image + config EFI_DEVICE_PATH_TO_TEXT bool "Device path to text protocol" default y diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index c7d231f0e57d..23b1828b0fe0 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o obj-y += efi_bootmgr.o obj-y += efi_boottime.o obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o +obj-$(CONFIG_EFI_CAPSULE_FIRMWARE_FIT) += efi_firmware.o obj-y += efi_console.o obj-y += efi_device_path.o obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 2015929e3708..a44f81daaee9 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -804,7 +804,17 @@ static void efi_capsule_scan_done(void) */ efi_status_t __weak arch_efi_load_capsule_drivers(void) { - return EFI_SUCCESS; + __maybe_unused efi_handle_t handle; + efi_status_t ret = EFI_SUCCESS; + + if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_FIT)) { + handle = NULL; + ret = EFI_CALL(efi_install_multiple_protocol_interfaces( + &handle, &efi_guid_firmware_management_protocol, + &efi_fmp_fit, NULL)); + } + + return ret; } /** diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c new file mode 100644 index 000000000000..4c395f4eb5d9 --- /dev/null +++ b/lib/efi_loader/efi_firmware.c @@ -0,0 +1,291 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * EFI Firmware management protocol + * + * Copyright (c) 2020 Linaro Limited + * Author: AKASHI Takahiro + */ + +#include +#include +#include +#include +#include +#include + +/* + * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update + * method with existing FIT image format, and handles + * - multiple regions of firmware via DFU + * but doesn't support + * - versioning of firmware image + * - package information + */ +const efi_guid_t efi_firmware_image_type_uboot_fit = + EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; + +/** + * efi_get_dfu_info - return information about the current firmware image + * @this: Protocol instance + * @image_info_size: Size of @image_info + * @image_info: Image information + * @descriptor_version: Pointer to version number + * @descriptor_count: Pointer to number of descriptors + * @descriptor_size: Pointer to descriptor size + * package_version: Package version + * package_version_name: Package version's name + * image_type: Image type GUID + * + * Return information bout the current firmware image in @image_info. + * @image_info will consist of a number of descriptors. + * Each descriptor will be created based on "dfu_alt_info" variable. + * + * Return status code + */ +static efi_status_t efi_get_dfu_info( + efi_uintn_t *image_info_size, + struct efi_firmware_image_descriptor *image_info, + u32 *descriptor_version, + u8 *descriptor_count, + efi_uintn_t *descriptor_size, + u32 *package_version, + u16 **package_version_name, + const efi_guid_t *image_type) +{ + struct dfu_entity *dfu; + size_t names_len, total_size; + int dfu_num, i; + u16 *name, *next; + + dfu_init_env_entities(NULL, NULL); + + names_len = 0; + dfu_num = 0; + list_for_each_entry(dfu, &dfu_list, list) { + names_len += (utf8_utf16_strlen(dfu->name) + 1) * 2; + dfu_num++; + } + if (!dfu_num) { + EFI_PRINT("Probably dfu_alt_info not defined\n"); + *image_info_size = 0; + dfu_free_entities(); + + return EFI_SUCCESS; + } + + total_size = sizeof(*image_info) * dfu_num + names_len; + /* + * we will assume that sizeof(*image_info) * dfu_name + * is, at least, a multiple of 2. So the start address for + * image_id_name would be aligned with 2 bytes. + */ + if (*image_info_size < total_size) { + *image_info_size = total_size; + dfu_free_entities(); + + return EFI_BUFFER_TOO_SMALL; + } + *image_info_size = total_size; + + *descriptor_version = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; + *descriptor_count = dfu_num; + *descriptor_size = sizeof(*image_info); + *package_version = 0xffffffff; /* not supported */ + *package_version_name = NULL; /* not supported */ + + /* DFU alt number should correspond to image_index */ + i = 0; + /* Name area starts just after descriptors */ + name = (u16 *)((u8 *)image_info + sizeof(*image_info) * dfu_num); + next = name; + list_for_each_entry(dfu, &dfu_list, list) { + image_info[i].image_index = dfu->alt + 1; + image_info[i].image_type_id = *image_type; + image_info[i].image_id = dfu->alt; + + /* copy the DFU entity name */ + utf8_utf16_strcpy(&next, dfu->name); + image_info[i].image_id_name = name; + name = ++next; + + image_info[i].version = 0; /* not supported */ + image_info[i].version_name = NULL; /* not supported */ + image_info[i].size = 0; + image_info[i].attributes_supported = + IMAGE_ATTRIBUTE_IMAGE_UPDATABLE; + image_info[i].attributes_setting = + IMAGE_ATTRIBUTE_IMAGE_UPDATABLE; + image_info[i].lowest_supported_image_version = 0; + image_info[i].last_attempt_version = 0; + image_info[i].last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS; + image_info[i].hardware_instance = 1; + image_info[i].dependencies = NULL; + + i++; + } + + dfu_free_entities(); + + return EFI_SUCCESS; +} + +/** + * efi_firmware_fit_get_image_info - return information about the current + * firmware image + * @this: Protocol instance + * @image_info_size: Size of @image_info + * @image_info: Image information + * @descriptor_version: Pointer to version number + * @descriptor_count: Pointer to number of descriptors + * @descriptor_size: Pointer to descriptor size + * package_version: Package version + * package_version_name: Package version's name + * + * Return information bout the current firmware image in @image_info. + * @image_info will consist of a number of descriptors. + * Each descriptor will be created based on "dfu_alt_info" variable. + * + * Return status code + */ +static +efi_status_t EFIAPI efi_firmware_fit_get_image_info( + struct efi_firmware_management_protocol *this, + efi_uintn_t *image_info_size, + struct efi_firmware_image_descriptor *image_info, + u32 *descriptor_version, + u8 *descriptor_count, + efi_uintn_t *descriptor_size, + u32 *package_version, + u16 **package_version_name) +{ + efi_status_t ret; + + EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this, + image_info_size, image_info, + descriptor_version, descriptor_count, descriptor_size, + package_version, package_version_name); + + if (!image_info_size) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + if (*image_info_size && + (!image_info || !descriptor_version || !descriptor_count || + !descriptor_size || !package_version || !package_version_name)) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + ret = efi_get_dfu_info(image_info_size, image_info, + descriptor_version, descriptor_count, + descriptor_size, + package_version, package_version_name, + &efi_firmware_image_type_uboot_fit); + + return EFI_EXIT(ret); +} + +/* Place holder; not supported */ +static +efi_status_t EFIAPI efi_firmware_get_image_unsupported( + struct efi_firmware_management_protocol *this, + u8 image_index, + void *image, + efi_uintn_t *image_size) +{ + EFI_ENTRY("%p %d %p %p\n", this, image_index, image, image_size); + + return EFI_EXIT(EFI_UNSUPPORTED); +} + +/** + * efi_firmware_fit_set_image - update the firmware image + * @this: Protocol instance + * @image_index: Image index number + * @image: New image + * @image_size: Size of new image + * @vendor_code: Vendor-specific update policy + * @progress: Function to report the progress of update + * @abort_reason: Pointer to string of abort reason + * + * Update the firmware to new image, using dfu. The new image should + * have FIT image format commonly used in U-Boot. + * @vendor_code, @progress and @abort_reason are not supported. + * + * Return: status code + */ +static +efi_status_t EFIAPI efi_firmware_fit_set_image( + struct efi_firmware_management_protocol *this, + u8 image_index, + const void *image, + efi_uintn_t image_size, + const void *vendor_code, + efi_status_t (*progress)(efi_uintn_t completion), + u16 **abort_reason) +{ + EFI_ENTRY("%p %d %p %ld %p %p %p\n", this, image_index, image, + image_size, vendor_code, progress, abort_reason); + + if (!image || image_index != 1) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + if (fit_update(image)) + return EFI_EXIT(EFI_DEVICE_ERROR); + + return EFI_EXIT(EFI_SUCCESS); +} + +/* Place holder; not supported */ +static +efi_status_t EFIAPI efi_firmware_check_image_unsupported( + struct efi_firmware_management_protocol *this, + u8 image_index, + const void *image, + efi_uintn_t *image_size, + u32 *image_updatable) +{ + EFI_ENTRY("%p %d %p %p %p\n", this, image_index, image, image_size, + image_updatable); + + return EFI_EXIT(EFI_UNSUPPORTED); +} + +/* Place holder; not supported */ +static +efi_status_t EFIAPI efi_firmware_get_package_info_unsupported( + struct efi_firmware_management_protocol *this, + u32 *package_version, + u16 **package_version_name, + u32 *package_version_name_maxlen, + u64 *attributes_supported, + u64 *attributes_setting) +{ + EFI_ENTRY("%p %p %p %p %p %p\n", this, package_version, + package_version_name, package_version_name_maxlen, + attributes_supported, attributes_setting); + + return EFI_EXIT(EFI_UNSUPPORTED); +} + +/* Place holder; not supported */ +static +efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( + struct efi_firmware_management_protocol *this, + const void *image, + efi_uintn_t *image_size, + const void *vendor_code, + u32 package_version, + const u16 *package_version_name) +{ + EFI_ENTRY("%p %p %p %p %x %p\n", this, image, image_size, vendor_code, + package_version, package_version_name); + + return EFI_EXIT(EFI_UNSUPPORTED); +} + +const struct efi_firmware_management_protocol efi_fmp_fit = { + .get_image_info = efi_firmware_fit_get_image_info, + .get_image = efi_firmware_get_image_unsupported, + .set_image = efi_firmware_fit_set_image, + .check_image = efi_firmware_check_image_unsupported, + .get_package_info = efi_firmware_get_package_info_unsupported, + .set_package_info = efi_firmware_set_package_info_unsupported, +}; From patchwork Mon Sep 7 05:34:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358583 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=Y2xyKU8l; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlHBz1k92z9sSP for ; Mon, 7 Sep 2020 15:38:51 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 0EE888250D; Mon, 7 Sep 2020 07:36:41 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Y2xyKU8l"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id E26EE824E8; Mon, 7 Sep 2020 07:36:18 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x643.google.com (mail-pl1-x643.google.com [IPv6:2607:f8b0:4864:20::643]) (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 93867824D3 for ; Mon, 7 Sep 2020 07:36:15 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pl1-x643.google.com with SMTP id c3so3701056plz.5 for ; Sun, 06 Sep 2020 22:36:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=WiqeZfpZSu5UfUsqbzXxfvRpNlDhX0frfl2n+yjmzt8=; b=Y2xyKU8l917U+tyVPy4EjBQU19dQfeerJylVLMJKN8S/lbXb9Dx5OTvYD5AEKRLSWs eFSms/rsuW4j8UcBlkpIWEDC50bIPzRIb89hIX2WS+M+2FvPpG0rKMTBY/Hp3Fvj+QtE 5/t/GC24qObqagVJew/GBbtkvA8Ghm25Mh9STzPfwSs7dNa4tbM53LsHKIWTvpIWUU8z xBmwCToIwu+XgSSuyBmMBQirnv/J7WfqxTSFZTT0c5z42Nu90vTNXxAghtHmNOSOvdUZ tlDfuGxNoHLrqG0sMpL7U8iJgvqDQe8L9ZYvYcKlB1ipGPmkT+IUU5tMel06p7RlxRSC TPqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WiqeZfpZSu5UfUsqbzXxfvRpNlDhX0frfl2n+yjmzt8=; b=UlIZHoOSo12T8dljptCxB7ANN5a7WJtF7m30h5PSlzjm/O4y2G4Yi9398vnt7YWWAg DRLeewJjTI5SxCEnuWY6XhQoKB4dt5DbO6IQtb6rAtgYi6JrjzP9EqVohwwQXjZowDe1 7BCv1j46D4IcvsQik5bz9SBZ/A5jWfV1cVK0/rfEpGU+JdXebPiZ+eR+MFPorXnuK4ty 07oZ8rfw9t66f6nDRU6MMAChSmBfs4N5LLEGxwwCp7SbEbxLuiYcFtb/wR4cgkDnpmCY KFyWKaNmWKHDwQ78Hu4g4/GhW+XO4cV0FaMdo/0OfK1AbhHhEJzKaTuMcTmr2VGMR+4+ 3feA== X-Gm-Message-State: AOAM533ET/9pm313VSrdo6N0w+zUG+Rv1adKV8LP6gdKtoETEoCYIvO+ ZyGUpn2mUf/WrwcVKmrQ8FAifQ== X-Google-Smtp-Source: ABdhPJx41trMplIY/7SIocB3y9eQRBxBsQwTgZNUwnvasR+5PDMV/u9ALeisJM3MfbrLCBTgTSwuHQ== X-Received: by 2002:a17:902:b703:: with SMTP id d3mr7185158pls.148.1599456974124; Sun, 06 Sep 2020 22:36:14 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.36.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:36:13 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 12/17] dfu: add dfu_write_by_alt() Date: Mon, 7 Sep 2020 14:34:21 +0900 Message-Id: <20200907053426.1675646-13-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean This function is a variant of dfu_write_by_name() and takes a DFU alt setting number for dfu configuration. It will be utilised to implement UEFI capsule management protocol for raw image in a later commit. Signed-off-by: AKASHI Takahiro --- drivers/dfu/dfu_alt.c | 47 +++++++++++++++++++++++++++++++++++++++++++ include/dfu.h | 26 +++++++++++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/drivers/dfu/dfu_alt.c b/drivers/dfu/dfu_alt.c index 7528806cd163..d5827812070c 100644 --- a/drivers/dfu/dfu_alt.c +++ b/drivers/dfu/dfu_alt.c @@ -76,3 +76,50 @@ done: return ret; } + +/** + * dfu_write_by_alt() - write data to DFU medium + * @dfu_alt_num: DFU alt setting number + * @addr: Address of data buffer to write + * @len: Number of bytes + * @interface: Destination DFU medium (e.g. "mmc") + * @devstring: Instance number of destination DFU medium (e.g. "1") + * + * This function is storing data received on DFU supported medium which + * is specified by @dfu_alt_name. + * + * Return: 0 - on success, error code - otherwise + */ +int dfu_write_by_alt(int dfu_alt_num, void *addr, unsigned int len, + char *interface, char *devstring) +{ + struct dfu_entity *dfu; + int ret; + + debug("%s: alt: %d addr: 0x%p len: %d device: %s:%s\n", __func__, + dfu_alt_num, addr, len, interface, devstring); + + ret = dfu_init_env_entities(interface, devstring); + if (ret) + goto done; + + if (dfu_alt_num < 0) { + pr_err("Invalid alt number: %d", dfu_alt_num); + ret = -ENODEV; + goto done; + } + + dfu = dfu_get_entity(dfu_alt_num); + if (!dfu) { + pr_err("DFU entity for alt: %d not found!", dfu_alt_num); + ret = -ENODEV; + goto done; + } + + ret = dfu_write_from_mem_addr(dfu, (void *)(uintptr_t)addr, len); + +done: + dfu_free_entities(); + + return ret; +} diff --git a/include/dfu.h b/include/dfu.h index 015d1bf895d0..6c5b4aaa5963 100644 --- a/include/dfu.h +++ b/include/dfu.h @@ -496,6 +496,7 @@ static inline int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr, } #endif +#if CONFIG_IS_ENABLED(DFU_ALT) /** * dfu_write_by_name() - write data to DFU medium * @dfu_entity_name: Name of DFU entity to write @@ -509,9 +510,24 @@ static inline int dfu_fill_entity_virt(struct dfu_entity *dfu, char *devstr, * * Return: 0 - on success, error code - otherwise */ -#if CONFIG_IS_ENABLED(DFU_ALT) int dfu_write_by_name(char *dfu_entity_name, void *addr, unsigned int len, char *interface, char *devstring); + +/** + * dfu_write_by_alt() - write data to DFU medium + * @dfu_alt_num: DFU alt setting number + * @addr: Address of data buffer to write + * @len: Number of bytes + * @interface: Destination DFU medium (e.g. "mmc") + * @devstring: Instance number of destination DFU medium (e.g. "1") + * + * This function is storing data received on DFU supported medium which + * is specified by @dfu_alt_name. + * + * Return: 0 - on success, error code - otherwise + */ +int dfu_write_by_alt(int dfu_alt_num, void *addr, unsigned int len, + char *interface, char *devstring); #else static inline int dfu_write_by_name(char *dfu_entity_name, void *addr, unsigned int len, char *interface, @@ -520,6 +536,14 @@ static inline int dfu_write_by_name(char *dfu_entity_name, void *addr, puts("write support for DFU not available!\n"); return -ENOSYS; } + +static inline int dfu_write_by_alt(int dfu_alt_num, void *addr, + unsigned int len, char *interface, + char *devstring) +{ + puts("write support for DFU not available!\n"); + return -ENOSYS; +} #endif int dfu_add(struct usb_configuration *c); From patchwork Mon Sep 7 05:34:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358586 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=KXSjFFn2; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlHDD3n1Gz9sSP for ; Mon, 7 Sep 2020 15:39:56 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 3EE8C82516; Mon, 7 Sep 2020 07:36:49 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="KXSjFFn2"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 5AE9F824F6; Mon, 7 Sep 2020 07:36:29 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x643.google.com (mail-pl1-x643.google.com [IPv6:2607:f8b0:4864:20::643]) (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 AEA3C824D7 for ; Mon, 7 Sep 2020 07:36:18 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pl1-x643.google.com with SMTP id d19so534958pld.0 for ; Sun, 06 Sep 2020 22:36:18 -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=Wd4E3fo9fjBQUY+V8CGDiqcOr+1oG+Dqp9qzfDQ7uCY=; b=KXSjFFn2HzlDRLNdwaoDb7liSDqNfAEgSaWR83mBHkVJGpMZxL/T+ANgd0jOxI1OEf Pa6TQdu1S+27Ec+gvX9nyhLKJCGpSXXcYB41i7aWbz7O+TyGVWHIQOkLDm2e3piDI+5t WAcHS+ag0p7+P+xe2kBOKior1Mla9TECZeNIlApTjee70Q5/H4qgDXBY8lefyFQtlkEt FUhZB3lIQn1GZok93rAlQzvGtJXFzg3DlPM34zZ/NniyaOsEhyqD0sFx5CKwyJx9vgLA +NgAIoQBx2ntQZ3GA9hgq1KTlZpeHKo88JrZvq5TLEoVBn7SHKd6jr9WnhPybNacD5j4 af4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Wd4E3fo9fjBQUY+V8CGDiqcOr+1oG+Dqp9qzfDQ7uCY=; b=NDXUQ8hc0W5c9z8tLRnv8WgF5RO26jG7T/+X2Na0cStaaXOZlJiybuPR0Pug2vRYdQ 9KcZ7IUEZVdlKkvP05hlEMcsZbg5G+ksM4i6PenrpSzb0QVyKapziyUUKl9UaG3peZyL 7QQ+j+eHLj60gDleH/BuxdJxGFUpAbbDBNWBBv/XLUtF6+gyuFxbQW4f4lZu7BrQ+NtF u6JrLnmG+AepvqcEO24eM+0K/rTINgc8UbHlQPLbmBruCeY+7+BmMvNFTJGdzuozkZ8B ddVwO/j4sEiNhtUWhvE6hCBM/6qK6pTgdjIas6XyepnvASo/jPjivw4xkp2o4l95gs6z ySbA== X-Gm-Message-State: AOAM531/ZGRbYhaKCTzd3laj2hrA3OfiVfUnXzUkxqp4A75N3s1QewCS i+XztSlVFOALxP/0/SlAoOr7Jkh7vJd79uwM X-Google-Smtp-Source: ABdhPJwwHYr9dWBOnOCD6caIbIKcIjrFWV0gk/wQOqXwQb1DKK5hryQ6dyeq6vrKcq93AF7FWeaSzA== X-Received: by 2002:a17:902:c3d3:: with SMTP id j19mr18286309plj.59.1599456977184; Sun, 06 Sep 2020 22:36:17 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.36.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:36:16 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 13/17] efi_loader: add firmware management protocol for raw image Date: Mon, 7 Sep 2020 14:34:22 +0900 Message-Id: <20200907053426.1675646-14-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean In this commit, a very simple firmware management protocol driver is implemented. It will take a binary image in a capsule file and apply the data using dfu backend storage drivers via dfu_write_by_alt() interface. So "dfu_alt_info" variable should be properly set to specify a device and location to be updated. Please read README.dfu. Signed-off-by: AKASHI Takahiro --- include/efi_api.h | 4 + include/efi_loader.h | 1 + lib/efi_loader/Kconfig | 16 +++ lib/efi_loader/Makefile | 2 +- lib/efi_loader/efi_capsule.c | 8 ++ lib/efi_loader/efi_firmware.c | 226 +++++++++++++++++++++++++--------- 6 files changed, 199 insertions(+), 58 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index 071d0ba866c7..c7038f863ab2 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -1853,6 +1853,10 @@ struct efi_signature_list { EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ 0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) +#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ + EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ + 0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) + #define IMAGE_ATTRIBUTE_IMAGE_UPDATABLE 0x0000000000000001 #define IMAGE_ATTRIBUTE_RESET_REQUIRED 0x0000000000000002 #define IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED 0x0000000000000004 diff --git a/include/efi_loader.h b/include/efi_loader.h index 6959f62b80a9..d9ffc333324d 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -811,6 +811,7 @@ void efi_memcpy_runtime(void *dest, const void *src, size_t n); u16 *efi_create_indexed_name(u16 *buffer, const u16 *name, unsigned int index); extern const struct efi_firmware_management_protocol efi_fmp_fit; +extern const struct efi_firmware_management_protocol efi_fmp_raw; /* Capsule update */ efi_status_t EFIAPI efi_update_capsule( diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index bc12f0afb4aa..ae8c3f07b320 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -126,6 +126,10 @@ config EFI_CAPSULE_ON_DISK_EARLY executed as part of U-Boot initialisation so that they will surely take place whatever is set to distro_bootcmd. +config EFI_CAPSULE_FIRMWARE + bool + default n + config EFI_CAPSULE_FIRMWARE_MANAGEMENT bool "Capsule: Firmware Management Protocol" depends on EFI_HAVE_CAPSULE_SUPPORT @@ -140,11 +144,23 @@ config EFI_CAPSULE_FIRMWARE_FIT depends on FIT select UPDATE_FIT select DFU + select EFI_CAPSULE_FIRMWARE default n help Select this option if you want to enable firmware management protocol driver for FIT image +config EFI_CAPSULE_FIRMWARE_RAW + bool "FMP driver for raw image" + depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT + select DFU + select DFU_ALT + select EFI_CAPSULE_FIRMWARE + default n + help + Select this option if you want to enable firmware management protocol + driver for raw image + config EFI_DEVICE_PATH_TO_TEXT bool "Device path to text protocol" default y diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 23b1828b0fe0..a7631d92a3b0 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -24,7 +24,7 @@ obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o obj-y += efi_bootmgr.o obj-y += efi_boottime.o obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o -obj-$(CONFIG_EFI_CAPSULE_FIRMWARE_FIT) += efi_firmware.o +obj-$(CONFIG_EFI_CAPSULE_FIRMWARE) += efi_firmware.o obj-y += efi_console.o obj-y += efi_device_path.o obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index a44f81daaee9..af40b4a1599e 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -814,6 +814,14 @@ efi_status_t __weak arch_efi_load_capsule_drivers(void) &efi_fmp_fit, NULL)); } + if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_RAW)) { + handle = NULL; + ret = EFI_CALL(efi_install_multiple_protocol_interfaces( + &efi_root, + &efi_guid_firmware_management_protocol, + &efi_fmp_raw, NULL)); + } + return ret; } diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 4c395f4eb5d9..7e5607738319 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -13,16 +13,66 @@ #include #include -/* - * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update - * method with existing FIT image format, and handles - * - multiple regions of firmware via DFU - * but doesn't support - * - versioning of firmware image - * - package information - */ -const efi_guid_t efi_firmware_image_type_uboot_fit = - EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; +/* Place holder; not supported */ +static +efi_status_t EFIAPI efi_firmware_get_image_unsupported( + struct efi_firmware_management_protocol *this, + u8 image_index, + void *image, + efi_uintn_t *image_size) +{ + EFI_ENTRY("%p %d %p %p\n", this, image_index, image, image_size); + + return EFI_EXIT(EFI_UNSUPPORTED); +} + +/* Place holder; not supported */ +static +efi_status_t EFIAPI efi_firmware_check_image_unsupported( + struct efi_firmware_management_protocol *this, + u8 image_index, + const void *image, + efi_uintn_t *image_size, + u32 *image_updatable) +{ + EFI_ENTRY("%p %d %p %p %p\n", this, image_index, image, image_size, + image_updatable); + + return EFI_EXIT(EFI_UNSUPPORTED); +} + +/* Place holder; not supported */ +static +efi_status_t EFIAPI efi_firmware_get_package_info_unsupported( + struct efi_firmware_management_protocol *this, + u32 *package_version, + u16 **package_version_name, + u32 *package_version_name_maxlen, + u64 *attributes_supported, + u64 *attributes_setting) +{ + EFI_ENTRY("%p %p %p %p %p %p\n", this, package_version, + package_version_name, package_version_name_maxlen, + attributes_supported, attributes_setting); + + return EFI_EXIT(EFI_UNSUPPORTED); +} + +/* Place holder; not supported */ +static +efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( + struct efi_firmware_management_protocol *this, + const void *image, + efi_uintn_t *image_size, + const void *vendor_code, + u32 package_version, + const u16 *package_version_name) +{ + EFI_ENTRY("%p %p %p %p %x %p\n", this, image, image_size, vendor_code, + package_version, package_version_name); + + return EFI_EXIT(EFI_UNSUPPORTED); +} /** * efi_get_dfu_info - return information about the current firmware image @@ -129,6 +179,18 @@ static efi_status_t efi_get_dfu_info( return EFI_SUCCESS; } +#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_FIT +/* + * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update + * method with existing FIT image format, and handles + * - multiple regions of firmware via DFU + * but doesn't support + * - versioning of firmware image + * - package information + */ +const efi_guid_t efi_firmware_image_type_uboot_fit = + EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; + /** * efi_firmware_fit_get_image_info - return information about the current * firmware image @@ -182,19 +244,6 @@ efi_status_t EFIAPI efi_firmware_fit_get_image_info( return EFI_EXIT(ret); } -/* Place holder; not supported */ -static -efi_status_t EFIAPI efi_firmware_get_image_unsupported( - struct efi_firmware_management_protocol *this, - u8 image_index, - void *image, - efi_uintn_t *image_size) -{ - EFI_ENTRY("%p %d %p %p\n", this, image_index, image, image_size); - - return EFI_EXIT(EFI_UNSUPPORTED); -} - /** * efi_firmware_fit_set_image - update the firmware image * @this: Protocol instance @@ -233,59 +282,122 @@ efi_status_t EFIAPI efi_firmware_fit_set_image( return EFI_EXIT(EFI_SUCCESS); } -/* Place holder; not supported */ -static -efi_status_t EFIAPI efi_firmware_check_image_unsupported( - struct efi_firmware_management_protocol *this, - u8 image_index, - const void *image, - efi_uintn_t *image_size, - u32 *image_updatable) -{ - EFI_ENTRY("%p %d %p %p %p\n", this, image_index, image, image_size, - image_updatable); +const struct efi_firmware_management_protocol efi_fmp_fit = { + .get_image_info = efi_firmware_fit_get_image_info, + .get_image = efi_firmware_get_image_unsupported, + .set_image = efi_firmware_fit_set_image, + .check_image = efi_firmware_check_image_unsupported, + .get_package_info = efi_firmware_get_package_info_unsupported, + .set_package_info = efi_firmware_set_package_info_unsupported, +}; +#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_FIT */ - return EFI_EXIT(EFI_UNSUPPORTED); -} +#ifdef CONFIG_EFI_CAPSULE_FIRMWARE_RAW +/* + * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update + * method with raw data. + */ +const efi_guid_t efi_firmware_image_type_uboot_raw = + EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; -/* Place holder; not supported */ +/** + * efi_firmware_raw_get_image_info - return information about the current + firmware image + * @this: Protocol instance + * @image_info_size: Size of @image_info + * @image_info: Image information + * @descriptor_version: Pointer to version number + * @descriptor_count: Pointer to number of descriptors + * @descriptor_size: Pointer to descriptor size + * package_version: Package version + * package_version_name: Package version's name + * + * Return information bout the current firmware image in @image_info. + * @image_info will consist of a number of descriptors. + * Each descriptor will be created based on "dfu_alt_info" variable. + * + * Return status code + */ static -efi_status_t EFIAPI efi_firmware_get_package_info_unsupported( +efi_status_t EFIAPI efi_firmware_raw_get_image_info( struct efi_firmware_management_protocol *this, + efi_uintn_t *image_info_size, + struct efi_firmware_image_descriptor *image_info, + u32 *descriptor_version, + u8 *descriptor_count, + efi_uintn_t *descriptor_size, u32 *package_version, - u16 **package_version_name, - u32 *package_version_name_maxlen, - u64 *attributes_supported, - u64 *attributes_setting) + u16 **package_version_name) { - EFI_ENTRY("%p %p %p %p %p %p\n", this, package_version, - package_version_name, package_version_name_maxlen, - attributes_supported, attributes_setting); + efi_status_t ret = EFI_SUCCESS; - return EFI_EXIT(EFI_UNSUPPORTED); + EFI_ENTRY("%p %p %p %p %p %p %p %p\n", this, + image_info_size, image_info, + descriptor_version, descriptor_count, descriptor_size, + package_version, package_version_name); + + if (!image_info_size) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + if (*image_info_size && + (!image_info || !descriptor_version || !descriptor_count || + !descriptor_size || !package_version || !package_version_name)) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + ret = efi_get_dfu_info(image_info_size, image_info, + descriptor_version, descriptor_count, + descriptor_size, + package_version, package_version_name, + &efi_firmware_image_type_uboot_raw); + + return EFI_EXIT(ret); } -/* Place holder; not supported */ +/** + * efi_firmware_raw_set_image - update the firmware image + * @this: Protocol instance + * @image_index: Image index number + * @image: New image + * @image_size: Size of new image + * @vendor_code: Vendor-specific update policy + * @progress: Function to report the progress of update + * @abort_reason: Pointer to string of abort reason + * + * Update the firmware to new image, using dfu. The new image should + * be a single raw image. + * @vendor_code, @progress and @abort_reason are not supported. + * + * Return: status code + */ static -efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( +efi_status_t EFIAPI efi_firmware_raw_set_image( struct efi_firmware_management_protocol *this, + u8 image_index, const void *image, - efi_uintn_t *image_size, + efi_uintn_t image_size, const void *vendor_code, - u32 package_version, - const u16 *package_version_name) + efi_status_t (*progress)(efi_uintn_t completion), + u16 **abort_reason) { - EFI_ENTRY("%p %p %p %p %x %p\n", this, image, image_size, vendor_code, - package_version, package_version_name); + EFI_ENTRY("%p %d %p %ld %p %p %p\n", this, image_index, image, + image_size, vendor_code, progress, abort_reason); - return EFI_EXIT(EFI_UNSUPPORTED); + if (!image) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + if (dfu_write_by_alt(image_index - 1, (void *)image, image_size, + NULL, NULL)) + return EFI_EXIT(EFI_DEVICE_ERROR); + + return EFI_EXIT(EFI_SUCCESS); } -const struct efi_firmware_management_protocol efi_fmp_fit = { - .get_image_info = efi_firmware_fit_get_image_info, +const struct efi_firmware_management_protocol efi_fmp_raw = { + .get_image_info = efi_firmware_raw_get_image_info, .get_image = efi_firmware_get_image_unsupported, - .set_image = efi_firmware_fit_set_image, + .set_image = efi_firmware_raw_set_image, .check_image = efi_firmware_check_image_unsupported, .get_package_info = efi_firmware_get_package_info_unsupported, .set_package_info = efi_firmware_set_package_info_unsupported, }; +#endif /* CONFIG_EFI_CAPSULE_FIRMWARE_RAW */ From patchwork Mon Sep 7 05:34:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358587 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=vnvUStx6; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlHDk2zYdz9sSP for ; Mon, 7 Sep 2020 15:40:22 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5146F8251B; Mon, 7 Sep 2020 07:36:50 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="vnvUStx6"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 54DE1824FB; Mon, 7 Sep 2020 07:36:34 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x102f.google.com (mail-pj1-x102f.google.com [IPv6:2607:f8b0:4864:20::102f]) (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 53F6C824F6 for ; Mon, 7 Sep 2020 07:36:31 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pj1-x102f.google.com with SMTP id t7so2983314pjd.3 for ; Sun, 06 Sep 2020 22:36:31 -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=dGekxwt++1aoKcVNmfvlJfu0ecAldwfhJZzOR+NXfZA=; b=vnvUStx6KtalJVWZ2xf4x/yfJWO+x1ga3Qfw7im2zchaM4EWQZv1qbE8EBnGq+iQ8V uHTD4gXWr+XfH+mIIbZijfCVsprrvTYkn2FeLTykpVWqrvqVc503eV5xUt8IVpJGFiyF JSTITBMAJmpzjWtUvX1MNIq04o8pIHvbXL2GyZ11OIBYajt1laUHgP5U3v/LiZB3Zkby X/StMVfMp8JKOWYgkxTBNpIentvkS2jp2U1tVrlR1L24mzeZ3VRUTwBIOolqUakn2K4S DFnplf5+SbZdmRaLXcD0KZohdWGEayzXEbITSOoCBx9LTgH6TqHWV78F0zwlLNQ7XpFi kKwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=dGekxwt++1aoKcVNmfvlJfu0ecAldwfhJZzOR+NXfZA=; b=YUEIlpskEpJcPzGEliqXbeYhvcSF5nXunV+1nUOhA2Tpt+WITTLtgvrYjYrRvOWU8C FszuSieoq9giRgT/Z/9iQCx5+PwCM/khrjl3rKsnU+HumooNFZvIhdqZe3QOd/ZBtPJn /y3/SzjpktuWc3vU9UCvwr4WN38oy+Dy5kTW3cxWDm3cwo4qTYJFdgrrKnyPDqzfoKK+ lWdmuwfQuPqjhUIGh/+cj6dqRgksu7rjUIPP6BxWig/iejqoS/HDPm/5X01kHTA2vBmV ZkmXtKzXTskClY0BQNLEWWEEBJi66nUB6cU6j5XPX0hljhP+jwqUO0SrZTWBgb5NAyZ7 T+nw== X-Gm-Message-State: AOAM531VOas+DGdF8+GKvIfATq10TLU7mjEHfEL/ZzuymRndj1RsimS/ GfgmgJd7lObGSjKz/Lx4gD4VuA== X-Google-Smtp-Source: ABdhPJxEkZ7CsrFPMU1APazpMobxzEdtjLAht+yF0ImcGjxzatROj9i9uSSVcBIdL9l5dnzicqEudg== X-Received: by 2002:a17:902:744a:: with SMTP id e10mr1086961plt.29.1599456979984; Sun, 06 Sep 2020 22:36:19 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.36.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:36:19 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 14/17] cmd: add "efidebug capsule" command Date: Mon, 7 Sep 2020 14:34:23 +0900 Message-Id: <20200907053426.1675646-15-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean "efidebug capsule" is more or less a debugging utility. efidebug capsule update: invoke UpdateCapsule against data on memory efidebug capsule show: show a capsule header efidebug capsule result: dump a capsule result variable Signed-off-by: AKASHI Takahiro --- cmd/efidebug.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) diff --git a/cmd/efidebug.c b/cmd/efidebug.c index 9874838b005a..ad7aa4a304a2 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -18,6 +18,228 @@ #include #define BS systab.boottime +#define RT systab.runtime + +#ifdef CONFIG_EFI_HAVE_CAPSULE_SUPPORT +/** + * do_efi_capsule_update() - process a capsule update + * + * @cmdtp: Command table + * @flag: Command flag + * @argc: Number of arguments + * @argv: Argument array + * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure + * + * Implement efidebug "capsule update" sub-command. + * process a capsule update. + * + * efidebug capsule update [-v] + */ +static int do_efi_capsule_update(struct cmd_tbl *cmdtp, int flag, + int argc, char * const argv[]) +{ + struct efi_capsule_header *capsule; + int verbose = 0; + char *endp; + efi_status_t ret; + + if (argc != 2 && argc != 3) + return CMD_RET_USAGE; + + if (argc == 3) { + if (strcmp(argv[1], "-v")) + return CMD_RET_USAGE; + + verbose = 1; + argc--; + argv++; + } + + capsule = (typeof(capsule))simple_strtoul(argv[1], &endp, 16); + if (endp == argv[1]) { + printf("Invalid address: %s", argv[1]); + return CMD_RET_FAILURE; + } + + if (verbose) { + printf("Capsule guid: %pUl\n", &capsule->capsule_guid); + printf("Capsule flags: 0x%x\n", capsule->flags); + printf("Capsule header size: 0x%x\n", capsule->header_size); + printf("Capsule image size: 0x%x\n", + capsule->capsule_image_size); + } + + ret = EFI_CALL(RT->update_capsule(&capsule, 1, (u64)NULL)); + if (ret) { + printf("Cannot handle a capsule at %p", capsule); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; +} + +/** + * do_efi_capsule_show() - show capsule information + * + * @cmdtp: Command table + * @flag: Command flag + * @argc: Number of arguments + * @argv: Argument array + * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure + * + * Implement efidebug "capsule show" sub-command. + * show capsule information. + * + * efidebug capsule show + */ +static int do_efi_capsule_show(struct cmd_tbl *cmdtp, int flag, + int argc, char * const argv[]) +{ + struct efi_capsule_header *capsule; + char *endp; + + if (argc != 2) + return CMD_RET_USAGE; + + capsule = (typeof(capsule))simple_strtoul(argv[1], &endp, 16); + if (endp == argv[1]) { + printf("Invalid address: %s", argv[1]); + return CMD_RET_FAILURE; + } + + printf("Capsule guid: %pUl\n", &capsule->capsule_guid); + printf("Capsule flags: 0x%x\n", capsule->flags); + printf("Capsule header size: 0x%x\n", capsule->header_size); + printf("Capsule image size: 0x%x\n", + capsule->capsule_image_size); + + return CMD_RET_SUCCESS; +} + +/** + * do_efi_capsule_res() - show a capsule update result + * + * @cmdtp: Command table + * @flag: Command flag + * @argc: Number of arguments + * @argv: Argument array + * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure + * + * Implement efidebug "capsule result" sub-command. + * show a capsule update result. + * If result number is not specified, CapsuleLast will be shown. + * + * efidebug capsule result [] + */ +static int do_efi_capsule_res(struct cmd_tbl *cmdtp, int flag, + int argc, char * const argv[]) +{ + int capsule_id; + char *endp; + char var_name[12]; + u16 var_name16[12], *p; + efi_guid_t guid; + struct efi_capsule_result_variable_header *result = NULL; + efi_uintn_t size; + efi_status_t ret; + + if (argc != 1 && argc != 2) + return CMD_RET_USAGE; + + guid = efi_guid_capsule_report; + if (argc == 1) { + size = sizeof(var_name16); + ret = EFI_CALL(RT->get_variable(L"CapsuleLast", &guid, NULL, + &size, var_name16)); + if (ret != EFI_SUCCESS) { + if (ret == EFI_NOT_FOUND) + printf("CapsuleLast doesn't exist\n"); + else + printf("Failed to get CapsuleLast\n"); + + return CMD_RET_FAILURE; + } + printf("CapsuleLast is %ls\n", var_name16); + } else { + argc--; + argv++; + + capsule_id = simple_strtoul(argv[0], &endp, 16); + if (capsule_id < 0 || capsule_id > 0xffff) + return CMD_RET_USAGE; + + sprintf(var_name, "Capsule%04X", capsule_id); + p = var_name16; + utf8_utf16_strncpy(&p, var_name, 9); + } + + size = 0; + ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, NULL)); + if (ret == EFI_BUFFER_TOO_SMALL) { + result = malloc(size); + ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, + result)); + if (ret != EFI_SUCCESS) { + free(result); + printf("Failed to get %ls\n", var_name16); + + return CMD_RET_FAILURE; + } + } + + printf("Result total size: 0x%x\n", result->variable_total_size); + printf("Capsule guid: %pUl\n", &result->capsule_guid); + printf("Time processed: %04d-%02d-%02d %02d:%02d:%02d\n", + result->capsule_processed.year, result->capsule_processed.month, + result->capsule_processed.day, result->capsule_processed.hour, + result->capsule_processed.minute, + result->capsule_processed.second); + printf("Capsule status: 0x%lx\n", result->capsule_status); + + free(result); + + return CMD_RET_SUCCESS; +} + +static struct cmd_tbl cmd_efidebug_capsule_sub[] = { + U_BOOT_CMD_MKENT(update, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_update, + "", ""), + U_BOOT_CMD_MKENT(show, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_show, + "", ""), + U_BOOT_CMD_MKENT(result, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_res, + "", ""), +}; + +/** + * do_efi_capsule() - manage UEFI capsules + * + * @cmdtp: Command table + * @flag: Command flag + * @argc: Number of arguments + * @argv: Argument array + * Return: CMD_RET_SUCCESS on success, + * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure + * + * Implement efidebug "capsule" sub-command. + */ +static int do_efi_capsule(struct cmd_tbl *cmdtp, int flag, + int argc, char * const argv[]) +{ + struct cmd_tbl *cp; + + if (argc < 2) + return CMD_RET_USAGE; + + argc--; argv++; + + cp = find_cmd_tbl(argv[0], cmd_efidebug_capsule_sub, + ARRAY_SIZE(cmd_efidebug_capsule_sub)); + if (!cp) + return CMD_RET_USAGE; + + return cp->cmd(cmdtp, flag, argc, argv); +} +#endif /* CONFIG_EFI_HAVE_CAPSULE_SUPPORT */ /** * efi_get_device_handle_info() - get information of UEFI device @@ -1232,6 +1454,10 @@ static int do_efi_query_info(struct cmd_tbl *cmdtp, int flag, static struct cmd_tbl cmd_efidebug_sub[] = { U_BOOT_CMD_MKENT(boot, CONFIG_SYS_MAXARGS, 1, do_efi_boot_opt, "", ""), +#ifdef CONFIG_EFI_HAVE_CAPSULE_SUPPORT + U_BOOT_CMD_MKENT(capsule, CONFIG_SYS_MAXARGS, 1, do_efi_capsule, + "", ""), +#endif U_BOOT_CMD_MKENT(devices, CONFIG_SYS_MAXARGS, 1, do_efi_show_devices, "", ""), U_BOOT_CMD_MKENT(drivers, CONFIG_SYS_MAXARGS, 1, do_efi_show_drivers, @@ -1306,6 +1532,15 @@ static char efidebug_help_text[] = "efidebug boot order [ [ [ [...]]]]\n" " - set/show UEFI boot order\n" "\n" +#ifdef CONFIG_EFI_HAVE_CAPSULE_SUPPORT + "efidebug capsule update [-v] \n" + " - process a capsule\n" + "efidebug capsule show \n" + " - show capsule information\n" + "efidebug capsule result []\n" + " - show a capsule update result\n" + "\n" +#endif "efidebug devices\n" " - show UEFI devices\n" "efidebug drivers\n" From patchwork Mon Sep 7 05:34:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358588 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=kcSYI1TO; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlHDw5SP2z9sSP for ; Mon, 7 Sep 2020 15:40:32 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5671782520; Mon, 7 Sep 2020 07:36:51 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="kcSYI1TO"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 9433E824F8; Mon, 7 Sep 2020 07:36:34 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,SPF_HELO_NONE,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from mail-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) (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 9A03B824ED for ; Mon, 7 Sep 2020 07:36:24 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pg1-x52f.google.com with SMTP id 67so7481146pgd.12 for ; Sun, 06 Sep 2020 22:36:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Z+/O5+FTtGlaZoI0+NvnfBAMCvpzihjClRuaSmYgNho=; b=kcSYI1TOgupx6E6tXEknsH1xjIsg5M+ywcJcDCqeAjFpBNyWxWfC/Lbf3F6EjwZopU DeEq8JUnYBYrosxhhCyP/R6mkeVr/BzORruTOlghBe1PSRkTnuKqpFtUUGwJgNq1e7Zq 4vh4G05uRQUOIJnFhpi9GMob2mYKESGB02q/hAeNUiRqjMs76iyNVd9zjAj0VTtgbTLZ XnTFkvulgdjshTImuJ684TJCDFA3i9yjWw1HpHA1IIkdvZ0rvXmlBMOVS5Ckfey+huHJ jeBYqSZVAeRrM7Vyp0az8ffISw7y1gYXNbhesj1SXeALhlCLU9mC2/86WfS0hBV6AUuA ZJMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Z+/O5+FTtGlaZoI0+NvnfBAMCvpzihjClRuaSmYgNho=; b=G9gjlrOW+PVkhCggO0FqcUmKT7gmqoWAflOc7CgPshUKK0OaSoEFRV+yYxYFeKn54r Iqrx1kE1y0jPextNVhfC/yB1DbkVFOQRcoK7OOj9PXaNiSQ12gvs/30agFVhLPPaEcGl FOoFuIVRKgiTMX3z/Vl1JsAuKDjzFHiM0M2FurxKdbjb5uAn/cWhmAHaSHXhA1rKuqb4 bzrc2HhpW5fJ8UCMagd5LNzDo1S5iV+G4aC9GQX1E8oJoLWGXzo2CaYqgC9ABMM771Xq pfocguqZwI7RirqwYr1yglUjzaRMec1JttliQT8B/yZ3V4dkZyZX5ubFLzvsfKreo+Xm xPZA== X-Gm-Message-State: AOAM530OmQQWkCGnUH+KmaQgBpzDCbEU1HwulD5hPIMim4VAp0Ckx32N awgVZPameyvSG/HR2PmyuB8YNkAGewmSzcbt X-Google-Smtp-Source: ABdhPJwTwKB18YHZvUdh0cCfCiXlX3ZFCbXLd6uj4nA4M4SGakiRPrzf6BF9TngZ2ypzkzj0SlJ4MA== X-Received: by 2002:aa7:91d9:: with SMTP id z25mr19357084pfa.116.1599456982929; Sun, 06 Sep 2020 22:36:22 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.36.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:36:22 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 15/17] tools: add mkeficapsule command for UEFI capsule update Date: Mon, 7 Sep 2020 14:34:24 +0900 Message-Id: <20200907053426.1675646-16-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean This is a utility mainly for test purpose. mkeficapsule -f: create a test capsule file for FIT image firmware Having said that, you will be able to customize the code to fit your specific requirements for your platform. Signed-off-by: AKASHI Takahiro --- tools/Makefile | 2 + tools/mkeficapsule.c | 238 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 tools/mkeficapsule.c diff --git a/tools/Makefile b/tools/Makefile index 51123fd92983..66d9376803e3 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -218,6 +218,8 @@ hostprogs-$(CONFIG_MIPS) += mips-relocs hostprogs-$(CONFIG_ASN1_COMPILER) += asn1_compiler HOSTCFLAGS_asn1_compiler.o = -idirafter $(srctree)/include +hostprogs-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += mkeficapsule + # We build some files with extra pedantic flags to try to minimize things # that won't build on some weird host compiler -- though there are lots of # exceptions for files that aren't complaint. diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c new file mode 100644 index 000000000000..db95426457cc --- /dev/null +++ b/tools/mkeficapsule.c @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2018 Linaro Limited + * Author: AKASHI Takahiro + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef __u8 u8; +typedef __u16 u16; +typedef __u32 u32; +typedef __u64 u64; +typedef __s16 s16; +typedef __s32 s32; + +#define aligned_u64 __aligned_u64 + +#ifndef __packed +#define __packed __attribute__((packed)) +#endif + +#include +#include + +static const char *tool_name = "mkeficapsule"; + +efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; +efi_guid_t efi_guid_image_type_uboot_fit = + EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; +efi_guid_t efi_guid_image_type_uboot_raw = + EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; + +static struct option options[] = { + {"fit", required_argument, NULL, 'f'}, + {"raw", required_argument, NULL, 'r'}, + {"index", required_argument, NULL, 'i'}, + {"instance", required_argument, NULL, 'I'}, + {"version", required_argument, NULL, 'v'}, + {"help", no_argument, NULL, 'h'}, + {NULL, 0, NULL, 0}, +}; + +static void print_usage(void) +{ + printf("Usage: %s [options] \n" + "Options:\n" + "\t--fit new FIT image file\n" + "\t--raw new raw image file\n" + "\t--index update image index\n" + "\t--instance update hardware instance\n" + "\t--version firmware version\n" + "\t--help print a help message\n", + tool_name); +} + +static int create_fwbin(char *path, char *bin, efi_guid_t *guid, + unsigned long version, unsigned long index, + unsigned long instance) +{ + struct efi_capsule_header header; + struct efi_firmware_management_capsule_header capsule; + struct efi_firmware_management_capsule_image_header image; + FILE *f, *g; + struct stat bin_stat; + u8 *data; + size_t size; + +#ifdef DEBUG + printf("For output: %s\n", path); + printf("\tbin: %s\n\ttype: %pUl\n" bin, guid); + printf("\tversion: %ld\n\tindex: %ld\n\tinstance: %ld\n", + version, index, instance); +#endif + + g = fopen(bin, "r"); + if (!g) { + printf("cannot open %s\n", bin); + return -1; + } + if (stat(bin, &bin_stat) < 0) { + printf("cannot determine the size of %s\n", bin); + goto err_1; + } + data = malloc(bin_stat.st_size); + if (!data) { + printf("cannot allocate memory: %lx\n", bin_stat.st_size); + goto err_1; + } + f = fopen(path, "w"); + if (!f) { + printf("cannot open %s\n", path); + goto err_2; + } + header.capsule_guid = efi_guid_fm_capsule; + header.header_size = sizeof(header); + header.flags = CAPSULE_FLAGS_PERSIST_ACROSS_RESET; /* TODO */ + header.capsule_image_size = sizeof(header) + + sizeof(capsule) + sizeof(u64) + + sizeof(image) + + bin_stat.st_size; + + size = fwrite(&header, 1, sizeof(header), f); + if (size < sizeof(header)) { + printf("write failed (%lx)\n", size); + goto err_3; + } + + capsule.version = 0x00000001; + capsule.embedded_driver_count = 0; + capsule.payload_item_count = 1; + capsule.item_offset_list[0] = sizeof(capsule) + sizeof(u64); + size = fwrite(&capsule, 1, sizeof(capsule) + sizeof(u64), f); + if (size < (sizeof(capsule) + sizeof(u64))) { + printf("write failed (%lx)\n", size); + goto err_3; + } + + image.version = version; + memcpy(&image.update_image_type_id, guid, sizeof(*guid)); + image.update_image_index = index; + image.update_image_size = bin_stat.st_size; + image.update_vendor_code_size = 0; /* none */ + image.update_hardware_instance = instance; + image.image_capsule_support = 0; + + size = fwrite(&image, 1, sizeof(image), f); + if (size < sizeof(image)) { + printf("write failed (%lx)\n", size); + goto err_3; + } + size = fread(data, 1, bin_stat.st_size, g); + if (size < bin_stat.st_size) { + printf("read failed (%lx)\n", size); + goto err_3; + } + size = fwrite(data, 1, bin_stat.st_size, f); + if (size < bin_stat.st_size) { + printf("write failed (%lx)\n", size); + goto err_3; + } + + fclose(f); + fclose(g); + free(data); + + return 0; + +err_3: + fclose(f); +err_2: + free(data); +err_1: + fclose(g); + + return -1; +} + +/* + * Usage: + * $ mkeficapsule -f + */ +int main(int argc, char **argv) +{ + char *file; + efi_guid_t *guid; + unsigned long index, instance, version; + int c, idx; + + file = NULL; + guid = NULL; + index = 0; + instance = 0; + version = 0; + for (;;) { + c = getopt_long(argc, argv, "f:r:i:I:v:h", options, &idx); + if (c == -1) + break; + + switch (c) { + case 'f': + if (file) { + printf("Image already specified\n"); + return -1; + } + file = optarg; + guid = &efi_guid_image_type_uboot_fit; + break; + case 'r': + if (file) { + printf("Image already specified\n"); + return -1; + } + file = optarg; + guid = &efi_guid_image_type_uboot_raw; + break; + case 'i': + index = strtoul(optarg, NULL, 0); + break; + case 'I': + instance = strtoul(optarg, NULL, 0); + break; + case 'v': + version = strtoul(optarg, NULL, 0); + break; + case 'h': + print_usage(); + return 0; + } + } + + /* need a output file */ + if (argc != optind + 1) { + print_usage(); + return -1; + } + + /* need a fit image file or raw image file */ + if (!file) { + print_usage(); + return -1; + } + + if (create_fwbin(argv[optind], file, guid, version, index, instance) + < 0) { + printf("Creating firmware capsule failed\n"); + return -1; + } + + return 0; +} From patchwork Mon Sep 7 05:34:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358589 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=hQV5Sz6s; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlHFG1XnNz9sSP for ; Mon, 7 Sep 2020 15:40:50 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 50EBE82525; Mon, 7 Sep 2020 07:36:52 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="hQV5Sz6s"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 6CA7A824FD; Mon, 7 Sep 2020 07:36:39 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x429.google.com (mail-pf1-x429.google.com [IPv6:2607:f8b0:4864:20::429]) (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 749EA824F7 for ; Mon, 7 Sep 2020 07:36:32 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pf1-x429.google.com with SMTP id o68so8053249pfg.2 for ; Sun, 06 Sep 2020 22:36:32 -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=GrUY44MWtP94MIIWPjtp35v3JdOgqmo3bkTAwU/kFBk=; b=hQV5Sz6sizJOtiopKJ6YaqPp9xdr5R/h04+W1dSVUQxP1mBQXOWTbbGl80D3i09Ygr 8Js9t7TZpcYIzCSOb+zDFkmdxzi8R+hmH0Twkq7W9RxH8d8hajU9Uzrc/BTd1wSdeWg/ tCYvB6CwR0z9mVyzg0AvFAh7dZytL9oaY+Y+kw/PSuPC7/+XOjXBd1rgwR2wNgm1f/HV 71nIzTWMCsskYtYfTYGDbVtB7ZCbFo2Uc3he7jsY7EF12juk9fAQM0AI2I+MPvbrp3nH 5P+YLjgO80fsrChiHKufjhiAERbbNsFpkD4p2OOf78J7M6sRXrPrJaXG4s5iGgsDyWao mNaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=GrUY44MWtP94MIIWPjtp35v3JdOgqmo3bkTAwU/kFBk=; b=SvfyGJmaKM9bf6DR1vOz7j+UgbInMhIyqGD8rMhWaJGS+E6GQJOk9C9c48M2VfzKyu NAdFI0uN2N1sTFoQaTVAhi1jh9PcC66Zxl6qDMWwi8RbhPQO8lDJUSpLYFucWp2JAi2x amTe598u8nUoNtI4HZL6SHm65dSBEalpZ0Vi/doUCZ3eCnpRm8YlraGu8Ptdf+KxwDFh 4ul6vLP9Orzaau1uz6RBROXXMhKpgXNyOndopMoEDOzkYKvjgGLZDORy97OBHNnVW4eP 88BKRFot6u+vWqieoNXuAdENOHCtxQZxL6h0GvvErfSmVpJGirjkef2WDtDohdWZquF5 iYDw== X-Gm-Message-State: AOAM532INgZaJSf8ZJMoVNWsBFHXinlYsNqMmTxfNx0D+mODurToSQ/J Ye5xdkCamUl5hvDOXx5z9I3gbA== X-Google-Smtp-Source: ABdhPJwcpUVtME+sFjolIR7h/SlbX1Uqi1hFevC/agyEIfBT8FPSAFSrUW+Nn4YNhSOdvtrechXEHQ== X-Received: by 2002:a62:301:0:b029:13c:1611:6528 with SMTP id 1-20020a6203010000b029013c16116528mr17377250pfd.8.1599456985914; Sun, 06 Sep 2020 22:36:25 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.36.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:36:25 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 16/17] test/py: efi_capsule: test for FIT image capsule Date: Mon, 7 Sep 2020 14:34:25 +0900 Message-Id: <20200907053426.1675646-17-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean The test can run on sandbox build and it attempts to execute a firmware update via a capsule-on-disk, using a FIT image capsule, CONFIG_EFI_CAPSULE_FIT. To run this test successfully, you need configure U-Boot specifically; See test_capsule_firmware.py for requirements, and hence it won't run on Travis CI, at least, for now. Signed-off-by: AKASHI Takahiro --- test/py/tests/test_efi_capsule/conftest.py | 69 +++++++ test/py/tests/test_efi_capsule/defs.py | 12 ++ .../test_efi_capsule/test_capsule_firmware.py | 178 ++++++++++++++++++ .../tests/test_efi_capsule/uboot_bin_env.its | 36 ++++ tools/mkeficapsule.c | 3 +- 5 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 test/py/tests/test_efi_capsule/conftest.py create mode 100644 test/py/tests/test_efi_capsule/defs.py create mode 100644 test/py/tests/test_efi_capsule/test_capsule_firmware.py create mode 100644 test/py/tests/test_efi_capsule/uboot_bin_env.its diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py new file mode 100644 index 000000000000..4e7c36f04ba5 --- /dev/null +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2020, Linaro Limited +# Author: AKASHI Takahiro + +import os +import os.path +import re +from subprocess import call, check_call, check_output, CalledProcessError +import pytest +from defs import * + +# +# Fixture for UEFI secure boot test +# + + +@pytest.fixture(scope='session') +def efi_capsule_data(request, u_boot_config): + """Set up a file system to be used in UEFI capsule test. + + Args: + request: Pytest request object. + u_boot_config: U-boot configuration. + + Return: + A path to disk image to be used for testing + """ + mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule' + data_dir = mnt_point + CAPSULE_DATA_DIR + install_dir = mnt_point + CAPSULE_INSTALL_DIR + image_path = u_boot_config.persistent_data_dir + '/test_efi_capsule.img' + + try: + # Create a target device + check_call('dd if=/dev/zero of=./spi.bin bs=1MiB count=16', shell=True) + + check_call('rm -rf %s' % mnt_point, shell=True) + check_call('mkdir -p %s' % data_dir, shell=True) + check_call('mkdir -p %s' % install_dir, shell=True) + + # Create capsule files + # two regions: one for u-boot.bin and the other for u-boot.env + check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old -> u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, + shell=True) + check_call('sed -e \"s?BINFILE1?u-boot.bin.new?\" -e \"s?BINFILE2?u-boot.env.new?\" %s/test/py/tests/test_efi_capsule/uboot_bin_env.its > %s/uboot_bin_env.its' % + (u_boot_config.source_dir, data_dir), + shell=True) + check_call('cd %s; %s/tools/mkimage -f uboot_bin_env.its uboot_bin_env.itb' % + (data_dir, u_boot_config.build_dir), + shell=True) + check_call('cd %s; %s/tools/mkeficapsule --fit uboot_bin_env.itb --version 1 --index 1 Test01' % + (data_dir, u_boot_config.build_dir), + shell=True) + + # Create a disk image with EFI system partition + check_call('virt-make-fs --partition=gpt --size=+1M --type=vfat %s %s' % + (mnt_point, image_path), shell=True) + check_call('sgdisk %s -A 1:set:0 -t 1:C12A7328-F81F-11D2-BA4B-00A0C93EC93B' % + image_path, shell=True) + + except CalledProcessError as exception: + pytest.skip('Setup failed: %s' % exception.cmd) + return + else: + yield image_path + finally: + call('rm -rf %s' % mnt_point, shell=True) + call('rm -f %s' % image_path, shell=True) + call('rm -f ./spi.bin', shell=True) diff --git a/test/py/tests/test_efi_capsule/defs.py b/test/py/tests/test_efi_capsule/defs.py new file mode 100644 index 000000000000..2c5b0ee49beb --- /dev/null +++ b/test/py/tests/test_efi_capsule/defs.py @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0+ + +# Size in MiB +EFI_BOOTDEV_IMAGE_SIZE = 16 +EFI_BOOTDEV_PART_SIZE = 8 + +# Owner guid +GUID = '11111111-2222-3333-4444-123456789abc' + +# Directories +CAPSULE_DATA_DIR = '/EFI/CapsuleTestData' +CAPSULE_INSTALL_DIR = '/EFI/UpdateCapsule' diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware.py b/test/py/tests/test_efi_capsule/test_capsule_firmware.py new file mode 100644 index 000000000000..ab7c2a7d6bea --- /dev/null +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware.py @@ -0,0 +1,178 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2020, Linaro Limited +# Author: AKASHI Takahiro +# +# U-Boot UEFI: Firmware Update Test + +""" +This test verifies capsule-on-disk firmware update +""" + +from subprocess import check_call, check_output, CalledProcessError +import pytest +from defs import * + + +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('efi_capsule_firmware_fit') +@pytest.mark.buildconfigspec('efi_capsule_on_disk') +@pytest.mark.buildconfigspec('dfu') +@pytest.mark.buildconfigspec('dfu_sf') +@pytest.mark.buildconfigspec('cmd_efidebug') +@pytest.mark.buildconfigspec('cmd_fat') +@pytest.mark.buildconfigspec('cmd_memory') +@pytest.mark.buildconfigspec('cmd_nvedit_efi') +@pytest.mark.buildconfigspec('cmd_sf') +@pytest.mark.slow +class TestEfiCapsuleFirmwareFit(object): + def test_efi_capsule_fw1( + self, u_boot_config, u_boot_console, efi_capsule_data): + """ + Test Case 1 - Update U-Boot and U-Boot environment on SPI Flash + but with OsIndications unset + No update should happen + 0x100000-0x150000: U-Boot binary (but dummy) + 0x150000-0x200000: U-Boot environment (but dummy) + """ + disk_img = efi_capsule_data + with u_boot_console.log.section('Test Case 1-a, before reboot'): + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'efidebug boot add 1 TEST host 0:1 /helloworld.efi ""', + 'efidebug boot order 1', + 'env set -e OsIndications', + 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', + 'env save']) + + # initialize contents + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR, + 'sf write 4000000 100000 10', + 'sf read 5000000 100000 10', + 'md.b 5000000 10']) + assert 'Old' in ''.join(output) + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR, + 'sf write 4000000 150000 10', + 'sf read 5000000 150000 10', + 'md.b 5000000 10']) + assert 'Old' in ''.join(output) + + # place a capsule file + output = u_boot_console.run_command_list([ + 'fatload host 0:1 4000000 %s/Test01' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test01 $filesize' % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test01' in ''.join(output) + + # reboot + u_boot_console.restart_uboot() + + capsule_early = u_boot_config.buildconfig.get( + 'config_efi_capsule_on_disk_early') + with u_boot_console.log.section('Test Case 1-b, after reboot'): + if not capsule_early: + # make sure that dfu_alt_info exists even persistent variables + # are not available. + output = u_boot_console.run_command_list([ + 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test01' in ''.join(output) + + # need to run uefi command to initiate capsule handling + output = u_boot_console.run_command( + 'env print -e -all Capsule0000') + + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test01' in ''.join(output) + + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'sf read 4000000 100000 10', + 'md.b 4000000 10']) + assert 'u-boot:Old' in ''.join(output) + + output = u_boot_console.run_command_list([ + 'sf read 4000000 150000 10', + 'md.b 4000000 10']) + assert 'u-boot-env:Old' in ''.join(output) + + def test_efi_capsule_fw2( + self, u_boot_config, u_boot_console, efi_capsule_data): + """ + Test Case 2 - Update U-Boot and U-Boot environment on SPI Flash + 0x100000-0x150000: U-Boot binary (but dummy) + 0x150000-0x200000: U-Boot environment (but dummy) + """ + disk_img = efi_capsule_data + with u_boot_console.log.section('Test Case 2-a, before reboot'): + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'efidebug boot add 1 TEST host 0:1 /helloworld.efi ""', + 'efidebug boot order 1', + 'env set -e -nv -bs -rt OsIndications =0x0000000000000004', + 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', + 'env save']) + + # initialize contents + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR, + 'sf write 4000000 100000 10', + 'sf read 5000000 100000 10', + 'md.b 5000000 10']) + assert 'Old' in ''.join(output) + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR, + 'sf write 4000000 150000 10', + 'sf read 5000000 150000 10', + 'md.b 5000000 10']) + assert 'Old' in ''.join(output) + + # place a capsule file + output = u_boot_console.run_command_list([ + 'fatload host 0:1 4000000 %s/Test01' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test01 $filesize' % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test01' in ''.join(output) + + # reboot + u_boot_console.restart_uboot() + + capsule_early = u_boot_config.buildconfig.get( + 'config_efi_capsule_on_disk_early') + with u_boot_console.log.section('Test Case 2-b, after reboot'): + if not capsule_early: + # make sure that dfu_alt_info exists even persistent variables + # are not available. + output = u_boot_console.run_command_list([ + 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test01' in ''.join(output) + + # need to run uefi command to initiate capsule handling + output = u_boot_console.run_command( + 'env print -e -all Capsule0000') + + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test01' not in ''.join(output) + + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'sf read 4000000 100000 10', + 'md.b 4000000 10']) + assert 'u-boot:New' in ''.join(output) + + output = u_boot_console.run_command_list([ + 'sf read 4000000 150000 10', + 'md.b 4000000 10']) + assert 'u-boot-env:New' in ''.join(output) diff --git a/test/py/tests/test_efi_capsule/uboot_bin_env.its b/test/py/tests/test_efi_capsule/uboot_bin_env.its new file mode 100644 index 000000000000..31e2f8049f9a --- /dev/null +++ b/test/py/tests/test_efi_capsule/uboot_bin_env.its @@ -0,0 +1,36 @@ +/* + * Automatic software update for U-Boot + * Make sure the flashing addresses ('load' prop) is correct for your board! + */ + +/dts-v1/; + +/ { + description = "Automatic U-Boot environment update"; + #address-cells = <2>; + + images { + u-boot-bin@100000 { + description = "U-Boot binary on SPI Flash"; + data = /incbin/("BINFILE1"); + compression = "none"; + type = "firmware"; + arch = "sandbox"; + load = <0>; + hash-1 { + algo = "sha1"; + }; + }; + u-boot-env@150000 { + description = "U-Boot environment on SPI Flash"; + data = /incbin/("BINFILE2"); + compression = "none"; + type = "firmware"; + arch = "sandbox"; + load = <0>; + hash-1 { + algo = "sha1"; + }; + }; + }; +}; diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index db95426457cc..45e27d74a5e9 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -101,7 +101,8 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid, } header.capsule_guid = efi_guid_fm_capsule; header.header_size = sizeof(header); - header.flags = CAPSULE_FLAGS_PERSIST_ACROSS_RESET; /* TODO */ + /* TODO: The current implementation ignores flags */ + header.flags = CAPSULE_FLAGS_PERSIST_ACROSS_RESET; header.capsule_image_size = sizeof(header) + sizeof(capsule) + sizeof(u64) + sizeof(image) From patchwork Mon Sep 7 05:34:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1358590 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=Gpo3DHc6; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BlHFQ32WNz9sSn for ; Mon, 7 Sep 2020 15:40:58 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 428578252A; Mon, 7 Sep 2020 07:36:53 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Gpo3DHc6"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id C50EB82511; Mon, 7 Sep 2020 07:36:41 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id CD5B9824BB for ; Mon, 7 Sep 2020 07:36:35 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pl1-x633.google.com with SMTP id k13so2005937plk.3 for ; Sun, 06 Sep 2020 22:36:35 -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=vOZL7HMoUBm2QgX/veSjMfzSO/qPFQVDFF4KFNeP7Lw=; b=Gpo3DHc644IdWwgrxpcGHTI0ruKQVPn4G/E0RRMYn+Mhr4myKBV0SZSRVy5fd2THqA 11pBZbaHdKh+fAKtGktxG7XBCS1Ow2s9lFfTNR9RoW6Z99RJ6NQrCJHeZ6yi8ahs0pp9 oLxlDh5CtmqGd0jSZ3iaIJWM996ItufT8PZDskcrs1ZSHXk/gHJztFN5aLtW+Tid7orO G3Q/nXM7c9pHO44rbH4ciqJGDyjnRJld+sWUHNNOzj/VFuSbVAQy8ZluEw6v5um6yaIq NFRNQ3fvdyOIK6uRNcn9zkd7JpJvs0KoM2nstKDibY8VpUTn/5DN88K2/sLcP5P8K50U zaQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vOZL7HMoUBm2QgX/veSjMfzSO/qPFQVDFF4KFNeP7Lw=; b=ibkISj8dI7W7ZuvF0Mwskfe6WmtAkOjayv5PS6qAro+2Eo+H/0nrLC6bKBWBLiI5SX /tMM+C+DhJnqAbTDJGg7rm0asnBqU3AZTLHry/YkrdtmC3b8wb8k+3LI8cVJ8bmZdJpV 5gNld0rTF3RguhA499kqzbTYTrL8ANsqQvzKc0e89cKjQCq9GECYQNcKelISJkdTQwbn dtiRfnyWgUK4zLb/KLpwLQti1F6e3zg4GlUGq0uCKC85XGPdvJo8bK/pUSnL29vpzyJx R+tTfrD4Kp+tkQxDnusCyKO/zx9x5oGp9vhaBsL6EL3C2cQjmZaNFa6YsjveMaUGohcv HsVw== X-Gm-Message-State: AOAM531ty+XBl7Z4F7FztxhV1H9FfK93V2iBaqkSVRILU4DnxoqWV2YB 9OwMvaMuZkXnrro3Co1zudA/+g== X-Google-Smtp-Source: ABdhPJx9JxecsrpovCvH749oQAEy+YAf5mTrciUt8BGzcaq7XXAF5AnXB1+6WrWuJ2/0oMdigeg15Q== X-Received: by 2002:a17:90a:e64e:: with SMTP id ep14mr19423038pjb.173.1599456988851; Sun, 06 Sep 2020 22:36:28 -0700 (PDT) Received: from localhost.localdomain (p784a66b9.tkyea130.ap.so-net.ne.jp. [120.74.102.185]) by smtp.gmail.com with ESMTPSA id w6sm10783939pgr.82.2020.09.06.22.36.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Sep 2020 22:36:28 -0700 (PDT) From: AKASHI Takahiro To: lukma@denx.de, trini@konsulko.com, xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v6 17/17] test/py: efi_capsule: test for raw image capsule Date: Mon, 7 Sep 2020 14:34:26 +0900 Message-Id: <20200907053426.1675646-18-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200907053426.1675646-1-takahiro.akashi@linaro.org> References: <20200907053426.1675646-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean The test can run on sandbox build and it attempts to execute a firmware update via a capsule-on-disk, using a raw image capsule, CONFIG_EFI_CAPSULE_RAW. To run this test successfully, you need configure U-Boot specifically; See test_capsule_firmware.py for requirements, and hence it won't run on Travis CI, at least, for now. Signed-off-by: AKASHI Takahiro --- test/py/tests/test_efi_capsule/conftest.py | 3 + .../test_efi_capsule/test_capsule_firmware.py | 63 +++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index 4e7c36f04ba5..4544a24d5351 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -51,6 +51,9 @@ def efi_capsule_data(request, u_boot_config): check_call('cd %s; %s/tools/mkeficapsule --fit uboot_bin_env.itb --version 1 --index 1 Test01' % (data_dir, u_boot_config.build_dir), shell=True) + check_call('cd %s; %s/tools/mkeficapsule --raw u-boot.bin.new --version 1 --index 1 Test02' % + (data_dir, u_boot_config.build_dir), + shell=True) # Create a disk image with EFI system partition check_call('virt-make-fs --partition=gpt --size=+1M --type=vfat %s %s' % diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware.py b/test/py/tests/test_efi_capsule/test_capsule_firmware.py index ab7c2a7d6bea..c9b180ac65e8 100644 --- a/test/py/tests/test_efi_capsule/test_capsule_firmware.py +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware.py @@ -15,6 +15,7 @@ from defs import * @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('efi_capsule_firmware_fit') +@pytest.mark.buildconfigspec('efi_capsule_firmware_raw') @pytest.mark.buildconfigspec('efi_capsule_on_disk') @pytest.mark.buildconfigspec('dfu') @pytest.mark.buildconfigspec('dfu_sf') @@ -176,3 +177,65 @@ class TestEfiCapsuleFirmwareFit(object): 'sf read 4000000 150000 10', 'md.b 4000000 10']) assert 'u-boot-env:New' in ''.join(output) + + def test_efi_capsule_fw3( + self, u_boot_config, u_boot_console, efi_capsule_data): + """ + Test Case 3 - Update U-Boot on SPI Flash, raw image format + 0x100000-0x150000: U-Boot binary (but dummy) + """ + disk_img = efi_capsule_data + with u_boot_console.log.section('Test Case 3-a, before reboot'): + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'efidebug boot add 1 TEST host 0:1 /helloworld.efi ""', + 'efidebug boot order 1', + 'env set -e -nv -bs -rt OsIndications =0x0000000000000004', + 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', + 'env save']) + + # initialize content + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR, + 'sf write 4000000 100000 10', + 'sf read 5000000 100000 10', + 'md.b 5000000 10']) + assert 'Old' in ''.join(output) + + # place a capsule file + output = u_boot_console.run_command_list([ + 'fatload host 0:1 4000000 %s/Test02' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test02 $filesize' % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test02' in ''.join(output) + + # reboot + u_boot_console.restart_uboot() + + capsule_early = u_boot_config.buildconfig.get( + 'config_efi_capsule_on_disk_early') + with u_boot_console.log.section('Test Case 3-b, after reboot'): + if not capsule_early: + # make sure that dfu_alt_info exists even persistent variables + # are not available. + output = u_boot_console.run_command_list([ + 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test02' in ''.join(output) + + # need to run uefi command to initiate capsule handling + output = u_boot_console.run_command( + 'env print -e -all Capsule0000') + + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test02' not in ''.join(output) + + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'sf read 4000000 100000 10', + 'md.b 4000000 10']) + assert 'u-boot:New' in ''.join(output)