Celes: Read dim count and spd index from smbios.

smbios has dim count and part number.
So, we can find correct spd info from part number.
From SPD index, we can get correct mosys output.

BUG=chrome-os-partner:45084
    chrome-os-partner:43986
BRANCH=master
TEST=read memory info with mosys on Celes.

Change-Id: Ib9b0d12880118d41d56fca22857655ab4cb8274f
Signed-off-by: jongpil19.jung <jongpil19.jung@samsung.com>
Reviewed-on: https://chromium-review.googlesource.com/299600
Commit-Ready: Jongpil Jung <jongpil19.jung@samsung.com>
Tested-by: Jongpil Jung <jongpil19.jung@samsung.com>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
(cherry picked from commit 27c9b254d4c9b115db95b314576e188b6bd7cf74)
Reviewed-on: https://chromium-review.googlesource.com/302240
Reviewed-by: David Hendricks <dhendrix@chromium.org>
diff --git a/platform/experimental/strago/memory.c b/platform/experimental/strago/memory.c
index f0e87b2..086bbb3 100755
--- a/platform/experimental/strago/memory.c
+++ b/platform/experimental/strago/memory.c
@@ -105,6 +105,46 @@
 	return 0;
 }
 
+
+/*
+ * find_spd_by_part_number - find spd index by part number
+ *
+ * @intf:	platform interface
+ * @dimm:	DIMM number
+ * @spd :	spd.bin address
+ * @num_spd:number of spd
+ *
+ * returns matched spd index by part number
+ */
+static int find_spd_by_part_number(struct platform_intf *intf, int dimm,
+				   uint8_t *spd, uint32_t num_spd)
+{
+	char *smbios_part_num;
+	char spd_part_num[19];
+	uint8_t i;
+	uint8_t *ptr;
+	struct smbios_table table;
+
+	lprintf(LOG_DEBUG, "Use SMBIOS type 17 to get memory information\n");
+	if (smbios_find_table(intf, SMBIOS_TYPE_MEMORY, dimm, &table,
+			      SMBIOS_LEGACY_ENTRY_BASE,
+			      SMBIOS_LEGACY_ENTRY_LEN) < 0) {
+		lprintf(LOG_DEBUG, "Can't find smbios type17\n");
+		return -1;
+	}
+	smbios_part_num = table.string[table.data.mem_device.part_number];
+
+	for (i = 0; i < num_spd; i++) {
+		ptr = (spd + i * 256);
+		memcpy(spd_part_num, ptr + 128, 18);
+		if (!memcmp(smbios_part_num, spd_part_num, 18)) {
+			lprintf(LOG_DEBUG, "found %x\n", i);
+			return i;
+		}
+	}
+	return -1;
+}
+
 static int strago_spd_read_cbfs(struct platform_intf *intf,
 				int dimm, int reg, int len, uint8_t *buf)
 {
@@ -113,7 +153,8 @@
 	size_t size = STRAGO_HOST_FIRMWARE_ROM_SIZE;
 	struct cbfs_file *file;
 	int spd_index = 0;
-	uint32_t spd_offset;
+	uint32_t spd_offset, num_spd;
+	uint8_t *ptr;
 
 	if (dimm >= strago_dimm_count(intf)) {
 		lprintf(LOG_DEBUG, "%s: Invalid DIMM specified\n", __func__);
@@ -134,7 +175,12 @@
 	if ((file = cbfs_find("spd.bin", bootblock, size)) == NULL)
 		return -1;
 
-	/* Use an spd index of 0, as spd.bin for strago has only 1 entry */
+	ptr = (uint8_t *)file + ntohl(file->offset);
+	num_spd = ntohl(file->len) / 256;
+	spd_index = find_spd_by_part_number(intf, dimm, ptr, num_spd);
+	if (spd_index < 0)
+		return -1;
+
 	spd_offset = ntohl(file->offset) + (spd_index * 256);
 	lprintf(LOG_DEBUG, "Using memory config %u\n", spd_index);
 	memcpy(buf, (void *)file + spd_offset + reg, len);