mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <a.fatoum@barebox.org>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@barebox.org>
Subject: [PATCH 2/6] param: support uuid/guid parameter type
Date: Thu, 15 Jan 2026 13:06:10 +0100	[thread overview]
Message-ID: <20260115120748.3433463-3-a.fatoum@barebox.org> (raw)
In-Reply-To: <20260115120748.3433463-1-a.fatoum@barebox.org>

Make UUIDs and GUIDs first class citizens for parameters by adding
dedicated dev_add_param_guid/uuid functions as well as globalvar_
wrappers.

We add different functions for both UUID and GUID to handle the
difference in string representation.

Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
---
 common/globalvar.c      | 40 +++++++++++++++++
 include/globalvar.h     | 12 ++++++
 include/linux/sprintf.h |  3 ++
 include/param.h         | 39 +++++++++++++++++
 lib/parameter.c         | 95 +++++++++++++++++++++++++++++++++++++++++
 lib/vsprintf.c          |  2 +-
 6 files changed, 190 insertions(+), 1 deletion(-)

diff --git a/common/globalvar.c b/common/globalvar.c
index fcaa15179f68..1fac891ae073 100644
--- a/common/globalvar.c
+++ b/common/globalvar.c
@@ -672,6 +672,46 @@ int globalvar_add_simple_ip(const char *name, IPaddr_t *ip)
 	return 0;
 }
 
+int globalvar_add_simple_uuid(const char *name, uuid_t *uuid)
+{
+	struct param_d *p;
+	int ret;
+
+	ret = globalvar_remove_unqualified(name);
+	if (ret)
+		return ret;
+
+	p = dev_add_param_uuid(&global_device, name,
+			       NULL, NULL, uuid, 0);
+
+	if (IS_ERR(p))
+		return PTR_ERR(p);
+
+	globalvar_nv_sync(name);
+
+	return 0;
+}
+
+int globalvar_add_simple_guid(const char *name, guid_t *guid)
+{
+	struct param_d *p;
+	int ret;
+
+	ret = globalvar_remove_unqualified(name);
+	if (ret)
+		return ret;
+
+	p = dev_add_param_guid(&global_device, name,
+			       NULL, NULL, guid, 0);
+
+	if (IS_ERR(p))
+		return PTR_ERR(p);
+
+	globalvar_nv_sync(name);
+
+	return 0;
+}
+
 static int globalvar_init(void)
 {
 	const char *endianness;
diff --git a/include/globalvar.h b/include/globalvar.h
index d0a8272588b4..e369616c632a 100644
--- a/include/globalvar.h
+++ b/include/globalvar.h
@@ -5,6 +5,7 @@
 #include <param.h>
 #include <driver.h>
 #include <linux/err.h>
+#include <linux/uuid.h>
 #include <stringlist.h>
 
 extern struct device global_device;
@@ -36,6 +37,8 @@ int globalvar_add_simple_enum(const char *name,	int *value,
 int globalvar_add_simple_bitmask(const char *name, unsigned long *value,
 				 const char * const *names, int max);
 int globalvar_add_simple_ip(const char *name, IPaddr_t *ip);
+int globalvar_add_simple_uuid(const char *name, uuid_t *uuid);
+int globalvar_add_simple_guid(const char *name, guid_t *guid);
 
 int nvvar_load(void);
 void nvvar_print(void);
@@ -101,6 +104,15 @@ static inline int globalvar_add_simple_ip(const char *name,
 	return 0;
 }
 
+static inline int globalvar_add_simple_uuid(const char *name, uuid_t *uuid)
+{
+	return 0;
+}
+static inline int globalvar_add_simple_guid(const char *name, guid_t *guid)
+{
+	return 0;
+}
+
 static inline void globalvar_remove(const char *name) {}
 
 static inline void globalvar_print(void) {}
diff --git a/include/linux/sprintf.h b/include/linux/sprintf.h
index 349773d3e16a..e4b3df959a72 100644
--- a/include/linux/sprintf.h
+++ b/include/linux/sprintf.h
@@ -43,6 +43,9 @@ static inline __printf(2, 3) int rasprintf(char **strp, const char *fmt, ...)
 
 #define basprintf xasprintf
 
+char *uuid_string(char *buf, const char *end, const u8 *addr, int field_width,
+		  int precision, int flags, const char *fmt);
 const char *size_human_readable(unsigned long long size);
 
+
 #endif	/* _LINUX_KERNEL_SPRINTF_H */
diff --git a/include/param.h b/include/param.h
index 1713a18c378e..c223114fbde1 100644
--- a/include/param.h
+++ b/include/param.h
@@ -5,6 +5,7 @@
 #include <linux/err.h>
 #include <linux/types.h>
 #include <linux/list.h>
+#include <linux/uuid.h>
 #include <bobject.h>
 #include <stdarg.h>
 
@@ -27,6 +28,8 @@ enum param_type {
 	PARAM_TYPE_IPV4,
 	PARAM_TYPE_MAC,
 	PARAM_TYPE_FILE_LIST,
+	PARAM_TYPE_UUID,
+	PARAM_TYPE_GUID,
 };
 
 struct param_d {
@@ -106,6 +109,12 @@ struct param_d *bobject_add_param_file_list(bobject_t bobj, const char *name,
 					struct file_list **file_list,
 					void *priv);
 
+struct param_d *__bobject_add_param_uuid(bobject_t _bobj, const char *name,
+					 int (*set)(struct param_d *p, void *priv),
+					 int (*get)(struct param_d *p, void *priv),
+					 void *uuid, bool is_guid,
+					 void *priv);
+
 struct param_d *vbobject_add_param_fixed(struct bobject *bobj, const char *name,
 					 const char *fmt, va_list ap);
 
@@ -233,6 +242,15 @@ static inline struct param_d *bobject_add_param_file_list(bobject_t bobj,
 	return NULL;
 }
 
+static inline struct param_d *__bobject_add_param_uuid(bobject_t _bobj, const char *name,
+						       int (*set)(struct param_d *p, void *priv),
+						       int (*get)(struct param_d *p, void *priv),
+						       void *uuid, bool is_guid,
+						       void *priv)
+{
+	return NULL;
+}
+
 static inline
 struct param_d *vbobject_add_param_fixed(struct bobject *bobj, const char *name,
 					 const char *fmt, va_list ap)
@@ -273,6 +291,25 @@ static inline const char *get_param_value(struct param_d *param)
 	return param->get(param->bobj, param);
 }
 
+static inline struct param_d *
+bobject_add_param_uuid(bobject_t _bobj, const char *name,
+		       int (*set)(struct param_d *p, void *priv),
+		       int (*get)(struct param_d *p, void *priv),
+		       uuid_t *uuid, void *priv)
+{
+	return __bobject_add_param_uuid(_bobj, name, set, get, uuid, false, priv);
+}
+
+static inline struct param_d *
+bobject_add_param_guid(bobject_t _bobj, const char *name,
+		       int (*set)(struct param_d *p, void *priv),
+		       int (*get)(struct param_d *p, void *priv),
+		       guid_t *guid, void *priv)
+{
+	return __bobject_add_param_uuid(_bobj, name, set, get, guid, true, priv);
+}
+
+
 int param_set_readonly(struct param_d *p, void *priv);
 
 /*
@@ -409,6 +446,8 @@ static inline struct param_d *bobject_add_param_bitmask_ro(bobject_t bobj,
 #define dev_add_param_ip		bobject_add_param_ip
 #define dev_add_param_mac		bobject_add_param_mac
 #define dev_add_param_file_list		bobject_add_param_file_list
+#define dev_add_param_uuid		bobject_add_param_uuid
+#define dev_add_param_guid		bobject_add_param_guid
 #define dev_param_set_generic		bobject_param_set_generic
 
 #define dev_add_param_int		bobject_add_param_int
diff --git a/lib/parameter.c b/lib/parameter.c
index 1243a12e8701..5c8b86d0dff3 100644
--- a/lib/parameter.c
+++ b/lib/parameter.c
@@ -42,6 +42,8 @@ static const char *param_type_string[] = {
 	[PARAM_TYPE_IPV4] = "ipv4",
 	[PARAM_TYPE_MAC] = "MAC",
 	[PARAM_TYPE_FILE_LIST] = "file-list",
+	[PARAM_TYPE_UUID] = "uuid",
+	[PARAM_TYPE_GUID] = "guid",
 };
 
 const char *get_param_type(struct param_d *param)
@@ -1095,6 +1097,99 @@ struct param_d *bobject_add_param_file_list(bobject_t _bobj, const char *name,
 	return &pfl->param;
 }
 
+struct param_uuid {
+	struct param_d param;
+	void *uuid;
+	char *uuid_str;
+	int (*set)(struct param_d *p, void *priv);
+	int (*get)(struct param_d *p, void *priv);
+};
+
+static inline struct param_uuid *to_param_uuid(struct param_d *p)
+{
+	return container_of(p, struct param_uuid, param);
+}
+
+static int param_uuid_set(struct bobject *bobj, struct param_d *p,
+			  const char *val)
+{
+	struct param_uuid *pui = to_param_uuid(p);
+	u8 uuid_save[UUID_SIZE];
+	int ret;
+
+	if (!val || strlen(val) == UUID_STRING_LEN)
+		return -EINVAL;
+
+	memcpy(uuid_save, pui->uuid, UUID_SIZE);
+
+	if (pui->param.type == PARAM_TYPE_GUID)
+		ret = guid_parse(val, pui->uuid);
+	else
+		ret = uuid_parse(val, pui->uuid);
+
+	if (ret)
+		return ret;
+
+	if (!pui->set)
+		return 0;
+
+	ret = pui->set(p, p->driver_priv);
+	if (ret)
+		memcpy(pui->uuid, uuid_save, UUID_SIZE);
+
+	return ret;
+}
+
+static const char *param_uuid_get(struct bobject *bobj, struct param_d *p)
+{
+	struct param_uuid *pui = to_param_uuid(p);
+	int ret;
+
+	if (pui->get) {
+		ret = pui->get(p, p->driver_priv);
+		if (ret)
+			return NULL;
+	}
+
+	p->value = xrealloc(p->value, UUID_STRING_LEN + 1);
+
+	/* We don't use xasprintf here to avoid forcing a PRINTF_UUID
+	 * dependency on all CONFIG_PARAMETER users
+	 */
+	*uuid_string(p->value, p->value + UUID_STRING_LEN + 1,
+		    pui->uuid, -1, -1, 0,
+		    pui->param.type == PARAM_TYPE_GUID ? "Ul" : "Ub") = '\0';
+
+	return p->value;
+}
+
+struct param_d *__bobject_add_param_uuid(bobject_t _bobj, const char *name,
+					 int (*set)(struct param_d *p, void *priv),
+					 int (*get)(struct param_d *p, void *priv),
+					 void *uuid, bool is_guid,
+					 void *priv)
+{
+	struct bobject *bobj = _bobj.bobj;
+	struct param_uuid *pui;
+	int ret;
+
+	pui = xzalloc(sizeof(*pui));
+	pui->uuid = uuid;
+	pui->set = set;
+	pui->get = get;
+	pui->param.driver_priv = priv;
+	pui->param.type = is_guid ? PARAM_TYPE_GUID : PARAM_TYPE_UUID;
+
+	ret = __bobject_add_param(&pui->param, bobj, name,
+			param_uuid_set, param_uuid_get, 0);
+	if (ret) {
+		free(pui);
+		return ERR_PTR(ret);
+	}
+
+	return &pui->param;
+}
+
 
 /**
  * param_remove - remove a parameter and free its memory
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 6c9dae467496..2dca20b8b0a3 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -321,7 +321,7 @@ char *error_string(char *buf, const char *end, const void *errptr, int field_wid
     return string(buf, end, strerror(-PTR_ERR(errptr)), field_width, precision, flags);
 }
 
-static noinline_for_stack
+noinline_for_stack
 char *uuid_string(char *buf, const char *end, const u8 *addr, int field_width,
 		  int precision, int flags, const char *fmt)
 {
-- 
2.47.3




  parent reply	other threads:[~2026-01-15 12:08 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-15 12:06 [PATCH 0/6] firmware: qemu_fw_cfg: improve support Ahmad Fatoum
2026-01-15 12:06 ` [PATCH 1/6] firmware: qemu_fw_cfg: use wider PIO reads if applicable Ahmad Fatoum
2026-01-15 12:06 ` Ahmad Fatoum [this message]
2026-01-15 12:06 ` [PATCH 3/6] lib: smbios: add support for setting product UUID Ahmad Fatoum
2026-01-15 12:06 ` [PATCH 4/6] common: boards: qemu: process some standard fw_cfg keys Ahmad Fatoum
2026-01-19 11:13   ` Sascha Hauer
2026-01-19 11:33     ` Ahmad Fatoum
2026-01-15 12:06 ` [PATCH 5/6] firmware: qemu_fw_cfg: add proper DMA and PIO bidirectional operating modes Ahmad Fatoum
2026-01-15 12:06 ` [PATCH 6/6] ARM: configs: multi: enable QEMU FW_CFG Ahmad Fatoum
2026-01-19 12:11 ` [PATCH 0/6] firmware: qemu_fw_cfg: improve support Sascha Hauer

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=20260115120748.3433463-3-a.fatoum@barebox.org \
    --to=a.fatoum@barebox.org \
    --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