From: Michal Simek <michal.simek@amd.com>
To: jassisinghbrar@gmail.com, u-boot@lists.denx.de
Cc: ilias.apalodimas@linaro.org, etienne.carriere@linaro.org,
trini@konsulko.com, sjg@chromium.org, sughosh.ganu@linaro.org,
xypron.glpk@gmx.de, takahiro.akashi@linaro.org,
Masami Hiramatsu <masami.hiramatsu@linaro.org>,
Jassi Brar <jaswinder.singh@linaro.org>
Subject: Re: [PATCH v4 1/6] FWU: Add FWU metadata access driver for MTD storage regions
Date: Wed, 29 Mar 2023 13:59:45 +0200 [thread overview]
Message-ID: <7bad6344-d0af-4ee2-e00f-c708d28fe1b7@amd.com> (raw)
In-Reply-To: <20230327211548.498919-1-jaswinder.singh@linaro.org>
On 3/27/23 23:15, jassisinghbrar@gmail.com wrote:
> From: Masami Hiramatsu <masami.hiramatsu@linaro.org>
>
> In the FWU Multi Bank Update feature, the information about the
> updatable images is stored as part of the metadata, on a separate
> region. Add a driver for reading from and writing to the metadata
> when the updatable images and the metadata are stored on a raw
> MTD region.
>
> Signed-off-by: Masami Hiramatsu <masami.hiramatsu@linaro.org>
> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
> ---
> drivers/fwu-mdata/Kconfig | 15 ++
> drivers/fwu-mdata/Makefile | 1 +
> drivers/fwu-mdata/raw_mtd.c | 272 ++++++++++++++++++++++++++++++++++++
> 3 files changed, 288 insertions(+)
> create mode 100644 drivers/fwu-mdata/raw_mtd.c
>
> diff --git a/drivers/fwu-mdata/Kconfig b/drivers/fwu-mdata/Kconfig
> index 36c4479a59..42736a5e43 100644
> --- a/drivers/fwu-mdata/Kconfig
> +++ b/drivers/fwu-mdata/Kconfig
> @@ -6,6 +6,11 @@ config FWU_MDATA
> FWU Metadata partitions reside on the same storage device
> which contains the other FWU updatable firmware images.
>
> +choice
> + prompt "Storage Layout Scheme"
> + depends on FWU_MDATA
> + default FWU_MDATA_GPT_BLK
> +
> config FWU_MDATA_GPT_BLK
> bool "FWU Metadata access for GPT partitioned Block devices"
> select PARTITION_TYPE_GUID
> @@ -14,3 +19,13 @@ config FWU_MDATA_GPT_BLK
> help
> Enable support for accessing FWU Metadata on GPT partitioned
> block devices.
> +
> +config FWU_MDATA_MTD
> + bool "Raw MTD devices"
> + depends on MTD
> + help
> + Enable support for accessing FWU Metadata on non-partitioned
> + (or non-GPT partitioned, e.g. partition nodes in devicetree)
> + MTD devices.
> +
> +endchoice
> diff --git a/drivers/fwu-mdata/Makefile b/drivers/fwu-mdata/Makefile
> index 3fee64c10c..06c49747ba 100644
> --- a/drivers/fwu-mdata/Makefile
> +++ b/drivers/fwu-mdata/Makefile
> @@ -6,3 +6,4 @@
>
> obj-$(CONFIG_FWU_MDATA) += fwu-mdata-uclass.o
> obj-$(CONFIG_FWU_MDATA_GPT_BLK) += gpt_blk.o
> +obj-$(CONFIG_FWU_MDATA_MTD) += raw_mtd.o
> diff --git a/drivers/fwu-mdata/raw_mtd.c b/drivers/fwu-mdata/raw_mtd.c
> new file mode 100644
> index 0000000000..4b1a10073a
> --- /dev/null
> +++ b/drivers/fwu-mdata/raw_mtd.c
> @@ -0,0 +1,272 @@
> +// SPDX-License-Identifier: GPL-2.0+
Just a note: Did you choose GPL-2.0+ by purpose? Or it is just c&p?
> +/*
> + * Copyright (c) 2023, Linaro Limited
> + */
> +
> +#define LOG_CATEGORY UCLASS_FWU_MDATA
> +
> +#include <fwu.h>
> +#include <fwu_mdata.h>
> +#include <memalign.h>
> +
> +#include <linux/errno.h>
> +#include <linux/types.h>
> +
> +/* Internal helper structure to move data around */
> +struct fwu_mdata_mtd_priv {
> + struct mtd_info *mtd;
> + char pri_label[50];
> + char sec_label[50];
> + u32 pri_offset;
> + u32 sec_offset;
> +};
> +
> +enum fwu_mtd_op {
> + FWU_MTD_READ,
> + FWU_MTD_WRITE,
> +};
> +
> +extern struct fwu_mtd_image_info fwu_mtd_images[];
if there is a need to share it. It should go to header.
And fwu_mtd_images[] is not defined when only this patch is applied.
It means order of patches is not right. 1/6 and 2/6 should be swapped
> +
> +static bool mtd_is_aligned_with_block_size(struct mtd_info *mtd, u64 size)
> +{
> + return !do_div(size, mtd->erasesize);
> +}
> +
> +static int mtd_io_data(struct mtd_info *mtd, u32 offs, u32 size, void *data,
> + enum fwu_mtd_op op)
> +{
> + struct mtd_oob_ops io_op = {};
> + u64 lock_offs, lock_len;
> + size_t len;
> + void *buf;
> + int ret;
> +
> + if (!mtd_is_aligned_with_block_size(mtd, offs)) {
> + log_err("Offset unaligned with a block (0x%x)\n", mtd->erasesize);
> + return -EINVAL;
> + }
> +
> + lock_offs = offs;
> + /* This will expand erase size to align with the block size */
> + lock_len = round_up(size, mtd->erasesize);
> +
> + ret = mtd_unlock(mtd, lock_offs, lock_len);
> + if (ret && ret != -EOPNOTSUPP)
> + return ret;
> +
> + if (op == FWU_MTD_WRITE) {
> + struct erase_info erase_op = {};
> +
> + erase_op.mtd = mtd;
> + erase_op.addr = lock_offs;
> + erase_op.len = lock_len;
> + erase_op.scrub = 0;
> +
> + ret = mtd_erase(mtd, &erase_op);
> + if (ret)
> + goto lock;
> + }
> +
> + /* Also, expand the write size to align with the write size */
> + len = round_up(size, mtd->writesize);
> +
> + buf = memalign(ARCH_DMA_MINALIGN, len);
> + if (!buf) {
> + ret = -ENOMEM;
> + goto lock;
> + }
> + memset(buf, 0xff, len);
> +
> + io_op.mode = MTD_OPS_AUTO_OOB;
> + io_op.len = len;
> + io_op.ooblen = 0;
> + io_op.datbuf = buf;
> + io_op.oobbuf = NULL;
> +
> + if (op == FWU_MTD_WRITE) {
> + memcpy(buf, data, size);
> + ret = mtd_write_oob(mtd, offs, &io_op);
> + } else {
> + ret = mtd_read_oob(mtd, offs, &io_op);
> + if (!ret)
> + memcpy(data, buf, size);
> + }
> + free(buf);
> +
> +lock:
> + mtd_lock(mtd, lock_offs, lock_len);
> +
> + return ret;
> +}
> +
> +static int fwu_mtd_read_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary)
> +{
> + struct fwu_mdata_mtd_priv *mtd_priv = dev_get_priv(dev);
> + struct mtd_info *mtd = mtd_priv->mtd;
> + u32 offs = primary ? mtd_priv->pri_offset : mtd_priv->sec_offset;
> +
> + return mtd_io_data(mtd, offs, sizeof(struct fwu_mdata), mdata, FWU_MTD_READ);
> +}
> +
> +static int fwu_mtd_write_mdata(struct udevice *dev, struct fwu_mdata *mdata, bool primary)
> +{
> + struct fwu_mdata_mtd_priv *mtd_priv = dev_get_priv(dev);
> + struct mtd_info *mtd = mtd_priv->mtd;
> + u32 offs = primary ? mtd_priv->pri_offset : mtd_priv->sec_offset;
> +
> + return mtd_io_data(mtd, offs, sizeof(struct fwu_mdata), mdata, FWU_MTD_WRITE);
> +}
> +
> +static int flash_partition_offset(struct udevice *dev, const char *part_name, fdt_addr_t *offset)
> +{
> + ofnode node, parts_node;
> + fdt_addr_t size = 0;
> +
> + parts_node = ofnode_by_compatible(dev_ofnode(dev), "fixed-partitions");
> + node = ofnode_by_prop_value(parts_node, "label", part_name, strlen(part_name) + 1);
> + if (!ofnode_valid(node)) {
> + log_err("Warning: Failed to find partition by label <%s>\n", part_name);
> + return -ENOENT;
> + }
> +
> + *offset = ofnode_get_addr_size_index_notrans(node, 0, &size);
> +
> + return (int)size;
> +}
> +
> +static int fwu_mdata_mtd_of_to_plat(struct udevice *dev)
> +{
> + struct fwu_mdata_mtd_priv *mtd_priv = dev_get_priv(dev);
> + const fdt32_t *phandle_p = NULL;
> + struct udevice *mtd_dev;
> + struct mtd_info *mtd;
> + const char *label;
> + fdt_addr_t offset;
> + int ret, size;
> + u32 phandle;
> + ofnode bank;
> + int off_img;
> +
> + /* Find the FWU mdata storage device */
> + phandle_p = ofnode_get_property(dev_ofnode(dev),
> + "fwu-mdata-store", &size);
> + if (!phandle_p) {
> + log_err("FWU meta data store not defined in device-tree\n");
> + return -ENOENT;
> + }
> +
> + phandle = fdt32_to_cpu(*phandle_p);
> +
> + ret = device_get_global_by_ofnode(ofnode_get_by_phandle(phandle),
> + &mtd_dev);
> + if (ret) {
> + log_err("FWU: failed to get mtd device\n");
> + return ret;
> + }
> +
> + mtd_probe_devices();
> +
> + mtd_for_each_device(mtd) {
> + if (mtd->dev == mtd_dev) {
> + mtd_priv->mtd = mtd;
> + log_debug("Found the FWU mdata mtd device %s\n", mtd->name);
> + break;
> + }
> + }
> + if (!mtd_priv->mtd) {
> + log_err("Failed to find mtd device by fwu-mdata-store\n");
> + return -ENODEV;
> + }
> +
> + /* Get the offset of primary and seconday mdata */
typo
> + ret = ofnode_read_string_index(dev_ofnode(dev), "mdata-parts", 0, &label);
> + if (ret)
> + return ret;
> + strcpy(mtd_priv->pri_label, label);
> +
> + ret = flash_partition_offset(mtd_dev, mtd_priv->pri_label, &offset);
> + if (ret <= 0)
> + return ret;
> + mtd_priv->pri_offset = offset;
> +
> + ret = ofnode_read_string_index(dev_ofnode(dev), "mdata-parts", 1, &label);
> + if (ret)
> + return ret;
> + strcpy(mtd_priv->sec_label, label);
> +
> + ret = flash_partition_offset(mtd_dev, mtd_priv->sec_label, &offset);
> + if (ret <= 0)
> + return ret;
> + mtd_priv->sec_offset = offset;
> +
> + off_img = 0;
> +
> + ofnode_for_each_subnode(bank, dev_ofnode(dev)) {
> + int bank_num, bank_offset, bank_size;
> + const char *bank_name;
> + ofnode image;
> +
> + ofnode_read_u32(bank, "id", &bank_num);
> + bank_name = ofnode_read_string(bank, "label");
> + bank_size = flash_partition_offset(mtd_dev, bank_name, &offset);
> + if (bank_size <= 0)
> + return bank_size;
> + bank_offset = offset;
> + log_debug("Bank%d: %s [0x%x - 0x%x]\n",
> + bank_num, bank_name, bank_offset, bank_offset + bank_size);
> +
> + ofnode_for_each_subnode(image, bank) {
> + int image_num, image_offset, image_size;
> + const char *uuid;
> +
> + if (off_img == CONFIG_FWU_NUM_BANKS *
> + CONFIG_FWU_NUM_IMAGES_PER_BANK) {
> + log_err("DT provides images more than configured!\n");
> + break;
> + }
> +
> + uuid = ofnode_read_string(image, "uuid");
> + ofnode_read_u32(image, "id", &image_num);
> + ofnode_read_u32(image, "offset", &image_offset);
> + ofnode_read_u32(image, "size", &image_size);
> +
> + fwu_mtd_images[off_img].start = bank_offset + image_offset;
> + fwu_mtd_images[off_img].size = image_size;
> + fwu_mtd_images[off_img].bank_num = bank_num;
> + fwu_mtd_images[off_img].image_num = image_num;
> + strcpy(fwu_mtd_images[off_img].uuidbuf, uuid);
> + log_debug("\tImage%d: %s @0x%x\n\n",
> + image_num, uuid, bank_offset + image_offset);
> + off_img++;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static int fwu_mdata_mtd_probe(struct udevice *dev)
> +{
> + /* Ensure the metadata can be read. */
> + return fwu_get_mdata(NULL);
> +}
> +
> +static struct fwu_mdata_ops fwu_mtd_ops = {
> + .read_mdata = fwu_mtd_read_mdata,
> + .write_mdata = fwu_mtd_write_mdata,
> +};
> +
> +static const struct udevice_id fwu_mdata_ids[] = {
> + { .compatible = "u-boot,fwu-mdata-mtd" },
> + { }
> +};
As I said this DT binding should be approved first to make sure that we don't
need to fix DT binding in future. Just simply do it right from the begining.
Thanks,
Michal
next prev parent reply other threads:[~2023-03-29 12:00 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-27 21:14 [PATCH v4 0/6] FWU: Add support for mtd backed feature on DeveloperBox jassisinghbrar
2023-03-27 21:15 ` [PATCH v4 1/6] FWU: Add FWU metadata access driver for MTD storage regions jassisinghbrar
2023-03-29 11:59 ` Michal Simek [this message]
2023-04-10 3:56 ` Jassi Brar
2023-04-14 13:56 ` Michal Simek
2023-04-14 15:09 ` Jassi Brar
2023-05-19 12:21 ` Ilias Apalodimas
2023-05-19 12:45 ` Michal Simek
2023-05-19 20:54 ` Tom Rini
2023-03-27 21:16 ` [PATCH v4 2/6] FWU: mtd: Add helper functions for accessing FWU metadata jassisinghbrar
2023-03-29 11:55 ` Michal Simek
2023-04-10 4:02 ` Jassi Brar
2023-03-27 21:16 ` [PATCH v4 3/6] tools: Add mkfwumdata tool for FWU metadata image jassisinghbrar
2023-03-29 12:28 ` Michal Simek
2023-04-10 4:05 ` Jassi Brar
2023-04-14 13:53 ` Michal Simek
2023-04-14 15:02 ` Jassi Brar
2023-04-17 6:37 ` Michal Simek
2023-04-17 13:48 ` Jassi Brar
2023-04-17 14:29 ` Michal Simek
2023-04-17 14:50 ` Jassi Brar
2023-03-29 20:02 ` Simon Glass
2023-04-10 4:25 ` Jassi Brar
2023-04-14 13:52 ` Michal Simek
2023-04-19 1:46 ` Simon Glass
2023-04-19 2:57 ` Jassi Brar
2023-04-19 22:40 ` Simon Glass
2023-03-30 6:07 ` Heinrich Schuchardt
2023-04-10 4:11 ` Jassi Brar
2023-03-27 21:16 ` [PATCH v4 4/6] dt: fwu: developerbox: enable fwu banks and mdata regions jassisinghbrar
2023-03-29 11:52 ` Michal Simek
2023-03-27 21:16 ` [PATCH v4 5/6] configs: move to new flash layout and boot flow jassisinghbrar
2023-03-27 21:16 ` [PATCH v4 6/6] fwu: DeveloperBox: add support for FWU jassisinghbrar
2023-03-29 13:01 ` Michal Simek
2023-04-10 4:21 ` Jassi Brar
2023-04-14 13:52 ` Michal Simek
2023-03-29 13:14 ` [PATCH v4 0/6] FWU: Add support for mtd backed feature on DeveloperBox Michal Simek
2023-03-30 13:35 ` Michal Simek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7bad6344-d0af-4ee2-e00f-c708d28fe1b7@amd.com \
--to=michal.simek@amd.com \
--cc=etienne.carriere@linaro.org \
--cc=ilias.apalodimas@linaro.org \
--cc=jassisinghbrar@gmail.com \
--cc=jaswinder.singh@linaro.org \
--cc=masami.hiramatsu@linaro.org \
--cc=sjg@chromium.org \
--cc=sughosh.ganu@linaro.org \
--cc=takahiro.akashi@linaro.org \
--cc=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
--cc=xypron.glpk@gmx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox