On Thu, Jan 21, 2021 at 10:07 AM Simon Glass <s...@chromium.org> wrote:
>
> At present the version string is obtained from PLAIN_VERSION. Some boards
> may want to configure this using the device tree, since the build system
> can more easily insert things there after U-Boot itself is built. Add this
> option to the code.
>
> Also in some cases the version needs to be generated programmatically,
> such as when it is stored elsewhere in the ROM and must be read first.
> To handle this, keep a pointer around so that it can be updated later.
> This works by storing the last string in the context, since it is easier
> than passing out a little-used extra parameter.
>
> Provide a function to update the version string.
>
> Signed-off-by: Simon Glass <s...@chromium.org>
> ---
>
> Changes in v2:
> - Correct documentation format
>
>  include/asm-generic/global_data.h |  6 ++++
>  include/smbios.h                  | 12 +++++++
>  lib/smbios.c                      | 56 +++++++++++++++++++++++++++++--
>  3 files changed, 71 insertions(+), 3 deletions(-)
>
> diff --git a/include/asm-generic/global_data.h 
> b/include/asm-generic/global_data.h
> index 19f70393b45..750e998d885 100644
> --- a/include/asm-generic/global_data.h
> +++ b/include/asm-generic/global_data.h
> @@ -439,6 +439,12 @@ struct global_data {
>          */
>         struct acpi_ctx *acpi_ctx;
>  #endif
> +#if CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)
> +       /**
> +        * @smbios_version: Points to SMBIOS type 0 version
> +        */
> +       char *smbios_version;
> +#endif
>  };
>
>  /**
> diff --git a/include/smbios.h b/include/smbios.h
> index 1cbeabf9522..ecc4fd1de3b 100644
> --- a/include/smbios.h
> +++ b/include/smbios.h
> @@ -257,4 +257,16 @@ const struct smbios_header *smbios_header(const struct 
> smbios_entry *entry, int
>   */
>  const char *smbios_string(const struct smbios_header *header, int index);
>
> +/**
> + * smbios_update_version() - Update the version string
> + *
> + * This can be called after the SMBIOS tables are written (e.g. after the 
> U-Boot
> + * main loop has started) to update the BIOS version string (SMBIOS table 0).
> + *
> + * @version: New version string to use
> + * @return 0 if OK, -ENOENT if no version string was previously written,
> + *     -ENOSPC if the new string is too large to fit
> + */
> +int smbios_update_version(const char *version);
> +
>  #endif /* _SMBIOS_H_ */
> diff --git a/lib/smbios.c b/lib/smbios.c
> index 7090460bc02..d46569b09f4 100644
> --- a/lib/smbios.c
> +++ b/lib/smbios.c
> @@ -17,6 +17,10 @@
>  #include <dm/uclass-internal.h>
>  #endif
>
> +enum {
> +       SMBIOS_STR_MAX  = 64,   /* Maximum length allowed for a string */
> +};
> +
>  /**
>   * struct smbios_ctx - context for writing SMBIOS tables
>   *
> @@ -27,12 +31,15 @@
>   * @next_ptr:  pointer to the start of the next string to be added. When the
>   *             table is nopt empty, this points to the byte after the \0 of 
> the
>   *             previous string.
> + * @last_str:  points to the last string that was written to the table, or 
> NULL
> + *             if none
>   */
>  struct smbios_ctx {
>         ofnode node;
>         struct udevice *dev;
>         char *eos;
>         char *next_ptr;
> +       char *last_str;
>  };
>
>  /**
> @@ -78,6 +85,7 @@ static int smbios_add_string(struct smbios_ctx *ctx, const 
> char *str)
>
>         for (;;) {
>                 if (!*p) {
> +                       ctx->last_str = p;
>                         strcpy(p, str);
>                         p += strlen(str);
>                         *p++ = '\0';
> @@ -87,8 +95,10 @@ static int smbios_add_string(struct smbios_ctx *ctx, const 
> char *str)
>                         return i;
>                 }
>
> -               if (!strcmp(p, str))
> +               if (!strcmp(p, str)) {
> +                       ctx->last_str = p;
>                         return i;
> +               }
>
>                 p += strlen(p) + 1;
>                 i++;
> @@ -120,6 +130,35 @@ static void set_eos(struct smbios_ctx *ctx, char *eos)
>  {
>         ctx->eos = eos;
>         ctx->next_ptr = eos;
> +       ctx->last_str = NULL;
> +}
> +
> +int smbios_update_version(const char *version)
> +{
> +       char *ptr = gd->smbios_version;

Missing DECLARE_GLOBAL_DATA_PTR?

> +       uint old_len, len;
> +
> +       if (!ptr)
> +               return log_ret(-ENOENT);
> +
> +       /*
> +        * This string is supposed to have at least enough bytes and is
> +        * padded with spaces. Update it, taking care not to move the
> +        * \0 terminator, so that other strings in the string table
> +        * are not disturbed. See smbios_add_string()
> +        */
> +       old_len = strnlen(ptr, SMBIOS_STR_MAX);
> +       len = strnlen(version, SMBIOS_STR_MAX);
> +       if (len > old_len)
> +               return log_ret(-ENOSPC);
> +
> +       log_debug("Replacing SMBIOS type 0 version string '%s'\n", ptr);
> +       memcpy(ptr, version, len);
> +#ifdef LOG_DEBUG
> +       print_buffer((ulong)ptr, ptr, 1, old_len + 1, 0);
> +#endif
> +
> +       return 0;
>  }
>
>  /**
> @@ -147,7 +186,18 @@ static int smbios_write_type0(ulong *current, int handle,
>         fill_smbios_header(t, SMBIOS_BIOS_INFORMATION, len, handle);
>         set_eos(ctx, t->eos);
>         t->vendor = smbios_add_string(ctx, "U-Boot");
> -       t->bios_ver = smbios_add_string(ctx, PLAIN_VERSION);
> +
> +       t->bios_ver = smbios_add_prop(ctx, "version");
> +       if (!t->bios_ver)
> +               t->bios_ver = smbios_add_string(ctx, PLAIN_VERSION);
> +       if (t->bios_ver)
> +               gd->smbios_version = ctx->last_str;
> +       log_debug("smbios_version = %p: '%s'\n", gd->smbios_version,
> +                 gd->smbios_version);
> +#ifdef LOG_DEBUG
> +       print_buffer((ulong)gd->smbios_version, gd->smbios_version,
> +                    1, strlen(gd->smbios_version) + 1, 0);
> +#endif
>         t->bios_release_date = smbios_add_string(ctx, U_BOOT_DMI_DATE);
>  #ifdef CONFIG_ROM_SIZE
>         t->bios_rom_size = (CONFIG_ROM_SIZE / 65536) - 1;
> @@ -346,7 +396,7 @@ static int smbios_write_type127(ulong *current, int 
> handle,
>  }
>
>  static struct smbios_write_method smbios_write_funcs[] = {
> -       { smbios_write_type0, },
> +       { smbios_write_type0, "bios", },
>         { smbios_write_type1, "system", },
>         { smbios_write_type2, "baseboard", },
>         { smbios_write_type3, "chassis", },
> --

Reviewed-by: Bin Meng <bmeng...@gmail.com>

Reply via email to