Message ID | 20230527214925.2360646-1-lynxis@fe80.eu |
---|---|
State | Changes Requested |
Delegated to: | Simon Glass |
Headers | show |
Series | fdt: cmd: allow to add chosen properties | expand |
Hi Alexander, On Sat, 27 May 2023 at 16:02, Alexander Couzens <lynxis@fe80.eu> wrote: > > 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. only be visible > > 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@fe80.eu> > --- > cmd/fdt.c | 10 +++++++ > common/fdt_support.c | 69 +++++++++++++++++++++++++++++++++++++++++++ > include/fdt_support.h | 2 ++ > 3 files changed, 81 insertions(+) Sorry I missed this patch when it was sent. Please can you add to doc/usage/cmd/fdt.rst and test/cmd/fdt.c ? We need docs and tests for new commands. > > 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, > +}; > + please comment this struct: > +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); check errors > + list_add_tail(&entry->list, &chosen_entries); blank line before final return > + 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); check error > + 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); Please add function comments > > /** > * Add initrd information to the FDT before booting the OS. > -- > 2.40.1 > Regards, Simon
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.