smbios: Fix issue finding SMBIOS string

The code that attempted to find a specific SMBIOS table entry by
a hardcoded string index is incorrect as the strings do not need
to be in any specific order.  Instead the string index value from
the table must be used to guarantee finding the right string.

This happens with (recent?) coreboot where the SMBIOS System Version
is stored at string index 3 and not index 2 like mosys was using.

Also fix the probe routine that was assuming the system name would
always be at string index 1.

BUG=chrome-os-partner:33031
BRANCH=samus
TEST=manual:
1) check that 'mosys platform version' returns the correct string
2) check that 'mosys platform vendor' returns the correct string
3) tested on stumpy and samus

Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/223710
Reviewed-by: Aaron Durbin <adurbin@chromium.org>

(cherry picked from commit 4e209285d00e040677c89e00daa67d2f94c498f4)

Change-Id: I243e942d9cb9ee2d462aeb0d887e45a9576537b7
Reviewed-on: https://chromium-review.googlesource.com/224561
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Commit-Queue: Ricky Liang <jcliang@chromium.org>
Tested-by: Ricky Liang <jcliang@chromium.org>
diff --git a/lib/misc/probe.c b/lib/misc/probe.c
index a8265e5..26743cb 100644
--- a/lib/misc/probe.c
+++ b/lib/misc/probe.c
@@ -121,11 +121,11 @@
 	if (intf->cb->smbios && intf->cb->smbios->system_name) {
 		id = intf->cb->smbios->system_name(intf);
 	} else {
-		id = smbios_find_string(intf,
-		                       SMBIOS_TYPE_SYSTEM,
-		                       1,
-		                       SMBIOS_LEGACY_ENTRY_BASE,
-		                       SMBIOS_LEGACY_ENTRY_LEN);
+		struct smbios_table table;
+		if (smbios_find_table(intf, SMBIOS_TYPE_SYSTEM, 0, &table,
+				      SMBIOS_LEGACY_ENTRY_BASE,
+				      SMBIOS_LEGACY_ENTRY_LEN) == 0)
+			id = table.string[table.data.system.name];
 	}
 
 probe_smbios_cmp:
diff --git a/lib/smbios/mosys_callbacks.c b/lib/smbios/mosys_callbacks.c
index 8f461c3..08af50c 100644
--- a/lib/smbios/mosys_callbacks.c
+++ b/lib/smbios/mosys_callbacks.c
@@ -105,16 +105,16 @@
 static char *smbios_bios_get_vendor(struct platform_intf *intf)
 {
 	char *str = NULL;
+	struct smbios_table table;
 
-	/* try normal SMBIOS approach first */
-	str = smbios_find_string(intf, SMBIOS_TYPE_BIOS, 0,
-	                         SMBIOS_LEGACY_ENTRY_BASE,
-	                         SMBIOS_LEGACY_ENTRY_LEN);
-
-	if (!str) {
+	if (smbios_find_table(intf, SMBIOS_TYPE_BIOS, 0, &table,
+			      SMBIOS_LEGACY_ENTRY_BASE,
+			      SMBIOS_LEGACY_ENTRY_LEN) < 0) {
 		lprintf(LOG_DEBUG, "%s: normal method failed, "
 		                   "trying sysfs\n", __func__);
 		str = smbios_scan_sysfs("bios_vendor");
+	} else {
+		str = mosys_strdup(table.string[table.data.bios.vendor]);
 	}
 
 	return str;
@@ -131,16 +131,17 @@
 static char *smbios_sysinfo_get_vendor(struct platform_intf *intf)
 {
 	char *str = NULL;
+	struct smbios_table table;
 
-	/* try normal SMBIOS approach first */
-	str = smbios_find_string(intf, SMBIOS_TYPE_SYSTEM, 0,
-	                         SMBIOS_LEGACY_ENTRY_BASE,
-	                         SMBIOS_LEGACY_ENTRY_LEN);
-
-	if (!str) {
+	if (smbios_find_table(intf, SMBIOS_TYPE_SYSTEM, 0, &table,
+			      SMBIOS_LEGACY_ENTRY_BASE,
+			      SMBIOS_LEGACY_ENTRY_LEN) < 0) {
 		lprintf(LOG_DEBUG, "%s: normal method failed, "
 		                   "trying sysfs\n", __func__);
 		str = smbios_scan_sysfs("sys_vendor");
+	} else {
+		str = mosys_strdup(table.string
+				   [table.data.system.manufacturer]);
 	}
 
 	return str;
@@ -157,14 +158,15 @@
 static char *smbios_sysinfo_get_name(struct platform_intf *intf)
 {
 	char *str = NULL;
+	struct smbios_table table;
 
-	str = smbios_find_string(intf, SMBIOS_TYPE_SYSTEM, 1,
-	                         SMBIOS_LEGACY_ENTRY_BASE,
-	                         SMBIOS_LEGACY_ENTRY_LEN);
-
-	if (!str) {
+	if (smbios_find_table(intf, SMBIOS_TYPE_SYSTEM, 0, &table,
+			      SMBIOS_LEGACY_ENTRY_BASE,
+			      SMBIOS_LEGACY_ENTRY_LEN) < 0) {
 		lprintf(LOG_DEBUG, "%s: attempting to use sysfs\n", __func__);
 		str = smbios_scan_sysfs("product_name");
+	} else {
+		str = mosys_strdup(table.string[table.data.system.name]);
 	}
 
 	return str;
@@ -181,15 +183,16 @@
 static char *smbios_sysinfo_get_version(struct platform_intf *intf)
 {
 	char *str = NULL;
+	struct smbios_table table;
 
-	str = smbios_find_string(intf, SMBIOS_TYPE_SYSTEM, 2,
-	                         SMBIOS_LEGACY_ENTRY_BASE,
-	                         SMBIOS_LEGACY_ENTRY_LEN);
-
-	if (!str) {
+	if (smbios_find_table(intf, SMBIOS_TYPE_SYSTEM, 0, &table,
+			      SMBIOS_LEGACY_ENTRY_BASE,
+			      SMBIOS_LEGACY_ENTRY_LEN) < 0) {
 		lprintf(LOG_INFO, "%s: normal approach failed, trying sysfs\n",
 		                  __func__);
 		str = smbios_scan_sysfs("product_version");
+	} else {
+		str = mosys_strdup(table.string[table.data.system.version]);
 	}
 
 	return str;
@@ -205,9 +208,14 @@
  */
 static char *smbios_sysinfo_get_family(struct platform_intf *intf)
 {
-	return smbios_find_string(intf, SMBIOS_TYPE_SYSTEM, 5,
-	                          SMBIOS_LEGACY_ENTRY_BASE,
-	                          SMBIOS_LEGACY_ENTRY_LEN);
+	struct smbios_table table;
+
+	if (smbios_find_table(intf, SMBIOS_TYPE_SYSTEM, 0, &table,
+			      SMBIOS_LEGACY_ENTRY_BASE,
+			      SMBIOS_LEGACY_ENTRY_LEN) < 0)
+		return NULL;
+
+	return mosys_strdup(table.string[table.data.system.family]);
 }
 
 /*
@@ -220,9 +228,14 @@
  */
 static char *smbios_sysinfo_get_sku(struct platform_intf *intf)
 {
-	return smbios_find_string(intf, SMBIOS_TYPE_SYSTEM, 4,
-	                          SMBIOS_LEGACY_ENTRY_BASE,
-	                          SMBIOS_LEGACY_ENTRY_LEN);
+	struct smbios_table table;
+
+	if (smbios_find_table(intf, SMBIOS_TYPE_SYSTEM, 0, &table,
+			      SMBIOS_LEGACY_ENTRY_BASE,
+			      SMBIOS_LEGACY_ENTRY_LEN) < 0)
+		return NULL;
+
+	return mosys_strdup(table.string[table.data.system.sku_number]);
 }
 
 struct smbios_cb smbios_sysinfo_cb = {