[PATCH] fdt: cmd: allow to add chosen properties
Alexander Couzens
lynxis at fe80.eu
Sat May 27 23:49:25 CEST 2023
Add command fdt chosenu32/chosenstr to allow setting runtime properties.
This is useful to pass information to the OS.
E.g. which slot is currently booted in a A/B/recovery scheme.
Or the reset reason which may only visitable to the u-boot.
Scripts can use:
> fdt chosenstr u-boot,abboot b
To inform the OS which slot was booted.
or pass u32
> fdt chosenu32 u-boot,try 3
Signed-off-by: Alexander Couzens <lynxis at fe80.eu>
---
cmd/fdt.c | 10 +++++++
common/fdt_support.c | 69 +++++++++++++++++++++++++++++++++++++++++++
include/fdt_support.h | 2 ++
3 files changed, 81 insertions(+)
diff --git a/cmd/fdt.c b/cmd/fdt.c
index aae3278526c4..050014cccd0e 100644
--- a/cmd/fdt.c
+++ b/cmd/fdt.c
@@ -278,6 +278,14 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
return CMD_RET_SUCCESS;
}
+ else if (strncmp(argv[1], "chosenstr", 3) == 0) {
+ if (argc != 4)
+ return CMD_RET_USAGE;
+
+ fdt_chosen_set_str(argv[2], argv[3]);
+ return 0;
+ }
+
if (!working_fdt) {
puts("No FDT memory address configured. Please configure\n"
"the FDT address via \"fdt addr <address>\" command.\n"
@@ -1147,6 +1155,8 @@ static char fdt_help_text[] =
"fdt rsvmem delete <index> - Delete a mem reserves\n"
"fdt chosen [<start> <size>] - Add/update the /chosen branch in the tree\n"
" <start>/<size> - initrd start addr/size\n"
+ "fdt chosenu32 key value - Add key to /chosen with u32 value\n"
+ "fdt chosenstr key value - Add key to /chosen with string value\n"
#if defined(CONFIG_FIT_SIGNATURE)
"fdt checksign [<addr>] - check FIT signature\n"
" <addr> - address of key blob\n"
diff --git a/common/fdt_support.c b/common/fdt_support.c
index 2053fe3bad83..33b22ebc94ad 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -10,10 +10,12 @@
#include <abuf.h>
#include <env.h>
#include <log.h>
+#include <malloc.h>
#include <mapmem.h>
#include <net.h>
#include <stdio_dev.h>
#include <linux/ctype.h>
+#include <linux/list.h>
#include <linux/types.h>
#include <asm/global_data.h>
#include <linux/libfdt.h>
@@ -22,6 +24,21 @@
#include <fdtdec.h>
#include <version.h>
+static LIST_HEAD(chosen_entries);
+
+enum fdt_chosen_type {
+ FDT_CHOSEN_TYPE_U32,
+ FDT_CHOSEN_TYPE_STR,
+};
+
+struct fdt_chosen_entry {
+ struct list_head list;
+ enum fdt_chosen_type type;
+ char *key;
+ char *str;
+ u32 u32;
+};
+
/**
* fdt_getprop_u32_default_node - Return a node's property or a default
*
@@ -269,6 +286,34 @@ int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end)
return 0;
}
+int fdt_chosen_set_str(char *key, char *value)
+{
+ struct fdt_chosen_entry *entry = calloc(1, sizeof(*entry));
+
+ if (!entry)
+ return 1;
+
+ entry->type = FDT_CHOSEN_TYPE_STR;
+ entry->key = strdup(key);
+ entry->str = strdup(value);
+ list_add_tail(&entry->list, &chosen_entries);
+ return 0;
+}
+
+int fdt_chosen_set_int(char *key, u32 value)
+{
+ struct fdt_chosen_entry *entry = calloc(1, sizeof(*entry));
+
+ if (!entry)
+ return 1;
+
+ entry->type = FDT_CHOSEN_TYPE_U32;
+ entry->key = strdup(key);
+ entry->u32 = value;
+ list_add_tail(&entry->list, &chosen_entries);
+ return 0;
+}
+
/**
* board_fdt_chosen_bootargs - boards may override this function to use
* alternative kernel command line arguments
@@ -284,6 +329,7 @@ int fdt_chosen(void *fdt)
int nodeoffset;
int err;
char *str; /* used to set string properties */
+ struct list_head *entry;
err = fdt_check_header(fdt);
if (err < 0) {
@@ -319,6 +365,29 @@ int fdt_chosen(void *fdt)
}
}
+ list_for_each(entry, &chosen_entries) {
+ struct fdt_chosen_entry *chosen = list_entry(entry, struct fdt_chosen_entry, list);
+
+ switch (chosen->type) {
+ case FDT_CHOSEN_TYPE_STR:
+ err = fdt_setprop_string(fdt, nodeoffset, chosen->key, chosen->str);
+ if (err < 0) {
+ printf("WARNING: could not set fdt %s to %s. Error: %s.\n",
+ chosen->key, chosen->str, fdt_strerror(err));
+ continue;
+ }
+ break;
+ case FDT_CHOSEN_TYPE_U32:
+ err = fdt_setprop_u32(fdt, nodeoffset, chosen->key, chosen->u32);
+ if (err < 0) {
+ printf("WARNING: could not set fdt %s to %d. Error: %s.\n",
+ chosen->key, chosen->u32, fdt_strerror(err));
+ continue;
+ }
+ break;
+ }
+ }
+
/* add u-boot version */
err = fdt_setprop(fdt, nodeoffset, "u-boot,version", PLAIN_VERSION,
strlen(PLAIN_VERSION) + 1);
diff --git a/include/fdt_support.h b/include/fdt_support.h
index 5638bd4f1655..b1c331f05370 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -51,6 +51,8 @@ int fdt_root(void *fdt);
* Return: 0 if ok, or -FDT_ERR_... on error
*/
int fdt_chosen(void *fdt);
+int fdt_chosen_set_str(char *key, char *value);
+int fdt_chosen_set_int(char *key, u32 value);
/**
* Add initrd information to the FDT before booting the OS.
--
2.40.1
More information about the U-Boot
mailing list