uboot-tools/0002-smbios-Fallback-to-the...

243 lines
6.6 KiB
Diff

From ed67997890981fda4f859cb96e523a0ec5b58042 Mon Sep 17 00:00:00 2001
From: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Date: Tue, 6 Sep 2022 16:44:26 +0300
Subject: [PATCH 2/2] smbios: Fallback to the default DT if sysinfo nodes are
missing
In order to fill in the SMBIOS tables U-Boot currently relies on a
"u-boot,sysinfo-smbios" compatible node. This is fine for the boards
that already include such nodes. However with some recent EFI changes,
the majority of boards can boot up distros, which usually rely on
things like dmidecode etc for their reporting. For boards that
lack this special node the SMBIOS output looks like:
System Information
Manufacturer: Unknown
Product Name: Unknown
Version: Unknown
Serial Number: Unknown
UUID: Not Settable
Wake-up Type: Reserved
SKU Number: Unknown
Family: Unknown
This looks problematic since most of the info are "Unknown". The DT spec
specifies standard properties containing relevant information like
'model' and 'compatible' for which the suggested format is
<manufacturer,model>. So let's add a last resort to our current
smbios parsing. If none of the sysinfo properties are found, we can
scan the root node for 'model' and 'compatible'.
pre-patch dmidecode:
<snip>
Handle 0x0001, DMI type 1, 27 bytes
System Information
Manufacturer: Unknown
Product Name: Unknown
Version: Unknown
Serial Number: Unknown
UUID: Not Settable
Wake-up Type: Reserved
SKU Number: Unknown
Family: Unknown
Handle 0x0002, DMI type 2, 14 bytes
Base Board Information
Manufacturer: Unknown
Product Name: Unknown
Version: Unknown
Serial Number: Not Specified
Asset Tag: Unknown
Features:
Board is a hosting board
Location In Chassis: Not Specified
Chassis Handle: 0x0000
Type: Motherboard
Handle 0x0003, DMI type 3, 21 bytes
Chassis Information
Manufacturer: Unknown
Type: Desktop
Lock: Not Present
Version: Not Specified
Serial Number: Not Specified
Asset Tag: Not Specified
Boot-up State: Safe
Power Supply State: Safe
Thermal State: Safe
Security Status: None
OEM Information: 0x00000000
Height: Unspecified
Number Of Power Cords: Unspecified
Contained Elements: 0
<snip>
post-pastch dmidecode:
<snip>
Handle 0x0001, DMI type 1, 27 bytes
System Information
Manufacturer: socionext,developer-box
Product Name: Socionext Developer Box
Version: Unknown
Serial Number: Unknown
UUID: Not Settable
Wake-up Type: Reserved
SKU Number: Unknown
Family: Unknown
Handle 0x0002, DMI type 2, 14 bytes
Base Board Information
Manufacturer: socionext,developer-box
Product Name: Socionext Developer Box
Version: Unknown
Serial Number: Not Specified
Asset Tag: Unknown
Features:
Board is a hosting board
Location In Chassis: Not Specified
Chassis Handle: 0x0000
Type: Motherboard
Handle 0x0003, DMI type 3, 21 bytes
Chassis Information
Manufacturer: socionext,developer-box
Type: Desktop
Lock: Not Present
Version: Not Specified
Serial Number: Not Specified
Asset Tag: Not Specified
Boot-up State: Safe
Power Supply State: Safe
Thermal State: Safe
Security Status: None
OEM Information: 0x00000000
Height: Unspecified
Number Of Power Cords: Unspecified
Contained Elements: 0
<snip>
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Reviewed-by: Peter Robinson <pbrobinson@gmail.com>
Tested-by: Peter Robinson <pbrobinson@gmail.com>
---
lib/smbios.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 64 insertions(+), 4 deletions(-)
diff --git a/lib/smbios.c b/lib/smbios.c
index fcc8686993ef..9c8e34625e65 100644
--- a/lib/smbios.c
+++ b/lib/smbios.c
@@ -9,11 +9,13 @@
#include <dm.h>
#include <env.h>
#include <linux/stringify.h>
+#include <linux/string.h>
#include <mapmem.h>
#include <smbios.h>
#include <sysinfo.h>
#include <tables_csum.h>
#include <version.h>
+#include <malloc.h>
#ifdef CONFIG_CPU
#include <cpu.h>
#include <dm/uclass-internal.h>
@@ -43,6 +45,25 @@
DECLARE_GLOBAL_DATA_PTR;
+/**
+ * struct map_sysinfo - Mapping of sysinfo strings to DT
+ *
+ * @sysinfo_str: sysinfo string
+ * @dt_str: DT string
+ * @max: Max index of the tokenized string to pick. First element is 0
+ *
+ */
+struct map_sysinfo {
+ const char *sysinfo_str;
+ const char *dt_str;
+ int max;
+};
+
+static const struct map_sysinfo sysinfo_to_dt[] = {
+ { .sysinfo_str = "product", .dt_str = "model", 1 },
+ { .sysinfo_str = "manufacturer", .dt_str = "compatible", 0 },
+};
+
/**
* struct smbios_ctx - context for writing SMBIOS tables
*
@@ -87,6 +108,18 @@ struct smbios_write_method {
const char *subnode_name;
};
+static const struct map_sysinfo *convert_sysinfo_to_dt(const char *sysinfo_str)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sysinfo_to_dt); i++) {
+ if (!strcmp(sysinfo_str, sysinfo_to_dt[i].sysinfo_str))
+ return &sysinfo_to_dt[i];
+ }
+
+ return NULL;
+}
+
/**
* smbios_add_string() - add a string to the string area
*
@@ -139,19 +172,46 @@ static int smbios_add_string(struct smbios_ctx *ctx, const char *str)
static int smbios_add_prop_si(struct smbios_ctx *ctx, const char *prop,
int sysinfo_id)
{
+ int ret = 0;
+
if (sysinfo_id && ctx->dev) {
char val[SMBIOS_STR_MAX];
- int ret;
ret = sysinfo_get_str(ctx->dev, sysinfo_id, sizeof(val), val);
if (!ret)
return smbios_add_string(ctx, val);
}
+
if (IS_ENABLED(CONFIG_OF_CONTROL)) {
- const char *str;
+ const char *str = NULL;
+ char str_tmp[128];
+ char *token;
- str = ofnode_read_string(ctx->node, prop);
- return smbios_add_string(ctx, str);
+ /*
+ * If the node is not valid fallback and try the entire DT
+ * so we can at least fill in maufacturer and board type
+ */
+ if (!ofnode_valid(ctx->node)) {
+ const struct map_sysinfo *nprop;
+
+ nprop = convert_sysinfo_to_dt(prop);
+ if (nprop) {
+ int cnt = 0;
+
+ str = ofnode_read_string(ofnode_root(), nprop->dt_str);
+ strncpy(str_tmp, str, sizeof(str_tmp));
+ token = strtok(str_tmp, ",");
+ while (token != NULL && cnt <= nprop->max) {
+ str = token;
+ token = strtok(NULL, ",");
+ cnt++;
+ }
+ }
+ } else {
+ str = ofnode_read_string(ctx->node, prop);
+ }
+ ret = smbios_add_string(ctx, str);
+ return ret;
}
return 0;
--
2.40.1