[Skiboot] [PATCH v2 5/5] hdata: Parse SPD data

Vasant Hegde hegdevasant at linux.vnet.ibm.com
Mon Aug 28 17:18:03 AEST 2017


Parse SPD data and populate device tree.

list of properites parsing from SPD:
-----------------------------------
[root at ltc-wspoon dimm at d00f]# lsprop .
memory-id        0000000c (12)   <-- DIMM type
device_type      "memory-dimm-ddr4"
serial           15d9ad22 (366587170)
part-number      "36ASF2G72PZ-2G6B2   "
manufacturer-id  0000802c (32812)   <-- Vendor ID, we can get vendor name from this ID

Signed-off-by: Vasant Hegde <hegdevasant at linux.vnet.ibm.com>
---
 hdata/memory.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/hdata/memory.c b/hdata/memory.c
index d1570eb..956e0d7 100644
--- a/hdata/memory.c
+++ b/hdata/memory.c
@@ -319,16 +319,49 @@ static void vpd_add_ram_area(const struct HDIF_common_hdr *msarea)
 	}
 }
 
+static void vpd_parse_spd(struct dt_node *dimm, const char *spd, u32 size)
+{
+	u16 *vendor;
+	u32 *sn;
+
+	/* SPD is too small */
+	if (size < 512) {
+		prlog(PR_WARNING, "MSVPD: Invalid SPD size. "
+		      "Expected 512 byts, got %d\n", size);
+		return;
+	}
+
+	/* Supports DDR4 format pasing only */
+	if (spd[0x2] < 0xc) {
+		prlog(PR_WARNING,
+		      "MSVPD: SPD format (%x) not supported\n", spd[0x2]);
+		return;
+	}
+
+	dt_add_property_string(dimm, "device_type", "memory-dimm-ddr4");
+
+	dt_add_property_cells(dimm, "memory-id", be16_to_cpu(spd[0x2]));
+
+	sn = (u32 *)&spd[0x145];
+	dt_add_property_cells(dimm, "serial", be32_to_cpu(*sn));
+
+	dt_add_property_nstr(dimm, "part-number", &spd[0x149], 20);
+
+	vendor = (u16 *)&spd[0x140];
+	dt_add_property_cells(dimm, "manufacturer-id", be16_to_cpu(*vendor));
+}
+
 static void add_mca_dimm_info(struct dt_node *mca,
 			      const struct HDIF_common_hdr *msarea)
 {
-	unsigned int i;
+	unsigned int i, size;
 	const struct HDIF_child_ptr *ramptr;
 	const struct HDIF_common_hdr *ramarea;
 	const struct spira_fru_id *fru_id;
 	const struct HDIF_ram_area_id *ram_id;
 	const struct HDIF_ram_area_size *ram_area_sz;
 	struct dt_node *dimm;
+	const void *vpd_blob;
 
 	ramptr = HDIF_child_arr(msarea, 0);
 	if (!CHECK_SPPTR(ramptr)) {
@@ -371,6 +404,14 @@ static void add_mca_dimm_info(struct dt_node *mca,
 			dt_add_property_string(dimm, "status", "okay");
 		else
 			dt_add_property_string(dimm, "status", "disabled");
+
+		vpd_blob = HDIF_get_idata(ramarea, 1, &size);
+		if (!CHECK_SPPTR(vpd_blob))
+			continue;
+		if (vpd_valid(vpd_blob, size))
+			vpd_data_parse(dimm, vpd_blob, size);
+		else
+			vpd_parse_spd(dimm, vpd_blob, size);
 	}
 }
 
-- 
2.9.3



More information about the Skiboot mailing list