From patchwork Mon Jan 9 01:06:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jassi Brar X-Patchwork-Id: 640553 Delivered-To: patch@linaro.org Received: by 2002:a17:522:f3c4:b0:4b4:3859:abed with SMTP id in4csp1903709pvb; Sun, 8 Jan 2023 17:06:55 -0800 (PST) X-Google-Smtp-Source: AMrXdXsu2OQ+KnoIsbLJJusskR5gUSJGPmTYi+EP80O97JnGRyBofQLNHlQCU/FUQ2cRLYumi0qp X-Received: by 2002:a9d:5604:0:b0:67f:e4ff:2996 with SMTP id e4-20020a9d5604000000b0067fe4ff2996mr32180059oti.12.1673226414864; Sun, 08 Jan 2023 17:06:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1673226414; cv=none; d=google.com; s=arc-20160816; b=gdzw62g4UxN8RmI7+LParqqL2gYVd81EsRaNDVUE1gMSYKQcl38iD2jFb+Hpv0XQBX zzaHb596Sv1GCCpCM2J8M5HE2y1wZG6vfic9rEStLLXEQnSwpxRm46mhAJn0vs6SK6Dx fjXBnvV7ivTkOp+AUbXX0OdFKR27bZFwDxpQUm8xUmnZjXT7ycA37gkCUwP+LZ3RHYR7 iezEZKR/E27zOYpZMII0T5ugbvuJ0iyDKbC92SGWPbk3csqxliM9B9IcoxMAOIs8b5yt JoYl/skjO7tzc3raY1V+6vlRfg51HPzR9pyD34Xyzvh5oMZqE/hjQO07w3y8qE4KkPPI iQlQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=/ZAQ5zqws6ceae8ZmqG3wPDftxDEtnQ7miJCwDDx09c=; b=uFCsYNl2jzNYs3olUBGkwrMdb3rj4qHbXzK60CTjBC1J/RfQd0Wpy2ba0Hb+VEBNBk PL1CV9fRD73xBfVIirYbkih8PWVvsb3nzmpjVml58j+fQXIVuwGAPRtGEqLS3ThG8lAt GaEbCVNnXjanjJn6RJJbHvMp6TrSqsW3vAfd0mJQUtyD23gdfokYw6Rl5+pgKvlQhStR p7v1d6jQaSXppAlA/bSMTithTV4zXOZhz2mIwNfT+4xFjyRA0VeOdNEjS+N/jE9PZAME T1xjphIaov62dMS6D3HmNbP2O/CtDFN4OGqdm8STRgh+bySimaqVVS+QNk/SJ4SQGQcu DnzQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=AR7bSDXZ; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id w2-20020a9d77c2000000b0066c7b890c56si7321135otl.189.2023.01.08.17.06.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Jan 2023 17:06:54 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20210112 header.b=AR7bSDXZ; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id CFB0A8549A; Mon, 9 Jan 2023 02:06:52 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com 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=gmail.com header.i=@gmail.com header.b="AR7bSDXZ"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D008D8549C; Mon, 9 Jan 2023 02:06:50 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-il1-x12f.google.com (mail-il1-x12f.google.com [IPv6:2607:f8b0:4864:20::12f]) (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 91D468537F for ; Mon, 9 Jan 2023 02:06:47 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=jassisinghbrar@gmail.com Received: by mail-il1-x12f.google.com with SMTP id o8so4226456ilo.1 for ; Sun, 08 Jan 2023 17:06:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/ZAQ5zqws6ceae8ZmqG3wPDftxDEtnQ7miJCwDDx09c=; b=AR7bSDXZamUHB1FuDH6g3d7tAYZ4w3vNhvfe8z8UQMzKuK8aY1w1P9GiJuSM+lrqJF u8uYp4kyl5EZswyCtdWwYaz0sOvuU3ABKhihYxbWpKW25qD5oC+gLxlUJDEW7INz6e66 F3+MZczsBt6zEacEg30AxMXkQYoyS+vhyjO8K9VRDmkmph2OroQESLxp/NF80Mo5jT2k vlehIfwvSZBBujW50+c1My/G0WgIP1yXV41sMP7fPG/yzvGnRdBirVBuUk9yYvDkUCts meF4CCT5Fk1aLDRkHhSQcuqYOady+KED4yB1ri4rXUJq9vuFvxyATFl9JD/4YqFfpCIT tJzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/ZAQ5zqws6ceae8ZmqG3wPDftxDEtnQ7miJCwDDx09c=; b=o83NL0GjwG/q/cGJbIIZOIEVQvFLQyGcE1gGskHgw+kbp0njbYMeyYsXFWCgagVX8j XTtoNHfAkBdyVWuF7gdx1cocG6qypdzWFi/9syS8qLR7kItKZYH/M/UEahYDT8/1yIcT shqdk4P4FBp3RNMU6LUKsG1mImYt5x1uHqTXUw2iQzAdWEMdcFQta90z2nUszN6mZF4A TXF4Ycmp3Vb27pZMBSqVZPMaLA1Hug86ezLWo1x4A699zK8yUzbzcj/mtrxFDxUW+dBr 1uo5o8tMgaynv1A7E/TxgFpsbRWr1dC5QVRfSCb5vtd8DS96e08QN8XGEM+eecm/g/SO i9Qg== X-Gm-Message-State: AFqh2kqNsczKcNC759pBuQPN8HzGVXVotVM8gxqjn4PTAlGl5vBVclZZ gsE2UqA8bLslHumBVO4nkY1wH4OZ4p0= X-Received: by 2002:a05:6e02:13f2:b0:30d:9f9c:cd35 with SMTP id w18-20020a056e0213f200b0030d9f9ccd35mr2928676ilj.21.1673226405851; Sun, 08 Jan 2023 17:06:45 -0800 (PST) Received: from jassi-Alienware-x17-R2.. (wnpgmb0311w-ds01-45-177-228.dynamic.bellmts.net. [206.45.177.228]) by smtp.gmail.com with ESMTPSA id p32-20020a056638192000b0039e89ea68f9sm465328jal.135.2023.01.08.17.06.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Jan 2023 17:06:45 -0800 (PST) From: Jassi Brar X-Google-Original-From: Jassi Brar To: 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, Jassi Brar Subject: [PATCHv3 1/5] FWU: Add FWU metadata access driver for MTD storage regions Date: Sun, 8 Jan 2023 19:06:42 -0600 Message-Id: <20230109010642.578484-1-jaswinder.singh@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230109010601.578439-1-jaswinder.singh@linaro.org> References: <20230109010601.578439-1-jaswinder.singh@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean From: Sughosh Ganu 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: Sughosh Ganu Signed-off-by: Jassi Brar --- drivers/fwu-mdata/Kconfig | 15 +++ drivers/fwu-mdata/Makefile | 1 + drivers/fwu-mdata/raw_mtd.c | 201 ++++++++++++++++++++++++++++++++++++ 3 files changed, 217 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..edd28b4525 --- /dev/null +++ b/drivers/fwu-mdata/raw_mtd.c @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2023, Linaro Limited + */ + +#define LOG_CATEGORY UCLASS_FWU_MDATA + +#include +#include +#include +#include + +#include +#include + +/* Internal helper structure to move data around */ +struct fwu_mdata_mtd_priv { + struct mtd_info *mtd; + u32 pri_offset; + u32 sec_offset; +}; + +enum fwu_mtd_op { + FWU_MTD_READ, + FWU_MTD_WRITE, +}; + +#define FWU_MDATA_PRIMARY true +#define FWU_MDATA_SECONDARY false + +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); +} + +/** + * fwu_mdata_mtd_of_to_plat() - Translate from DT to fwu mdata device + */ +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; + int ret, size; + u32 phandle; + + /* 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 -ENOENT; + } + + /* Get the offset of primary and seconday mdata */ + ret = ofnode_read_u32_index(dev_ofnode(dev), "mdata-offsets", 0, + &mtd_priv->pri_offset); + if (ret) + return ret; + ret = ofnode_read_u32_index(dev_ofnode(dev), "mdata-offsets", 1, + &mtd_priv->sec_offset); + if (ret) + return ret; + + 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" }, + { } +}; + +U_BOOT_DRIVER(fwu_mdata_mtd) = { + .name = "fwu-mdata-mtd", + .id = UCLASS_FWU_MDATA, + .of_match = fwu_mdata_ids, + .ops = &fwu_mtd_ops, + .probe = fwu_mdata_mtd_probe, + .of_to_plat = fwu_mdata_mtd_of_to_plat, + .priv_auto = sizeof(struct fwu_mdata_mtd_priv), +};