[PATCH v2 09/12] smbios: Add more options for the BIOS version string
Bin Meng
bmeng.cn at gmail.com
Thu Jan 21 07:54:31 CET 2021
On Thu, Jan 21, 2021 at 10:07 AM Simon Glass <sjg at 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 <sjg at 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.cn at gmail.com>
More information about the U-Boot
mailing list