[PATCH] fdt: cmd: allow to add chosen properties

Simon Glass sjg at chromium.org
Wed Jul 12 16:00:35 CEST 2023


Hi Alexander,

On Sat, 27 May 2023 at 16:02, Alexander Couzens <lynxis at 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 at 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


More information about the U-Boot mailing list