From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4CDF6C433EF for ; Fri, 21 Jan 2022 02:20:39 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 36164838FD; Fri, 21 Jan 2022 03:20:37 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="RYjQN11r"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id DA283838FE; Fri, 21 Jan 2022 03:20:35 +0100 (CET) Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) (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 5528C837DE for ; Fri, 21 Jan 2022 03:20:32 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pl1-x62c.google.com with SMTP id t18so7050061plg.9 for ; Thu, 20 Jan 2022 18:20:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:mail-followup-to:references :mime-version:content-disposition:in-reply-to; bh=5j19dsqp1q7dDtbHlm3reP8/P/B+D7OlDu37V1iFwaA=; b=RYjQN11rlATpgd+Hu3PPQ3cXNTCdbPXijBoB3UJQLxZEAds612dgHtCD6jRaMjuk78 JZDY/LDt3PW8tc9xIdEdS/2dayI/Zm1Hah1sGqaL0c/k5YXv2YOawQjmiuS+xbs3iWqZ QQ8UL+RQCXvH3+zqazTbG6k/q7X4ZkyO9n+9n6fR88n1Uv+fBTjgQ/FnpmCeioPeuIQK izZuXD6GHlKxo5m1Yj4R2YGozaUYhV5krY8usdtm+KWIWzBkGDk8/FhnSzvO7qs2JYdA lXcfFCl1lIJkHppwmy9vDwmB26C/c3x20e8JuR1u4hYe/Eg8k9SD4IVRSaiO3jUE62aJ mFjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id :mail-followup-to:references:mime-version:content-disposition :in-reply-to; bh=5j19dsqp1q7dDtbHlm3reP8/P/B+D7OlDu37V1iFwaA=; b=mUHrGVOvkq7lcNK4rzeK/yoG8h42+v7Pzwr1HnHI+yZ4m+ALxtpEZ3rlwpWUH6C1qn 0G4+tPutdliuiG/rQ7sTLE0B6n2x/UbH9WJn1nIJwY0+kU3X+RInWQUcOwCXEGy5jvZ4 PFEK4YB1d1c+T0ouCkXdYOTfHmtPZUmxMzaVlHyY3H3h1rKMjtxY2qNGVZdHXD2u5+bn tmXsa7eB19PkhMLylcc7wbfC9G+BHsrQn8XlyHTObgZ3/7rjU/Fe3IVKD71iSItZs98x u/qdPCIHzxYPlsbvlvz/HV6ytuAcmlBpdNQeB6SB9fxkouPn0bdewRKGg0ScXnSDdayg Tvgg== X-Gm-Message-State: AOAM532hZpxkxP9AzsIYMpdMyKSz370pyL3Djz+Fi5OtjjKD4oH7/ZCO xpLDW/Q5eNJOuXXUX8kGsc/Z9w== X-Google-Smtp-Source: ABdhPJz4kR3kALO+mPpXzaLPBqt/1ehnX9ajz9BlZIz6oKhmDadrFhcbYY6s0h0taCoZ78JNtI7ZMg== X-Received: by 2002:a17:902:6bc9:b0:149:b7bf:9b33 with SMTP id m9-20020a1709026bc900b00149b7bf9b33mr2099050plt.18.1642731630480; Thu, 20 Jan 2022 18:20:30 -0800 (PST) Received: from laputa ([2400:4050:c3e1:100:9dfa:ef9c:130b:a92f]) by smtp.gmail.com with ESMTPSA id nk11sm3531549pjb.55.2022.01.20.18.20.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Jan 2022 18:20:29 -0800 (PST) Date: Fri, 21 Jan 2022 11:20:25 +0900 From: AKASHI Takahiro To: Masami Hiramatsu Cc: u-boot@lists.denx.de, Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Tom Rini , Etienne Carriere , Sughosh Ganu , Paul Liu Subject: Re: [RFC PATCH 11/14] FWU: Add FWU Multi Bank Update on SPI Flash Message-ID: <20220121022025.GB44335@laputa> Mail-Followup-To: AKASHI Takahiro , Masami Hiramatsu , u-boot@lists.denx.de, Patrick Delaunay , Patrice Chotard , Heinrich Schuchardt , Alexander Graf , Simon Glass , Bin Meng , Ilias Apalodimas , Jose Marinho , Grant Likely , Tom Rini , Etienne Carriere , Sughosh Ganu , Paul Liu References: <164269255955.39378.260729958623102750.stgit@localhost> <164269267060.39378.17392247605833481024.stgit@localhost> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <164269267060.39378.17392247605833481024.stgit@localhost> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean On Fri, Jan 21, 2022 at 12:31:10AM +0900, Masami Hiramatsu wrote: > Signed-off-by: Masami Hiramatsu > --- > include/fwu.h | 13 ++ > lib/fwu_updates/Kconfig | 34 ++++++ > lib/fwu_updates/Makefile | 5 - > lib/fwu_updates/fwu_mdata_sf.c | 241 ++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 288 insertions(+), 5 deletions(-) > create mode 100644 lib/fwu_updates/fwu_mdata_sf.c > > diff --git a/include/fwu.h b/include/fwu.h > index 7af94988b7..a013170321 100644 > --- a/include/fwu.h > +++ b/include/fwu.h > @@ -64,9 +64,18 @@ int fwu_accept_image(efi_guid_t *img_type_id, u32 bank); > int fwu_clear_accept_image(efi_guid_t *img_type_id, u32 bank); > > int fwu_plat_get_update_index(u32 *update_idx); > -int fwu_plat_get_blk_desc(struct blk_desc **desc); > -int fwu_plat_get_alt_num(void *identifier); > int fwu_plat_fill_partition_guids(efi_guid_t **part_guid_arr); > void fwu_plat_get_bootidx(void *boot_idx); > > +#ifdef CONFIG_FWU_MULTI_BANK_UPDATE_GPT_BLK > +int fwu_plat_get_blk_desc(struct blk_desc **desc); > +int fwu_plat_get_alt_num(void *identifier); > +#endif We can (and should) remove "#ifdef ..." from headers. -Takahiro Akashi > +#ifdef CONFIG_FWU_MULTI_BANK_UPDATE_SF > +struct fwu_mdata_ops *fwu_sf_get_fwu_mdata_ops(void); > +int fwu_plat_get_image_alt_num(efi_guid_t image_type_id, u32 update_bank, > + int *alt_no); > +#endif > + > #endif /* _FWU_H_ */ > diff --git a/lib/fwu_updates/Kconfig b/lib/fwu_updates/Kconfig > index 0940a90747..8a369b9872 100644 > --- a/lib/fwu_updates/Kconfig > +++ b/lib/fwu_updates/Kconfig > @@ -38,3 +38,37 @@ config FWU_REBOOT_AFTER_UPDATE > Reboot the machine soon after installing a new firmware > and start trial boot. You can disable this option for > debugging or FWU development, but recommended to enable it. > + > +config FWU_MULTI_BANK_UPDATE_GPT_BLK > + bool "Enable FWU Multi Bank Update for GPT on blockdev" > + depends on FWU_MULTI_BANK_UPDATE > + select EFI_PARTITION > + help > + Enable FWU Multi Bank Update for GPT on a block device. This > + driver depends on GPT and the block device. FWU meatadata and > + firmware will be stored on a block device with GPT. > + > +config FWU_MULTI_BANK_UPDATE_SF > + bool "Enable FWU Multi Bank Update for SPI Flash" > + depends on FWU_MULTI_BANK_UPDATE > + help > + Enable FWU Multi Bank Update for SPI flash driver. This > + driver does not depend on GPT. Instead, the platform must > + provide some APIs and define the offset of the primary and > + the secondary metadata. > + > +config FWU_SF_PRIMARY_MDATA_OFFSET > + hex "The offset of the primary metadata" > + depends on FWU_MULTI_BANK_UPDATE_SF > + help > + The offset of the primary metadata on SPI Flash in > + hexadecimal. > + > +config FWU_SF_SECONDARY_MDATA_OFFSET > + hex "The offset of the secondary metadata" > + depends on FWU_MULTI_BANK_UPDATE_SF > + help > + The offset of the secondary metadata on SPI Flash in > + hexadecimal. > + This must NOT be the same offset of the primary > + metadata. > diff --git a/lib/fwu_updates/Makefile b/lib/fwu_updates/Makefile > index 73099a30cb..80669344f2 100644 > --- a/lib/fwu_updates/Makefile > +++ b/lib/fwu_updates/Makefile > @@ -6,6 +6,5 @@ > obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu_mdata.o > obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu.o > > -ifdef CONFIG_EFI_PARTITION > -obj-$(CONFIG_FWU_MULTI_BANK_UPDATE) += fwu_mdata_gpt_blk.o > -endif > +obj-$(CONFIG_FWU_MULTI_BANK_UPDATE_GPT_BLK) += fwu_mdata_gpt_blk.o > +obj-$(CONFIG_FWU_MULTI_BANK_UPDATE_SF) += fwu_mdata_sf.o > diff --git a/lib/fwu_updates/fwu_mdata_sf.c b/lib/fwu_updates/fwu_mdata_sf.c > new file mode 100644 > index 0000000000..9e3cae7b68 > --- /dev/null > +++ b/lib/fwu_updates/fwu_mdata_sf.c > @@ -0,0 +1,241 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (c) 2021, Linaro Limited > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > + > +/* > + * For the FWU SPI flash driver, the platform must define below functions > + * according to its dfu_alt_info. > + */ > +extern int fwu_plat_get_image_alt_num(efi_guid_t image_type_id, > + u32 update_bank, int *alt_no); > + > +static struct spi_flash *fwu_spi_flash; > + > +static int __fwu_sf_get_flash(void) > +{ > + if (IS_ENABLED(CONFIG_DM_SPI_FLASH)) { > + struct udevice *new; > + int ret; > + > + ret = spi_flash_probe_bus_cs(CONFIG_SF_DEFAULT_BUS, CONFIG_SF_DEFAULT_CS, > + CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE, > + &new); > + if (ret) > + return ret; > + > + fwu_spi_flash = dev_get_uclass_priv(new); > + } else { > + fwu_spi_flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, CONFIG_SF_DEFAULT_CS, > + CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE); > + if (!fwu_spi_flash) > + return -EIO; > + } > + return 0; > +} > + > +static int fwu_sf_get_flash(struct spi_flash **flash) > +{ > + int ret = 0; > + > + if (!fwu_spi_flash) > + ret = __fwu_sf_get_flash(); > + > + *flash = fwu_spi_flash; > + > + return ret; > +} > + > +static int sf_load_data(u32 offs, u32 size, void **data) > +{ > + struct spi_flash *flash; > + int ret; > + > + ret = fwu_sf_get_flash(&flash); > + if (ret < 0) > + return ret; > + > + *data = memalign(ARCH_DMA_MINALIGN, size); > + if (!*data) > + return -ENOMEM; > + > + ret = spi_flash_read(flash, offs, size, *data); > + if (ret < 0) { > + free(*data); > + *data = NULL; > + } > + > + return ret; > +} > + > +static int sf_save_data(u32 offs, u32 size, void *data) > +{ > + struct spi_flash *flash; > + u32 sect_size, nsect; > + void *buf; > + int ret; > + > + ret = fwu_sf_get_flash(&flash); > + if (ret < 0) > + return ret; > + > + sect_size = flash->mtd.erasesize; > + nsect = DIV_ROUND_UP(size, sect_size); > + ret = spi_flash_erase(flash, offs, nsect * sect_size); > + if (ret < 0) > + return ret; > + > + buf = memalign(ARCH_DMA_MINALIGN, size); > + if (!buf) > + return -ENOMEM; > + memcpy(buf, data, size); > + > + ret = spi_flash_write(flash, offs, size, buf); > + > + free(buf); > + > + return ret; > +} > + > +static int fwu_sf_load_mdata(struct fwu_mdata **mdata, u32 offs) > +{ > + int ret; > + > + ret = sf_load_data(offs, sizeof(struct fwu_mdata), (void **)mdata); > + > + if (ret >= 0) { > + ret = fwu_verify_mdata(*mdata, > + offs == CONFIG_FWU_SF_PRIMARY_MDATA_OFFSET); > + if (ret < 0) { > + free(*mdata); > + *mdata = NULL; > + } > + } > + > + return ret; > +} > + > +static int fwu_sf_load_primary_mdata(struct fwu_mdata **mdata) > +{ > + return fwu_sf_load_mdata(mdata, CONFIG_FWU_SF_PRIMARY_MDATA_OFFSET); > +} > + > +static int fwu_sf_load_secondary_mdata(struct fwu_mdata **mdata) > +{ > + return fwu_sf_load_mdata(mdata, CONFIG_FWU_SF_SECONDARY_MDATA_OFFSET); > +} > + > +static int fwu_sf_save_primary_mdata(struct fwu_mdata *mdata) > +{ > + return sf_save_data(CONFIG_FWU_SF_PRIMARY_MDATA_OFFSET, > + sizeof(struct fwu_mdata), mdata); > +} > + > +static int fwu_sf_save_secondary_mdata(struct fwu_mdata *mdata) > +{ > + return sf_save_data(CONFIG_FWU_SF_SECONDARY_MDATA_OFFSET, > + sizeof(struct fwu_mdata), mdata); > +} > + > +static int fwu_sf_get_valid_mdata(struct fwu_mdata **mdata) > +{ > + if (fwu_sf_load_primary_mdata(mdata) == 0) > + return 0; > + > + log_err("Failed to load/verify primary mdata. Try secondary.\n"); > + > + if (fwu_sf_load_secondary_mdata(mdata) == 0) > + return 0; > + > + log_err("Failed to load/verify secondary mdata.\n"); > + > + return -1; > +} > + > +static int fwu_sf_update_mdata(struct fwu_mdata *mdata) > +{ > + int ret; > + > + /* Update mdata crc32 field */ > + mdata->crc32 = crc32(0, (void *)&mdata->version, > + sizeof(*mdata) - sizeof(u32)); > + > + /* First write the primary mdata */ > + ret = fwu_sf_save_primary_mdata(mdata); > + if (ret < 0) { > + log_err("Failed to update the primary mdata.\n"); > + return ret; > + } > + > + /* And now the replica */ > + ret = fwu_sf_save_secondary_mdata(mdata); > + if (ret < 0) { > + log_err("Failed to update the secondary mdata.\n"); > + return ret; > + } > + > + return 0; > +} > + > +static int fwu_sf_mdata_check(void) > +{ > + struct fwu_mdata *primary = NULL, *secondary = NULL; > + int ret; > + > + ret = fwu_sf_load_primary_mdata(&primary); > + if (ret < 0) > + log_err("Failed to read the primary mdata: %d\n", ret); > + > + ret = fwu_sf_load_secondary_mdata(&secondary); > + if (ret < 0) > + log_err("Failed to read the secondary mdata: %d\n", ret); > + > + if (primary && secondary) { > + if (memcmp(primary, secondary, sizeof(struct fwu_mdata))) { > + log_err("The primary and the secondary mdata are different\n"); > + ret = -1; > + } > + } else if (primary) { > + ret = fwu_sf_save_secondary_mdata(primary); > + if (ret < 0) > + log_err("Restoring secondary mdata partition failed\n"); > + } else if (secondary) { > + ret = fwu_sf_save_primary_mdata(secondary); > + if (ret < 0) > + log_err("Restoring primary mdata partition failed\n"); > + } > + > + free(primary); > + free(secondary); > + return ret; > +} > + > +static int fwu_sf_get_mdata(struct fwu_mdata **mdata) > +{ > + return fwu_sf_get_valid_mdata(mdata); > +} > + > +static struct fwu_mdata_ops fwu_sf_mdata_ops = { > + .get_image_alt_num = fwu_plat_get_image_alt_num, > + .mdata_check = fwu_sf_mdata_check, > + .get_mdata = fwu_sf_get_mdata, > + .update_mdata = fwu_sf_update_mdata, > +}; > + > +struct fwu_mdata_ops *fwu_sf_get_fwu_mdata_ops(void) > +{ > + return &fwu_sf_mdata_ops; > +} >