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 */
+	"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 */
+	"Other",			/* 0x01 */
+	"Unknown",			/* 0x02 */
+	"Safe",				/* 0x03 */
+	"Warning",			/* 0x04 */
+	"Critical",			/* 0x05 */
+	"Non-recoverable",		/* 0x06 */
+};
+
+static const char * const chassis_security_strings[] = {
+	"Reserved",			/* 0x00 */
+	"Other",			/* 0x01 */
+	"Unknown",			/* 0x02 */
+	"None",				/* 0x03 */
+	"External interface locked out",/* 0x04 */
+	"External interface enabled",	/* 0x05 */
+};
+
+static const char * const processor_type_strings[] = {
+	"Reserved",			/* 0x00 */
+	"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 */
+	[254] = "Refer to 'Processor Family 2'",
+	[255] = "Reserved",
+	[256] = "ARMv7",
+	[257] = "ARMv8",
+};
+
+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));
+	printf("\tProcessor Family: %s\n",
+	       smbios_processor_family_str(table->processor_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;
