summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2021-02-04 21:17:20 -0700
committerBin Meng <bmeng.cn@gmail.com>2021-02-06 19:20:27 +0800
commite9adaa75bb38ded5cf4e460270315afd891d141c (patch)
tree95791c1205f994c551d1042a61f8e255c0cfb6af /lib
parentfd3b826da8faabdf288de8e4ff8ce020cf6d9391 (diff)
downloadu-boot-e9adaa75bb38ded5cf4e460270315afd891d141c.tar.gz
u-boot-e9adaa75bb38ded5cf4e460270315afd891d141c.tar.xz
u-boot-e9adaa75bb38ded5cf4e460270315afd891d141c.zip
smbios: Add more options for the BIOS version string
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@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/smbios.c58
1 files changed, 55 insertions, 3 deletions
diff --git a/lib/smbios.c b/lib/smbios.c
index a7273529cc..e8bfc9ee1c 100644
--- a/lib/smbios.c
+++ b/lib/smbios.c
@@ -17,6 +17,12 @@
#include <dm/uclass-internal.h>
#endif
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+ SMBIOS_STR_MAX = 64, /* Maximum length allowed for a string */
+};
+
/**
* struct smbios_ctx - context for writing SMBIOS tables
*
@@ -27,12 +33,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 +87,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 +97,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++;
@@ -119,6 +131,35 @@ static void smbios_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;
+ 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;
}
/**
@@ -146,7 +187,18 @@ static int smbios_write_type0(ulong *current, int handle,
fill_smbios_header(t, SMBIOS_BIOS_INFORMATION, len, handle);
smbios_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;
@@ -345,7 +397,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", },