mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Oleksij Rempel <o.rempel@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Oleksij Rempel <o.rempel@pengutronix.de>
Subject: [PATCH v1 3/7] commands: nvmem: Add support for creating dynamic rmem devices
Date: Fri, 30 May 2025 13:41:02 +0200	[thread overview]
Message-ID: <20250530114106.1009454-4-o.rempel@pengutronix.de> (raw)
In-Reply-To: <20250530114106.1009454-1-o.rempel@pengutronix.de>

The 'nvmem' command is extended to allow the creation of dynamic
RAM-backed NVMEM devices (rmem). This functionality is useful for
testing NVMEM operations, for scripts that require temporary, writable
NVMEM areas, or when a persistent NVMEM device is not available or
necessary.

This patch introduces the following new options to the 'nvmem' command:

-c : Creates a new rmem NVMEM device of the specified . The size can be
given with common suffixes (e.g., K, M). The command enforces that the
size is non-zero and does not exceed a defined maximum (NVMEM_MAX_SIZE,
defaulting to 1MB). This option requires CONFIG_NVMEM_RMEM to be
enabled.

-v : When used in conjunction with the -c option, this stores the name
of the newly created rmem device (e.g., "rmem0") into the environment
variable specified by . This allows subsequent commands or scripts to
easily reference the dynamic NVMEM device.

If invoked without any options, the 'nvmem' command retains its original
behavior of listing all currently available NVMEM devices.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 commands/nvmem.c | 124 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 118 insertions(+), 6 deletions(-)

diff --git a/commands/nvmem.c b/commands/nvmem.c
index a0e3d092e3cf..5f60e70e62c3 100644
--- a/commands/nvmem.c
+++ b/commands/nvmem.c
@@ -1,24 +1,136 @@
 // SPDX-License-Identifier: GPL-2.0
 // SPDX-FileCopyrightText: © 2021 Ahmad Fatoum, Pengutronix
 
-#include <common.h>
 #include <command.h>
+#include <common.h>
+#include <environment.h>
+#include <getopt.h>
 #include <linux/nvmem-consumer.h>
+#include <linux/sizes.h>
 
-static int do_nvmem(int argc, char *argv[])
+/* Maximum size for dynamically created NVMEM devices.
+ * This is a reasonable limit for RAM-backed devices, but can be adjusted
+ * based on system capabilities and requirements.
+ */
+#define NVMEM_MAX_SIZE		SZ_1M
+
+/* Static counter to ensure unique device IDs for dynamically created rmem
+ * devices
+ */
+static int dynamic_rmem_idx;
+
+/**
+ * nvmem_create_dynamic_rmem - Creates a dynamic RAM-backed NVMEM device.
+ * @create_size: Size of the NVMEM device to create.
+ * @var_name: Optional environment variable name to store the created device's
+ *            name.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+static int nvmem_create_dynamic_rmem(unsigned long create_size,
+				     const char *var_name)
+{
+	struct device *dev;
+	void *buffer;
+	int ret = 0;
+
+	buffer = xzalloc(create_size);
+	if (!buffer)
+		return -ENOMEM;
+
+	dev = add_generic_device("rmem", dynamic_rmem_idx, NULL,
+				 (resource_size_t)(uintptr_t)buffer,
+				 (resource_size_t)create_size,
+				 IORESOURCE_MEM, NULL);
+
+	if (var_name)
+		ret = setenv(var_name, dev_name(dev));
+
+	dynamic_rmem_idx++;
+
+	return ret;
+}
+
+static int nvmem_parse_and_validate_create_size(const char *size_arg,
+						unsigned long *out_size)
 {
-	nvmem_devices_print();
+
+	if (!IS_ENABLED(CONFIG_NVMEM_RMEM)) {
+		printf("Error: rmem NVMEM driver (CONFIG_NVMEM_RMEM) is not enabled in this build.\n");
+		return -EINVAL;
+	}
+
+	*out_size = strtoul_suffix(optarg, NULL, 0);
+	if (!*out_size) {
+		printf("Error: Invalid size '%s' for -c option. Must be non-zero.\n",
+		       optarg);
+		return COMMAND_ERROR_USAGE;
+	}
+
+	if (*out_size > NVMEM_MAX_SIZE) {
+		printf("Error: Size '%lu' exceeds maximum allowed size of %d bytes.\n",
+		       *out_size, NVMEM_MAX_SIZE);
+		return COMMAND_ERROR_USAGE;
+	}
 
 	return 0;
 }
 
+static int do_nvmem(int argc, char *argv[])
+{
+	unsigned long create_size = 0;
+	char *optarg_v = NULL;
+	int ret = 0;
+	int opt;
+
+	while ((opt = getopt(argc, argv, "c:v:h")) != -1) {
+		switch (opt) {
+		case 'c':
+			ret = nvmem_parse_and_validate_create_size(optarg,
+								&create_size);
+			if (ret < 0)
+				return ret;
+			break;
+		case 'v':
+			optarg_v = optarg;
+			break;
+		case 'h': /* fallthrough */
+		default:
+			return COMMAND_ERROR_USAGE;
+		}
+	}
+
+	if (optarg_v && !create_size) {
+		printf("Error: -v <VARNAME> option requires -c <SIZE> to create a device.\n");
+		return COMMAND_ERROR_USAGE;
+	}
+
+	if (create_size > 0)
+		ret = nvmem_create_dynamic_rmem(create_size, optarg_v);
+	else
+		nvmem_devices_print();
+
+	return ret;
+}
+
 BAREBOX_CMD_HELP_START(nvmem)
-BAREBOX_CMD_HELP_TEXT("Usage: nvmem")
-BAREBOX_CMD_HELP_END
+BAREBOX_CMD_HELP_TEXT("List NVMEM devices or create dynamic RAM-backed NVMEM")
+BAREBOX_CMD_HELP_TEXT("devices. If no arguments are provided, it lists all")
+BAREBOX_CMD_HELP_TEXT("available NVMEM devices.")
+BAREBOX_CMD_HELP_TEXT("")
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT("-c <size>", "Create a new RAM-backed NVMEM device of")
+BAREBOX_CMD_HELP_OPT("         ", "<size> bytes. (Requires CONFIG_NVMEM_RMEM")
+BAREBOX_CMD_HELP_OPT("         ", "to be enabled). <size> must be a non-zero.")
+BAREBOX_CMD_HELP_OPT("-v <variable>", "When using -c, set environment variable")
+BAREBOX_CMD_HELP_OPT("             ", "<variable> to the name of the created")
+BAREBOX_CMD_HELP_OPT("             ", "NVMEM device (e.g., rmem0).")
+BAREBOX_CMD_HELP_END;
 
 BAREBOX_CMD_START(nvmem)
 	.cmd		= do_nvmem,
-	BAREBOX_CMD_DESC("list nvmem devices")
+	BAREBOX_CMD_DESC("list or create NVMEM devices")
+	BAREBOX_CMD_OPTS("[-c <size> [-v <varname>]]")
 	BAREBOX_CMD_GROUP(CMD_GRP_HWMANIP)
 	BAREBOX_CMD_HELP(cmd_nvmem_help)
 BAREBOX_CMD_END
-- 
2.39.5




  parent reply	other threads:[~2025-05-30 11:44 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-30 11:40 [PATCH v1 0/7] NVMEM: Introduce write protection support Oleksij Rempel
2025-05-30 11:41 ` [PATCH v1 1/7] nvmem: Add 'protect' operation to core framework Oleksij Rempel
2025-06-02  9:04   ` Sascha Hauer
2025-05-30 11:41 ` [PATCH v1 2/7] nvmem: rmem: add write and protect support Oleksij Rempel
2025-06-02  9:33   ` Sascha Hauer
2025-05-30 11:41 ` Oleksij Rempel [this message]
2025-06-02  9:41   ` [PATCH v1 3/7] commands: nvmem: Add support for creating dynamic rmem devices Sascha Hauer
2025-05-30 11:41 ` [PATCH v1 4/7] regmap: Add reg_seal operation for hardware protection Oleksij Rempel
2025-06-02  9:47   ` Sascha Hauer
2025-05-30 11:41 ` [PATCH v1 5/7] nvmem: regmap: Implement protect operation using regmap_seal Oleksij Rempel
2025-06-02  9:57   ` Sascha Hauer
2025-05-30 11:41 ` [PATCH v1 6/7] nvmem: bsec: Implement NVMEM protect via regmap_seal for OTP locking Oleksij Rempel
2025-05-30 11:41 ` [PATCH v1 7/7] nvmem: rmem: Use unique device name for NVMEM registration Oleksij Rempel

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=20250530114106.1009454-4-o.rempel@pengutronix.de \
    --to=o.rempel@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /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