[PATCH 03/10] smbios: Refactor SMBIOS library

Heinrich Schuchardt xypron.glpk at gmx.de
Mon Sep 9 17:30:55 CEST 2024


On 16.08.24 17:46, Raymond Mao wrote:
> Current SMBIOS library does not fully match to the specification.
> It hardcodes values instead of exposing values from the device.
> It does not support dynamic length for contained object handles
> or elements and misses the handling of a few fields.
>
> The refactoring of this patch includes:
> 1. Expose values from device via sysinfo interface.
> 2. Replace smbios_add_prop with smbios_add_prop_si to allow getting
>     string values from sysinfo.
> 3. Add smbios_get_val_si to get int values from sysinfo.
> 4. Use sysinfo_get_data to get data area like contained object
>     handles, elements or processor id.
> 5. Refactor SMBIOS cmd print functions to match the command output
>     with the specification
> 6. Add new print functions for Type 0, 3 and 4.
> 7. Miscellaneous fixes in SMBIOS.
>
> Signed-off-by: Raymond Mao <raymond.mao at linaro.org>
> ---
>   cmd/smbios.c     | 268 +++++++++++++++++++++++++++++++++--
>   include/smbios.h | 116 +++++++++++----
>   lib/smbios.c     | 358 ++++++++++++++++++++++++++++++++++++++---------
>   3 files changed, 632 insertions(+), 110 deletions(-)
>
> diff --git a/cmd/smbios.c b/cmd/smbios.c
> index d3bd8b12a67..8e2bf46a09c 100644
> --- a/cmd/smbios.c
> +++ b/cmd/smbios.c
> @@ -26,6 +26,71 @@ static const char * const wakeup_type_strings[] = {
>   	"AC Power Restored",	/* 0x08 */
>   };
>
> +static const char * const boardtype_strings[] = {
> +	"Reserved",			/* 0x00 */

0x00 is not in the spec. For all values that are not in the spec just
print the hexadecimal number.

> +	"Unknown",			/* 0x01 */
> +	"Other",			/* 0x02 */
> +	"Server Blade",			/* 0x03 */
> +	"Connectivity Switch",		/* 0x04 */
> +	"System Management Module",	/* 0x05 */
> +	"Processor Module",		/* 0x06 */
> +	"I/O Module",			/* 0x07 */
> +	"Memory Module",		/* 0x08 */
> +	"Daughter board",		/* 0x09 */
> +	"Motherboard",			/* 0x0a */
> +	"Processor/Memory Module",	/* 0x0b */
> +	"Processor/IO Module",		/* 0x0c */
> +	"Interconnect board",		/* 0x0d */
> +};
> +
> +static const char * const chassis_state_strings[] = {
> +	"Reserved",			/* 0x00 */

ditto

> +	"Other",			/* 0x01 */
> +	"Unknown",			/* 0x02 */
> +	"Safe",				/* 0x03 */
> +	"Warning",			/* 0x04 */
> +	"Critical",			/* 0x05 */
> +	"Non-recoverable",		/* 0x06 */
> +};
> +
> +static const char * const chassis_security_strings[] = {
> +	"Reserved",			/* 0x00 */

ditto

> +	"Other",			/* 0x01 */
> +	"Unknown",			/* 0x02 */
> +	"None",				/* 0x03 */
> +	"External interface locked out",/* 0x04 */
> +	"External interface enabled",	/* 0x05 */
> +};
> +
> +static const char * const processor_type_strings[] = {
> +	"Reserved",			/* 0x00 */

ditto

> +	"Other",			/* 0x01 */
> +	"Unknown",			/* 0x02 */
> +	"Central Processor",		/* 0x03 */
> +	"Math Processor",		/* 0x04 */
> +	"DSP Processor",		/* 0x05 */
> +	"Video Processor",		/* 0x06 */
> +};
> +
> +static const char * const processor_family_strings[] = {
> +	[0] = "Other",
> +	[1] = "Unknown",
> +	[2 ... 253] = "Other", /* skip these definitions from now */

"Other" should only be used for 0x01. In all other cases print the
hexadecimal number.

As we have hundreds of unused strings we should use a structure which
contains only used values to reduce the structure size, e.g.

struct processor_family_str {
	u16 index;
	const char *str;
};

const struct processor_family_str processor_family_strings;

> +	[254] = "Refer to 'Processor Family 2'",

This string should never be printed. Instead use the 'Processor Family
2' field to identify the family.

> +	[255] = "Reserved",
> +	[256] = "ARMv7",
> +	[257] = "ARMv8",

Please, add:

0x200 512 RISC-V RV32
0x201 513 RISC-V RV64

and the LoongArch values that we support.

Best regards

Heinrich

> +};
> +
> +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));

u16 family = table->processor_family;
if (family == 0xfe)
	family = table->processor_family2;

For values above 0xfe we must evaluate the table->processor_family2 field.

Best regards

Heinrich

> +	printf("\tProcessor Family: %s\n",
> +	       smbios_processor_family_str(table->processor_family));

smbios_processor_family_str(family));

> +	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;



More information about the U-Boot mailing list