summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Frisch <bfrisch@gmail.com>2015-05-09 19:52:18 -0500
committerPatrick Georgi <pgeorgi@google.com>2015-07-07 08:23:33 +0200
commit72af5d79f9f66e59533f00b58b4cc528658c904b (patch)
tree464fe2d1e8da9f83ccb8a3c7c6f1cac00e0120f0
parentf6dde95e8722bf8b5cfbba9469f3aabea3a593ab (diff)
downloadcoreboot-72af5d79f9f66e59533f00b58b4cc528658c904b.tar.xz
smbios: Calculate SMBIOS Max Struct size
The SMBIOS Specification 2.3 and up defines Maximum Structure Size as the "Size of the largest SMBIOS structure, in bytes, and encompasses the structure’s formatted area and text strings." The hardcoded size is too small to accurately represent the maximum SMBIOS structure sizes. While the field is not used by Linux it is used by some RTOS implementations, eg. VxWorks. TEST=Booted Linux and ran github.com/bfrisch/dmidecode which verified the maximum structure size on Minnowboard Max. Change-Id: I98087975c53a02857742dea283f4e303485b2ffe Signed-off-by: Ben Frisch <bfrisch@gmail.com> Reviewed-on: http://review.coreboot.org/10163 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Reviewed-by: Patrick Georgi <pgeorgi@google.com>
-rw-r--r--src/arch/x86/boot/smbios.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/src/arch/x86/boot/smbios.c b/src/arch/x86/boot/smbios.c
index 1dbe32dc2d..fc5ac6634f 100644
--- a/src/arch/x86/boot/smbios.c
+++ b/src/arch/x86/boot/smbios.c
@@ -529,11 +529,14 @@ static int smbios_walk_device_tree(struct device *tree, int *handle, unsigned lo
return len;
}
+#define update_max(len, max_len, stmt) do { int tmp = stmt; max_len = MAX(max_len, tmp); len += tmp; } while(0)
unsigned long smbios_write_tables(unsigned long current)
{
struct smbios_entry *se;
unsigned long tables;
- int len, handle = 0;
+ int len = 0;
+ int max_struct_size = 0;
+ int handle = 0;
current = ALIGN(current, 16);
printk(BIOS_DEBUG, "%s: %08lx\n", __func__, current);
@@ -543,28 +546,28 @@ unsigned long smbios_write_tables(unsigned long current)
current = ALIGN(current, 16);
tables = current;
- len = smbios_write_type0(&current, handle++);
- len += smbios_write_type1(&current, handle++);
- len += smbios_write_type2(&current, handle++);
- len += smbios_write_type3(&current, handle++);
- len += smbios_write_type4(&current, handle++);
- len += smbios_write_type11(&current, &handle);
+ update_max(len, max_struct_size, smbios_write_type0(&current, handle++));
+ update_max(len, max_struct_size, smbios_write_type1(&current, handle++));
+ update_max(len, max_struct_size, smbios_write_type2(&current, handle++));
+ update_max(len, max_struct_size, smbios_write_type3(&current, handle++));
+ update_max(len, max_struct_size, smbios_write_type4(&current, handle++));
+ update_max(len, max_struct_size, smbios_write_type11(&current, &handle));
#if CONFIG_ELOG
- len += elog_smbios_write_type15(&current, handle++);
+ update_max(len, max_struct_size, smbios_write_type15(&current, &handle));
#endif
- len += smbios_write_type17(&current, &handle);
- len += smbios_write_type32(&current, handle++);
+ update_max(len, max_struct_size, smbios_write_type17(&current, &handle));
+ update_max(len, max_struct_size, smbios_write_type32(&current, handle++));
- len += smbios_walk_device_tree(all_devices, &handle, &current);
+ update_max(len, max_struct_size, smbios_walk_device_tree(all_devices, &handle, &current));
- len += smbios_write_type127(&current, handle++);
+ update_max(len, max_struct_size, smbios_write_type127(&current, handle++));
memset(se, 0, sizeof(struct smbios_entry));
memcpy(se->anchor, "_SM_", 4);
se->length = sizeof(struct smbios_entry);
se->major_version = 2;
se->minor_version = 7;
- se->max_struct_size = 24;
+ se->max_struct_size = max_struct_size;
se->struct_count = handle;
memcpy(se->intermediate_anchor_string, "_DMI_", 5);