aboutsummaryrefslogtreecommitdiff
path: root/hdata
diff options
context:
space:
mode:
authorVasant Hegde <hegdevasant@linux.vnet.ibm.com>2017-10-13 16:51:19 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-12-18 17:58:32 -0600
commitc0840ae7330fcbc310d864894f7a8b79f32ce05e (patch)
tree48947c4c955a9237e229441fee60b9420dddc881 /hdata
parent5110b54067c0db11122ab9a57dd2dcc56f026581 (diff)
downloadskiboot-c0840ae7330fcbc310d864894f7a8b79f32ce05e.zip
skiboot-c0840ae7330fcbc310d864894f7a8b79f32ce05e.tar.gz
skiboot-c0840ae7330fcbc310d864894f7a8b79f32ce05e.tar.bz2
hdata: Parse SPD data
Parse SPD data and populate device tree. list of properites parsing from SPD: ----------------------------------- [root@ltc-wspoon dimm@d00f]# lsprop . memory-id 0000000c (12) <-- DIMM type product-version 00000032 (50) <-- Module Revision Code device_type "memory-dimm-ddr4" serial-number 15d9acb6 (366587062) status "okay" size 00004000 (16384) phandle 000000bd (189) ibm,loc-code "UOPWR.0000000-Node0-DIMM7" part-number "36ASF2G72PZ-2G6B2 " reg 0000d007 (53255) name "dimm" manufacturer-id 0000802c (32812) <-- Vendor ID, we can get vendor name from this ID Also update documentation. Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hdata')
-rw-r--r--hdata/memory.c50
1 files changed, 49 insertions, 1 deletions
diff --git a/hdata/memory.c b/hdata/memory.c
index 74eedff..27dc559 100644
--- a/hdata/memory.c
+++ b/hdata/memory.c
@@ -319,16 +319,56 @@ 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 bytes, 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");
+
+ /* DRAM device type */
+ dt_add_property_cells(dimm, "memory-id", spd[0x2]);
+
+ /* Module revision code */
+ dt_add_property_cells(dimm, "product-version", spd[0x15d]);
+
+ /* Serial number */
+ sn = (u32 *)&spd[0x145];
+ dt_add_property_cells(dimm, "serial-number", be32_to_cpu(*sn));
+
+ /* Part number */
+ dt_add_property_nstr(dimm, "part-number", &spd[0x149], 20);
+
+ /* Module manufacturer ID */
+ 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)) {
@@ -373,6 +413,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);
}
}