+};
+
+static const char * const processor_upgrade_strings[] = {
+ [0] = "Reserved",
+ [1] = "Other",
+ [2] = "Unknown",
+ [3 ... 5] = "Other", /* skip these definitions from now */
+ [6] = "None",
+ [7 ... 80] = "Other", /* skip these definitions from now */
+};
+
/**
* smbios_get_string() - get SMBIOS string from table
*
@@ -92,6 +157,32 @@ const char *smbios_wakeup_type_str(u8 wakeup_type)
return wakeup_type_strings[wakeup_type];
}
+static void smbios_print_type0(struct smbios_type0 *table)
+{
+ printf("BIOS Information\n");
+ smbios_print_str("Vendor", table, table->vendor);
+ smbios_print_str("BIOS Version", table, table->bios_ver);
+ /* Keep table->bios_start_segment as 0 for UEFI-based systems */
+ smbios_print_str("BIOS Release Date", table, table->bios_release_date);
+ printf("\tBIOS ROM Size: 0x%02x\n", table->bios_rom_size);
+ printf("\tBIOS Characteristics: 0x%016llx\n",
+ table->bios_characteristics);
+ printf("\tBIOS Characteristics Extension Byte 1: 0x%02x\n",
+ table->bios_characteristics_ext1);
+ printf("\tBIOS Characteristics Extension Byte 2: 0x%02x\n",
+ table->bios_characteristics_ext2);
+ printf("\tSystem BIOS Major Release: 0x%02x\n",
+ table->bios_major_release);
+ printf("\tSystem BIOS Minor Release: 0x%02x\n",
+ table->bios_minor_release);
+ printf("\tEmbedded Controller Firmware Major Release: 0x%02x\n",
+ table->ec_major_release);
+ printf("\tEmbedded Controller Firmware Minor Release: 0x%02x\n",
+ table->ec_minor_release);
+ printf("\tExtended BIOS ROM Size: 0x%04x\n",
+ table->extended_bios_rom_size);
+}
+
static void smbios_print_type1(struct smbios_type1 *table)
{
printf("System Information\n");
@@ -99,38 +190,180 @@ static void smbios_print_type1(struct smbios_type1 *table)
smbios_print_str("Product Name", table, table->product_name);
smbios_print_str("Version", table, table->version);
smbios_print_str("Serial Number", table, table->serial_number);
- if (table->length >= 0x19) {
+ if (table->hdr.length >= SMBIOS_TYPE1_LENGTH_V21) {
printf("\tUUID: %pUl\n", table->uuid);
printf("\tWake-up Type: %s\n",
smbios_wakeup_type_str(table->wakeup_type));
}
- if (table->length >= 0x1b) {
+ if (table->hdr.length >= SMBIOS_TYPE1_LENGTH_V24) {
smbios_print_str("SKU Number", table, table->sku_number);
smbios_print_str("Family", table, table->family);
}
}
+const char *smbios_baseboard_type_str(u8 borad_type)
+{
+ if (borad_type >= ARRAY_SIZE(boardtype_strings))
+ borad_type = 0;
+ return boardtype_strings[borad_type];
+}
+
static void smbios_print_type2(struct smbios_type2 *table)
{
- u16 *handle;
+ int i;
+ u8 *addr = (u8 *)table + offsetof(struct smbios_type2, eos);
- printf("Base Board Information\n");
+ printf("Baseboard Information\n");
smbios_print_str("Manufacturer", table, table->manufacturer);
smbios_print_str("Product Name", table, table->product_name);
smbios_print_str("Version", table, table->version);
smbios_print_str("Serial Number", table, table->serial_number);
smbios_print_str("Asset Tag", table, table->asset_tag_number);
- printf("\tFeature Flags: 0x%04x\n", table->feature_flags);
+ printf("\tFeature Flags: 0x%02x\n", table->feature_flags);
smbios_print_str("Chassis Location", table, table->chassis_location);
printf("\tChassis Handle: 0x%04x\n", table->chassis_handle);
- smbios_print_str("Board Type", table, table->board_type);
- printf("\tContained Object Handles: ");
- handle = (void *)table->eos;
- for (int i = 0; i < table->number_contained_objects; ++i)
- printf("0x%04x ", handle[i]);
+ printf("\tBoard Type: %s\n",
+ smbios_baseboard_type_str(table->board_type));
+ printf("\tNumber of Contained Object Handles: 0x%02x\n",
+ table->number_contained_objects);
+ if (!table->number_contained_objects)
+ return;
+
+ printf("\tContained Object Handles:\n");
+ for (i = 0; i < table->number_contained_objects; i++) {
+ printf("\t\tObject[%03d]:\n", i);
+ if (CONFIG_IS_ENABLED(HEXDUMP))
+ print_hex_dump("\t\t", DUMP_PREFIX_OFFSET, 16, 1, addr,
+ sizeof(u16), false);
+ addr += sizeof(u16);
+ }
printf("\n");
}
+const char *smbios_chassis_state_str(u8 state)
+{
+ if (state >= ARRAY_SIZE(chassis_state_strings))
+ state = 0;
+ return chassis_state_strings[state];
+}
+
+const char *smbios_chassis_security_str(u8 status)
+{
+ if (status >= ARRAY_SIZE(chassis_security_strings))
+ status = 0;
+ return chassis_security_strings[status];
+}
+
+static void smbios_print_type3(struct smbios_type3 *table)
+{
+ int i;
+ u8 *addr = (u8 *)table + offsetof(struct smbios_type3, sku_number);
+
+ printf("Baseboard Information\n");
+ smbios_print_str("Manufacturer", table, table->manufacturer);
+ printf("\tType: 0x%02x\n", table->chassis_type);
+ smbios_print_str("Version", table, table->version);
+ smbios_print_str("Serial Number", table, table->serial_number);
+ smbios_print_str("Asset Tag", table, table->asset_tag_number);
+
+ printf("\tBoot-up State: %s\n",
+ smbios_chassis_state_str(table->bootup_state));
+ printf("\tPower Supply State: %s\n",
+ smbios_chassis_state_str(table->power_supply_state));
+ printf("\tThermal State: %s\n",
+ smbios_chassis_state_str(table->thermal_state));
+ printf("\tSecurity Status: %s\n",
+ smbios_chassis_security_str(table->security_status));
+
+ printf("\tOEM-defined: 0x%08x\n", table->oem_defined);
+ printf("\tHeight: 0x%02x\n", table->height);
+ printf("\tNumber of Power Cords: 0x%02x\n",
+ table->number_of_power_cords);
+ printf("\tContained Element Count: 0x%02x\n", table->element_count);
+ printf("\tContained Element Record Length: 0x%02x\n",
+ table->element_record_length);
+ if (table->element_count) {
+ printf("\tContained Elements:\n");
+ for (i = 0; i < table->element_count; i++) {
+ printf("\t\tElement[%03d]:\n", i);
+ if (CONFIG_IS_ENABLED(HEXDUMP))
+ print_hex_dump("\t\t", DUMP_PREFIX_OFFSET, 16,
+ 1, addr,
+ table->element_record_length,
+ false);
+ printf("\t\tContained Element Type: 0x%02x\n", *addr);
+ printf("\t\tContained Element Minimum: 0x%02x\n",
+ *(addr + 1));
+ printf("\t\tContained Element Maximum: 0x%02x\n",
+ *(addr + 2));
+ addr += table->element_record_length;
+ }
+ }
+ smbios_print_str("SKU Number", table, *addr);
+}
+
+const char *smbios_processor_type_str(u8 type)
+{
+ if (type >= ARRAY_SIZE(processor_type_strings))
+ type = 0;
+ return processor_type_strings[type];
+}
+
+const char *smbios_processor_family_str(u16 family)
+{
+ if (family >= ARRAY_SIZE(processor_family_strings))
+ family = 0;
+
+ return processor_family_strings[family];
+}
+
+const char *smbios_processor_upgrade_str(u16 upgrade)
+{
+ if (upgrade >= ARRAY_SIZE(processor_upgrade_strings))
+ upgrade = 0;
+
+ return processor_upgrade_strings[upgrade];
+}
+
+static void smbios_print_type4(struct smbios_type4 *table)
+{
+ printf("Processor Information:\n");
+ smbios_print_str("Socket Designation", table, table->socket_design);
+ printf("\tProcessor Type: %s\n",
+ smbios_processor_type_str(table->processor_type));
+ smbios_print_str("Processor Manufacturer", table,
+ table->processor_manufacturer);
+ printf("\tProcessor ID word 0: 0x%08x\n", table->processor_id[0]);
+ printf("\tProcessor ID word 1: 0x%08x\n", table->processor_id[1]);
+ smbios_print_str("Processor Version", table, table->processor_version);
+ printf("\tVoltage: 0x%02x\n", table->voltage);
+ printf("\tExternal Clock: 0x%04x\n", table->external_clock);
+ printf("\tMax Speed: 0x%04x\n", table->max_speed);
+ printf("\tCurrent Speed: 0x%04x\n", table->current_speed);
+ printf("\tStatus: 0x%02x\n", table->status);
+ printf("\tProcessor Upgrade: %s\n",
+ smbios_processor_upgrade_str(table->processor_upgrade));
+ printf("\tL1 Cache Handle: 0x%04x\n", table->l1_cache_handle);
+ printf("\tL2 Cache Handle: 0x%04x\n", table->l2_cache_handle);
+ printf("\tL3 Cache Handle: 0x%04x\n", table->l3_cache_handle);
+ smbios_print_str("Serial Number", table, table->serial_number);
+ smbios_print_str("Asset Tag", table, table->asset_tag);
+ smbios_print_str("Part Number", table, table->part_number);
+ printf("\tCore Count: 0x%02x\n", table->core_count);
+ printf("\tCore Enabled: 0x%02x\n", table->core_enabled);
+ printf("\tThread Count: 0x%02x\n", table->thread_count);
+ printf("\tProcessor Characteristics: 0x%04x\n",
+ table->processor_characteristics);
+ printf("\tProcessor Family 2: %s\n",
+ smbios_processor_family_str(table->processor_family2));
+ printf("\tCore Count 2: 0x%04x\n", table->core_count2);
+ printf("\tCore Enabled 2: 0x%04x\n", table->core_enabled2);
+ printf("\tThread Count 2: 0x%04x\n", table->thread_count2);
+ printf("\tThread Enabled: 0x%04x\n", table->thread_enabled);
+}
+
static void smbios_print_type127(struct smbios_type127 *table)
{
printf("End Of Table\n");
@@ -192,13 +425,22 @@ static int do_smbios(struct cmd_tbl *cmdtp, int flag, int
argc,
pos->handle, pos->type, pos->length,
(unsigned long long)map_to_sysmem(pos));
switch (pos->type) {
- case 1:
+ case SMBIOS_BIOS_INFORMATION:
+ smbios_print_type0((struct smbios_type0 *)pos);
+ break;
+ case SMBIOS_SYSTEM_INFORMATION:
smbios_print_type1((struct smbios_type1 *)pos);
break;
- case 2:
+ case SMBIOS_BOARD_INFORMATION:
smbios_print_type2((struct smbios_type2 *)pos);
break;
- case 127:
+ case SMBIOS_SYSTEM_ENCLOSURE:
+ smbios_print_type3((struct smbios_type3 *)pos);
+ break;
+ case SMBIOS_PROCESSOR_INFORMATION:
+ smbios_print_type4((struct smbios_type4 *)pos);
+ break;
+ case SMBIOS_END_OF_TABLE:
smbios_print_type127((struct smbios_type127 *)pos);
break;
default:
diff --git a/include/smbios.h b/include/smbios.h
index 60e28a89af8..f2269642268 100644
--- a/include/smbios.h
+++ b/include/smbios.h
@@ -80,19 +80,24 @@ struct __packed smbios3_entry {
u64 struct_table_address;
};
+struct __packed smbios_header {
+ u8 type;
+ u8 length;
+ u16 handle;
+};
+
/* BIOS characteristics */
-#define BIOS_CHARACTERISTICS_PCI_SUPPORTED (1 << 7)
-#define BIOS_CHARACTERISTICS_UPGRADEABLE (1 << 11)
-#define BIOS_CHARACTERISTICS_SELECTABLE_BOOT (1 << 16)
-#define BIOS_CHARACTERISTICS_EXT1_ACPI (1 << 0)
-#define BIOS_CHARACTERISTICS_EXT2_UEFI (1 << 3)
-#define BIOS_CHARACTERISTICS_EXT2_TARGET (1 << 2)
+#define BIOS_CHARACTERISTICS_PCI_SUPPORTED BIT(7)
+#define BIOS_CHARACTERISTICS_UPGRADEABLE BIT(11)
+#define BIOS_CHARACTERISTICS_SELECTABLE_BOOT BIT(16)
+
+#define BIOS_CHARACTERISTICS_EXT1_ACPI BIT(0)
+#define BIOS_CHARACTERISTICS_EXT2_UEFI BIT(3)
+#define BIOS_CHARACTERISTICS_EXT2_TARGET BIT(2)
struct __packed smbios_type0 {
- u8 type;
- u8 length;
- u16 handle;
+ struct smbios_header hdr;
u8 vendor;
u8 bios_ver;
u16 bios_start_segment;
@@ -136,10 +141,12 @@ enum smbios_wakeup_type {
SMBIOS_WAKEUP_TYPE_AC_POWER_RESTORED,
};
+#define SMBIOS_TYPE1_LENGTH_V20 0x08
+#define SMBIOS_TYPE1_LENGTH_V21 0x19
+#define SMBIOS_TYPE1_LENGTH_V24 0x1b
+
struct __packed smbios_type1 {
- u8 type;
- u8 length;
- u16 handle;
+ struct smbios_header hdr;
u8 manufacturer;
u8 product_name;
u8 version;
@@ -151,8 +158,19 @@ struct __packed smbios_type1 {
char eos[SMBIOS_STRUCT_EOS_BYTES];
};
-#define SMBIOS_BOARD_FEATURE_HOSTING (1 << 0)
+#define SMBIOS_BOARD_UNKNOWN 1
+#define SMBIOS_BOARD_OTHER 2
+#define SMBIOS_BOARD_SERVER_BLADE 3
+#define SMBIOS_BOARD_CON_SWITCH 4
+#define SMBIOS_BOARD_SM_MODULE 5
+#define SMBIOS_BOARD_PROCESSOR_MODULE 6
+#define SMBIOS_BOARD_IO_MODULE 7
+#define SMBIOS_BOARD_MEM_MODULE 8
+#define SMBIOS_BOARD_DAUGHTER_BOARD 9
#define SMBIOS_BOARD_MOTHERBOARD 10
+#define SMBIOS_BOARD_PROC_MEM_MODULE 11
+#define SMBIOS_BOARD_PROC_IO_MODULE 12
+#define SMBIOS_BOARD_INTERCON 13
union baseboard_feat {
struct {
@@ -167,9 +185,7 @@ union baseboard_feat {
};
struct __packed smbios_type2 {
- u8 type;
- u8 length;
- u16 handle;
+ struct smbios_header hdr;
u8 manufacturer;
u8 product_name;
u8 version;
@@ -180,17 +196,29 @@ struct __packed smbios_type2 {
u16 chassis_handle;
u8 board_type;
u8 number_contained_objects;
+ /*
+ * Dynamic bytes will be inserted here to store the objects.
+ * length is equal to 'number_contained_objects'.
+ */
char eos[SMBIOS_STRUCT_EOS_BYTES];
};
#define SMBIOS_ENCLOSURE_DESKTOP 3
#define SMBIOS_STATE_SAFE 3
#define SMBIOS_SECURITY_NONE 3
+#define SMBIOS_ENCLOSURE_OEM_UND 0
+#define SMBIOS_ENCLOSURE_HEIGHT_UND 0
+#define SMBIOS_POWCORD_NUM_UND 0
+#define SMBIOS_ELEMENT_TYPE_SELECT BIT(7)
-struct __packed smbios_type3 {
+struct __packed elem_hdr {
u8 type;
- u8 length;
- u16 handle;
+ u8 minimum; /* 0 - 254 */
+ u8 maximum; /* 1 - 255 */
+};
+
+struct __packed smbios_type3 {
+ struct smbios_header hdr;
u8 manufacturer;
u8 chassis_type;
u8 version;
@@ -205,21 +233,52 @@ struct __packed smbios_type3 {
u8 number_of_power_cords;
u8 element_count;
u8 element_record_length;
+ /*
+ * Dynamic bytes will be inserted here to store the elements.
+ * length is equal to 'element_record_length' * 'element_record_length'
+ */
+ u8 sku_number;
char eos[SMBIOS_STRUCT_EOS_BYTES];
};
+#define SMBIOS_PROCESSOR_TYPE_OTHER 1
+#define SMBIOS_PROCESSOR_TYPE_UNKNOWN 2
#define SMBIOS_PROCESSOR_TYPE_CENTRAL 3
-#define SMBIOS_PROCESSOR_STATUS_ENABLED 1
+#define SMBIOS_PROCESSOR_TYPE_MATH 4
+#define SMBIOS_PROCESSOR_TYPE_DSP 5
+#define SMBIOS_PROCESSOR_TYPE_VIDEO 6
+
+#define SMBIOS_PROCESSOR_STATUS_UNKNOWN 0
+#define SMBIOS_PROCESSOR_STATUS_ENABLED 1
+#define SMBIOS_PROCESSOR_STATUS_DISABLED_USER 2
+#define SMBIOS_PROCESSOR_STATUS_DISABLED_BIOS 3
+#define SMBIOS_PROCESSOR_STATUS_IDLE 4
+#define SMBIOS_PROCESSOR_STATUS_OTHER 7
+
#define SMBIOS_PROCESSOR_UPGRADE_NONE 6
#define SMBIOS_PROCESSOR_FAMILY_OTHER 1
#define SMBIOS_PROCESSOR_FAMILY_UNKNOWN 2
+#define SMBIOS_PROCESSOR_FAMILY_ARMV7 256
+#define SMBIOS_PROCESSOR_FAMILY_ARMV8 257
+
+#define SMBIOS_PROCESSOR_FAMILY_EXT 0xfe
+
+/* Processor Characteristics */
+#define SMBIOS_PROCESSOR_RSVD BIT(0)
+#define SMBIOS_PROCESSOR_UND BIT(1)
+#define SMBIOS_PROCESSOR_64BIT BIT(2)
+#define SMBIOS_PROCESSOR_MULTICORE BIT(3)
+#define SMBIOS_PROCESSOR_HWTHREAD BIT(4)
+#define SMBIOS_PROCESSOR_EXEC_PROT BIT(5)
+#define SMBIOS_PROCESSOR_ENH_VIRT BIT(6)
+#define SMBIOS_PROCESSOR_POW_CON BIT(7)
+#define SMBIOS_PROCESSOR_128BIT BIT(8)
+#define SMBIOS_PROCESSOR_ARM64_SOCID BIT(9)
struct __packed smbios_type4 {
- u8 type;
- u8 length;
- u16 handle;
- u8 socket_designation;
+ struct smbios_header hdr;
+ u8 socket_design;
u8 processor_type;
u8 processor_family;
u8 processor_manufacturer;
@@ -245,9 +304,12 @@ struct __packed smbios_type4 {
u16 core_count2;
u16 core_enabled2;
u16 thread_count2;
+ u16 thread_enabled;
char eos[SMBIOS_STRUCT_EOS_BYTES];
};
+#define SMBIOS_CACHE_HANDLE_NONE 0xffff
+
struct __packed smbios_type32 {
u8 type;
u8 length;
@@ -264,12 +326,6 @@ struct __packed smbios_type127 {
char eos[SMBIOS_STRUCT_EOS_BYTES];
};
-struct __packed smbios_header {
- u8 type;
- u8 length;
- u16 handle;
-};
-
/**
* fill_smbios_header() - Fill the header of an SMBIOS table
*
diff --git a/lib/smbios.c b/lib/smbios.c
index 7c24ea129eb..8e481365165 100644
--- a/lib/smbios.c
+++ b/lib/smbios.c
@@ -8,6 +8,8 @@
#define LOG_CATEGORY LOGC_BOARD
#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
#include <env.h>
#include <linux/stringify.h>
#include <linux/string.h>
@@ -206,6 +208,26 @@ void get_str_from_dt(const struct map_sysinfo *nprop, char
*str, size_t size)
}
}
+/**
+ * smbios_get_val_si() - Get value from sysinfo
+ *
+ * @ctx: context of SMBIOS
+ * @sysinfo_id: unique identifier for the value to be read
+ * Return: 0 if not found, else value from sysinfo
+ */
+static int smbios_get_val_si(struct smbios_ctx *ctx, int sysinfo_id)
+{
+ int val;
+
+ if (!sysinfo_id || !ctx->dev)
+ return 0;
+
+ if (!sysinfo_get_int(ctx->dev, sysinfo_id, &val))
+ return val;
+
+ return 0;
+}
+
/**
* smbios_add_prop_si() - Add a property from the devicetree or sysinfo
*
@@ -225,8 +247,7 @@ static int smbios_add_prop_si(struct smbios_ctx *ctx, const
char *prop,
if (!dval || !*dval)
dval = NULL;
- if (!prop)
- return smbios_add_string(ctx, dval);
+ log_debug("smbios: %s, sysinfo id: %d\n", prop, sysinfo_id);
if (sysinfo_id && ctx->dev) {
char val[SMBIOS_STR_MAX];
@@ -235,6 +256,9 @@ static int smbios_add_prop_si(struct smbios_ctx *ctx, const
char *prop,
if (!ret)
return smbios_add_string(ctx, val);
}
+ if (!prop)
+ return smbios_add_string(ctx, dval);
+
if (IS_ENABLED(CONFIG_OF_CONTROL)) {
const char *str = NULL;
char str_dt[128] = { 0 };
@@ -247,6 +271,8 @@ static int smbios_add_prop_si(struct smbios_ctx *ctx, const
char *prop,
} else {
const struct map_sysinfo *nprop;
+ log_debug("no smbios node, try the entire DT\n");
+
nprop = convert_sysinfo_to_dt(ctx->subnode_name, prop);
get_str_from_dt(nprop, str_dt, sizeof(str_dt));
str = (const char *)str_dt;
@@ -330,15 +356,18 @@ static int smbios_write_type0(ulong *current, int handle,
struct smbios_ctx *ctx)
{
struct smbios_type0 *t;
- int len = sizeof(struct smbios_type0);
+ int len = sizeof(*t);
t = map_sysmem(*current, len);
- memset(t, 0, sizeof(struct smbios_type0));
+ memset(t, 0, len);
fill_smbios_header(t, SMBIOS_BIOS_INFORMATION, len, handle);
smbios_set_eos(ctx, t->eos);
- t->vendor = smbios_add_prop(ctx, NULL, "U-Boot");
+ t->vendor = smbios_add_prop_si(ctx, NULL, SYSINFO_ID_SMBIOS_BIOS_VENDOR,
+ "U-Boot");
- t->bios_ver = smbios_add_prop(ctx, "version", PLAIN_VERSION);
+ t->bios_ver = smbios_add_prop_si(ctx, "version",
+ SYSINFO_ID_SMBIOS_BIOS_VER,
+ PLAIN_VERSION);
if (t->bios_ver)
gd->smbios_version = ctx->last_str;
log_debug("smbios_version = %p: '%s'\n", gd->smbios_version,
@@ -347,7 +376,9 @@ static int smbios_write_type0(ulong *current, int handle,
print_buffer((ulong)gd->smbios_version, gd->smbios_version,
1, strlen(gd->smbios_version) + 1, 0);
#endif
- t->bios_release_date = smbios_add_prop(ctx, NULL, U_BOOT_DMI_DATE);
+ t->bios_release_date =
+ smbios_add_prop_si(ctx, NULL, SYSINFO_ID_SMBIOS_BIOS_REL_DATE,
+ U_BOOT_DMI_DATE);
#ifdef CONFIG_ROM_SIZE
if (CONFIG_ROM_SIZE < SZ_16M) {
t->bios_rom_size = (CONFIG_ROM_SIZE / 65536) - 1;
@@ -374,7 +405,7 @@ static int smbios_write_type0(ulong *current, int handle,
t->ec_major_release = 0xff;
t->ec_minor_release = 0xff;
- len = t->length + smbios_string_table_len(ctx);
+ len = t->hdr.length + smbios_string_table_len(ctx);
*current += len;
unmap_sysmem(t);
@@ -385,16 +416,18 @@ static int smbios_write_type1(ulong *current, int handle,
struct smbios_ctx *ctx)
{
struct smbios_type1 *t;
- int len = sizeof(struct smbios_type1);
+ int len = sizeof(*t);
char *serial_str = env_get("serial#");
t = map_sysmem(*current, len);
- memset(t, 0, sizeof(struct smbios_type1));
+ memset(t, 0, len);
fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle);
smbios_set_eos(ctx, t->eos);
- t->manufacturer = smbios_add_prop_si(ctx, "manufacturer",
-
SYSINFO_ID_SMBIOS_SYSTEM_MANUFACTURER,
- NULL);
+
+ t->manufacturer =
+ smbios_add_prop_si(ctx, "manufacturer",
+ SYSINFO_ID_SMBIOS_SYSTEM_MANUFACTURER,
+ NULL);
t->product_name = smbios_add_prop_si(ctx, "product",
SYSINFO_ID_SMBIOS_SYSTEM_PRODUCT,
NULL);
@@ -403,19 +436,21 @@ static int smbios_write_type1(ulong *current, int handle,
NULL);
if (serial_str) {
t->serial_number = smbios_add_prop(ctx, NULL, serial_str);
- strncpy((char *)t->uuid, serial_str, sizeof(t->uuid));
+ strlcpy((char *)t->uuid, serial_str, sizeof(t->uuid));
} else {
- t->serial_number = smbios_add_prop_si(ctx, "serial",
-
SYSINFO_ID_SMBIOS_SYSTEM_SERIAL,
- NULL);
+ t->serial_number =
+ smbios_add_prop_si(ctx, "serial",
+ SYSINFO_ID_SMBIOS_SYSTEM_SERIAL,
+ NULL);
}
- t->wakeup_type = SMBIOS_WAKEUP_TYPE_UNKNOWN;
+ t->wakeup_type =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_SYSTEM_WAKEUP);
t->sku_number = smbios_add_prop_si(ctx, "sku",
SYSINFO_ID_SMBIOS_SYSTEM_SKU, NULL);
t->family = smbios_add_prop_si(ctx, "family",
SYSINFO_ID_SMBIOS_SYSTEM_FAMILY, NULL);
- len = t->length + smbios_string_table_len(ctx);
+ len = t->hdr.length + smbios_string_table_len(ctx);
*current += len;
unmap_sysmem(t);
@@ -426,33 +461,80 @@ static int smbios_write_type2(ulong *current, int handle,
struct smbios_ctx *ctx)
{
struct smbios_type2 *t;
- int len = sizeof(struct smbios_type2);
+ int len = sizeof(*t);
+ size_t obj_hdl_size = 0;
+ u8 *obj_hdl = NULL;
+ u8 *obj_addr, *eos_addr;
+
+ if (!sysinfo_get_data(ctx->dev, SYSINFO_ID_SMBIOS_BASEBOARD_OBJS_HANDLE,
+ &obj_hdl, &obj_hdl_size))
+ len += obj_hdl_size; /* Add the dynamic part */
t = map_sysmem(*current, len);
- memset(t, 0, sizeof(struct smbios_type2));
+ memset(t, 0, len);
+
+ /* Verify the contained object handles */
+ t->number_contained_objects =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_BASEBOARD_OBJS_NUM);
+
+ if ((t->number_contained_objects * sizeof(u16) != obj_hdl_size) ||
+ (!obj_hdl && (t->number_contained_objects || obj_hdl_size)) ||
+ (obj_hdl && (!t->number_contained_objects || !obj_hdl_size))) {
+ /*
+ * Error with returning 0-length when any of below rules does
+ * not match:
+ * 1. Contained Object Handles length must be equal to (Object
+ * Handle Length * Object Number).
+ * 2. If no Contained Object Handles exist, Object Number must
+ * be 0, and versa vice.
+ */
+ unmap_sysmem(t);
+ return 0;
+ }
+
fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle);
+
+ obj_addr = (u8 *)t + offsetof(struct smbios_type2, eos);
+ /* eos is at the end of the structure */
+ eos_addr = (u8 *)t + len - sizeof(t->eos);
smbios_set_eos(ctx, t->eos);
- t->manufacturer = smbios_add_prop_si(ctx, "manufacturer",
-
SYSINFO_ID_SMBIOS_BASEBOARD_MANUFACTURER,
- NULL);
- t->product_name = smbios_add_prop_si(ctx, "product",
-
SYSINFO_ID_SMBIOS_BASEBOARD_PRODUCT,
- NULL);
- t->version = smbios_add_prop_si(ctx, "version",
- SYSINFO_ID_SMBIOS_BASEBOARD_VERSION,
- NULL);
+ t->manufacturer =
+ smbios_add_prop_si(ctx, "manufacturer",
+ SYSINFO_ID_SMBIOS_BASEBOARD_MANUFACTURER,
+ NULL);
+ t->product_name =
+ smbios_add_prop_si(ctx, "product",
+ SYSINFO_ID_SMBIOS_BASEBOARD_PRODUCT,
+ NULL);
+ t->version =
+ smbios_add_prop_si(ctx, "version",
+ SYSINFO_ID_SMBIOS_BASEBOARD_VERSION,
+ NULL);
+ t->serial_number =
+ smbios_add_prop_si(ctx, "serial",
+ SYSINFO_ID_SMBIOS_BASEBOARD_SERIAL,
+ NULL);
+ t->asset_tag_number =
+ smbios_add_prop_si(ctx, "asset-tag",
+ SYSINFO_ID_SMBIOS_BASEBOARD_ASSET_TAG,
+ NULL);
+ t->feature_flags =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_BASEBOARD_FEATURE);
+
+ t->chassis_location =
+ smbios_add_prop_si(ctx, "chassis-location",
+ SYSINFO_ID_SMBIOS_BASEBOARD_CHASSIS_LOCAT,
+ NULL);
+ t->board_type =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_BASEBOARD_TYPE);
+
+ /* Get the objs from driver */
+ if (obj_hdl)
+ memcpy(obj_addr, obj_hdl, obj_hdl_size);
- t->serial_number = smbios_add_prop_si(ctx, "serial",
-
SYSINFO_ID_SMBIOS_BASEBOARD_SERIAL,
- NULL);
- t->asset_tag_number = smbios_add_prop_si(ctx, "asset-tag",
-
SYSINFO_ID_SMBIOS_BASEBOARD_ASSET_TAG,
- NULL);
- t->feature_flags = SMBIOS_BOARD_FEATURE_HOSTING;
- t->board_type = SMBIOS_BOARD_MOTHERBOARD;
t->chassis_handle = handle + 1;
- len = t->length + smbios_string_table_len(ctx);
+ len = t->hdr.length + smbios_string_table_len(ctx);
*current += len;
unmap_sysmem(t);
@@ -463,20 +545,94 @@ static int smbios_write_type3(ulong *current, int handle,
struct smbios_ctx *ctx)
{
struct smbios_type3 *t;
- int len = sizeof(struct smbios_type3);
+ int len = sizeof(*t);
+ u8 *elem = NULL;
+ u8 *elem_addr, *eos_addr, *sku_num_addr;
+ size_t elem_size = 0;
+
+ if (!sysinfo_get_data(ctx->dev, SYSINFO_ID_SMBIOS_ENCLOSURE_ELEMENTS,
+ &elem, &elem_size))
+ len += elem_size; /* Add the dynamic part */
t = map_sysmem(*current, len);
- memset(t, 0, sizeof(struct smbios_type3));
+ memset(t, 0, len);
+
+ /* Verify the contained elements */
+ t->element_count =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_ENCLOSURE_ELEMENT_CNT);
+
+ t->element_record_length =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_ENCLOSURE_ELEMENT_LEN);
+
+ if ((elem_size != t->element_record_length * t->element_count) ||
+ (!elem && (t->element_count || t->element_record_length ||
+ elem_size)) ||
+ (elem && (t->element_record_length < sizeof(struct elem_hdr) ||
+ !elem_size))) {
+ /*
+ * Error with returning 0-length when any of below rules does
+ * not match:
+ * 1. Contained Elements length must be equal to (Element
+ * Record Length * Element Count).
+ * 2. If no Contained Elements exist, Element Count and Element
+ * Record Length must be 0.
+ * 3. If Contained Elements exist, Element Record Length must
+ * be at least the size of the Element Record Header.
+ */
+ unmap_sysmem(t);
+ return 0;
+ }
+
fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle);
- smbios_set_eos(ctx, t->eos);
- t->manufacturer = smbios_add_prop(ctx, "manufacturer", NULL);
- t->chassis_type = SMBIOS_ENCLOSURE_DESKTOP;
- t->bootup_state = SMBIOS_STATE_SAFE;
- t->power_supply_state = SMBIOS_STATE_SAFE;
- t->thermal_state = SMBIOS_STATE_SAFE;
- t->security_status = SMBIOS_SECURITY_NONE;
-
- len = t->length + smbios_string_table_len(ctx);
+
+ elem_addr = (u8 *)t + offsetof(struct smbios_type3, sku_number);
+ sku_num_addr = elem_addr + elem_size;
+
+ /* eos is at the end of the structure */
+ eos_addr = (u8 *)t + len - sizeof(t->eos);
+ smbios_set_eos(ctx, eos_addr);
+
+ t->manufacturer =
+ smbios_add_prop_si(ctx, "manufacturer",
+ SYSINFO_ID_SMBIOS_ENCLOSURE_MANUFACTURER,
+ NULL);
+
+ t->chassis_type = smbios_get_val_si(ctx,
+ SYSINFO_ID_SMBIOS_ENCLOSURE_TYPE);
+ t->version = smbios_add_prop_si(ctx, "version",
+ SYSINFO_ID_SMBIOS_ENCLOSURE_VERSION,
+ NULL);
+ t->serial_number =
+ smbios_add_prop_si(ctx, "serial",
+ SYSINFO_ID_SMBIOS_ENCLOSURE_SERIAL,
+ NULL);
+ t->asset_tag_number =
+ smbios_add_prop_si(ctx, "asset-tag",
+ SYSINFO_ID_SMBIOS_BASEBOARD_ASSET_TAG,
+ NULL);
+ t->bootup_state = smbios_get_val_si(ctx,
+ SYSINFO_ID_SMBIOS_ENCLOSURE_BOOTUP);
+ t->power_supply_state =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_ENCLOSURE_POW);
+ t->thermal_state =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_ENCLOSURE_THERMAL);
+ t->security_status =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_ENCLOSURE_SECURITY);
+ t->oem_defined = smbios_get_val_si(ctx,
+ SYSINFO_ID_SMBIOS_ENCLOSURE_OEM);
+ t->height = smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_ENCLOSURE_HEIGHT);
+ t->number_of_power_cords =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_ENCLOSURE_POWCORE_NUM);
+
+ /* Get the elements from driver */
+ if (elem)
+ memcpy(elem_addr, elem, elem_size);
+
+ *sku_num_addr =
+ smbios_add_prop_si(ctx, "sku", SYSINFO_ID_SMBIOS_ENCLOSURE_SKU,
+ NULL);
+
+ len = t->hdr.length + smbios_string_table_len(ctx);
*current += len;
unmap_sysmem(t);
@@ -489,6 +645,8 @@ static void smbios_write_type4_dm(struct smbios_type4 *t,
u16 processor_family = SMBIOS_PROCESSOR_FAMILY_UNKNOWN;
const char *vendor = NULL;
const char *name = NULL;
+ u8 *id_data = NULL;
+ size_t id_size = 0;
#ifdef CONFIG_CPU
char processor_name[49];
@@ -511,31 +669,97 @@ static void smbios_write_type4_dm(struct smbios_type4 *t,
}
#endif
- t->processor_family = 0xfe;
+ if (processor_family == SMBIOS_PROCESSOR_FAMILY_UNKNOWN)
+ processor_family =
+ smbios_get_val_si(ctx,
+ SYSINFO_ID_SMBIOS_PROCESSOR_FAMILY2);
+
+ t->processor_family = SMBIOS_PROCESSOR_FAMILY_EXT;
t->processor_family2 = processor_family;
- t->processor_manufacturer = smbios_add_prop(ctx, NULL, vendor);
- t->processor_version = smbios_add_prop(ctx, NULL, name);
+
+ t->processor_manufacturer =
+ smbios_add_prop_si(ctx, NULL,
+ SYSINFO_ID_SMBIOS_PROCESSOR_MANUFACT,
+ vendor);
+ t->processor_version =
+ smbios_add_prop_si(ctx, NULL,
+ SYSINFO_ID_SMBIOS_PROCESSOR_VERSION,
+ name);
+
+ if (t->processor_id[0] || t->processor_id[1])
+ return;
+
+ if (sysinfo_get_data(ctx->dev, SYSINFO_ID_SMBIOS_PROCESSOR_ID,
+ &id_data, &id_size) ||
+ id_size != sizeof(t->processor_id))
+ return;
+ if (id_data)
+ memcpy((u8 *)t->processor_id, id_data, id_size);
+
}
static int smbios_write_type4(ulong *current, int handle,
struct smbios_ctx *ctx)
{
struct smbios_type4 *t;
- int len = sizeof(struct smbios_type4);
+ int len = sizeof(*t);
t = map_sysmem(*current, len);
- memset(t, 0, sizeof(struct smbios_type4));
+ memset(t, 0, len);
fill_smbios_header(t, SMBIOS_PROCESSOR_INFORMATION, len, handle);
smbios_set_eos(ctx, t->eos);
- t->processor_type = SMBIOS_PROCESSOR_TYPE_CENTRAL;
+ t->socket_design =
+ smbios_add_prop_si(ctx, NULL,
+ SYSINFO_ID_SMBIOS_PROCESSOR_SOCKET,
+ NULL);
+ t->processor_type =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_TYPE);
smbios_write_type4_dm(t, ctx);
- t->status = SMBIOS_PROCESSOR_STATUS_ENABLED;
- t->processor_upgrade = SMBIOS_PROCESSOR_UPGRADE_NONE;
- t->l1_cache_handle = 0xffff;
- t->l2_cache_handle = 0xffff;
- t->l3_cache_handle = 0xffff;
- len = t->length + smbios_string_table_len(ctx);
+ t->voltage =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_VOLTAGE);
+ t->external_clock =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_EXT_CLOCK);
+ t->max_speed =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_MAX_SPEED);
+ t->current_speed =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_CUR_SPEED);
+ t->status =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_STATUS);
+ t->processor_upgrade =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_UPGRADE);
+
+ t->l1_cache_handle = SMBIOS_CACHE_HANDLE_NONE;
+ t->l2_cache_handle = SMBIOS_CACHE_HANDLE_NONE;
+ t->l3_cache_handle = SMBIOS_CACHE_HANDLE_NONE;
+
+ t->serial_number = smbios_add_prop_si(ctx, NULL,
+ SYSINFO_ID_SMBIOS_PROCESSOR_SN,
+ NULL);
+ t->asset_tag = smbios_add_prop_si(ctx, NULL,
+ SYSINFO_ID_SMBIOS_PROCESSOR_ASSET_TAG,
+ NULL);
+ t->part_number = smbios_add_prop_si(ctx, NULL,
+ SYSINFO_ID_SMBIOS_PROCESSOR_PN,
+ NULL);
+ t->core_count =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_CORE_CNT);
+ t->core_enabled =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_CORE_EN);
+ t->thread_count =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_THREAD_CNT);
+ t->processor_characteristics =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_CHARA);
+ t->core_count2 =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_CORE_CNT2);
+ t->core_enabled2 =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_CORE_EN2);
+ t->thread_count2 =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_THREAD_CNT2);
+ t->thread_enabled =
+ smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_THREAD_EN);
+
+ len = t->hdr.length + smbios_string_table_len(ctx);
*current += len;
unmap_sysmem(t);
@@ -546,10 +770,10 @@ static int smbios_write_type32(ulong *current, int handle,
struct smbios_ctx *ctx)
{
struct smbios_type32 *t;
- int len = sizeof(struct smbios_type32);
+ int len = sizeof(*t);
t = map_sysmem(*current, len);
- memset(t, 0, sizeof(struct smbios_type32));
+ memset(t, 0, len);
fill_smbios_header(t, SMBIOS_SYSTEM_BOOT_INFORMATION, len, handle);
smbios_set_eos(ctx, t->eos);
@@ -563,10 +787,10 @@ static int smbios_write_type127(ulong *current, int
handle,
struct smbios_ctx *ctx)
{
struct smbios_type127 *t;
- int len = sizeof(struct smbios_type127);
+ int len = sizeof(*t);
t = map_sysmem(*current, len);
- memset(t, 0, sizeof(struct smbios_type127));
+ memset(t, 0, len);
fill_smbios_header(t, SMBIOS_END_OF_TABLE, len, handle);
*current += len;
@@ -598,7 +822,7 @@ ulong write_smbios_table(ulong addr)
int i;
ctx.node = ofnode_null();
- if (IS_ENABLED(CONFIG_OF_CONTROL) && CONFIG_IS_ENABLED(SYSINFO)) {
+ if (CONFIG_IS_ENABLED(SYSINFO)) {
uclass_first_device(UCLASS_SYSINFO, &ctx.dev);
if (ctx.dev) {
int ret;