[coreboot-gerrit] Patch set updated for coreboot: device/dram/ddr3: Calculate CRC16 of SPD unique identifier

Kyösti Mälkki (kyosti.malkki@gmail.com) gerrit at coreboot.org
Sat Nov 19 19:45:21 CET 2016


Kyösti Mälkki (kyosti.malkki at gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17486

-gerrit

commit aeb705e433ae4ea01700342b393a937831a92cfe
Author: Kyösti Mälkki <kyosti.malkki at gmail.com>
Date:   Fri Nov 18 18:41:17 2016 +0200

    device/dram/ddr3: Calculate CRC16 of SPD unique identifier
    
    Specification allows for the unique identifier bytes 117..125
    to be excluded of CRC calculation. For such SPD, the CRC
    would not identify replacement between two identical DIMM parts,
    while memory training needs to be redone.
    
    Change-Id: I8e830018b15c344d9f72f921ab84893f633f7654
    Signed-off-by: Kyösti Mälkki <kyosti.malkki at gmail.com>
---
 src/device/dram/ddr3.c         | 53 +++++++++++++++++++++++++++++-------------
 src/include/device/dram/ddr3.h |  1 +
 2 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/src/device/dram/ddr3.c b/src/device/dram/ddr3.c
index cb5b685..0d15a93 100644
--- a/src/device/dram/ddr3.c
+++ b/src/device/dram/ddr3.c
@@ -46,6 +46,24 @@ int dimm_is_registered(enum spd_dimm_type type)
 	return 0;
 }
 
+static u16 crc16(const u8 *ptr, int n_crc)
+{
+	int i;
+	u16 crc = 0;
+
+	while (--n_crc >= 0) {
+		crc = crc ^ (int)*ptr++ << 8;
+		for (i = 0; i < 8; ++i)
+			if (crc & 0x8000) {
+				crc = (crc << 1) ^ 0x1021;
+			} else {
+				crc = crc << 1;
+			}
+	}
+
+	return crc;
+}
+
 /**
  * \brief Calculate the CRC of a DDR3 SPD
  *
@@ -56,9 +74,7 @@ int dimm_is_registered(enum spd_dimm_type type)
  */
 u16 spd_ddr3_calc_crc(u8 *spd, int len)
 {
-	int n_crc, i;
-	u8 *ptr;
-	u16 crc;
+	int n_crc;
 
 	/* Find the number of bytes covered by CRC */
 	if (spd[0] & 0x80) {
@@ -71,19 +87,24 @@ u16 spd_ddr3_calc_crc(u8 *spd, int len)
 		/* Not enough bytes available to get the CRC */
 		return 0;
 
-	/* Compute the CRC */
-	crc = 0;
-	ptr = spd;
-	while (--n_crc >= 0) {
-		crc = crc ^ (int)*ptr++ << 8;
-		for (i = 0; i < 8; ++i)
-			if (crc & 0x8000) {
-				crc = crc << 1 ^ 0x1021;
-			} else {
-				crc = crc << 1;
-			}
-	}
-	return crc;
+	return crc16(spd, n_crc);
+}
+
+/**
+ * \brief Calculate the CRC of a DDR3 SPD unique identifier
+ *
+ * @param spd pointer to raw SPD data
+ * @param len length of data in SPD
+ *
+ * @return the CRC of SPD data bytes 117..127, or 0 when spd data is truncated.
+ */
+u16 spd_ddr3_calc_unique_crc(u8 *spd, int len)
+{
+	if (len < (117 + 11))
+		/* Not enough bytes available to get the CRC */
+		return 0;
+
+	return crc16(&spd[117], 11);
 }
 
 /**
diff --git a/src/include/device/dram/ddr3.h b/src/include/device/dram/ddr3.h
index 7388012..905aa84 100644
--- a/src/include/device/dram/ddr3.h
+++ b/src/include/device/dram/ddr3.h
@@ -199,6 +199,7 @@ enum ddr3_xmp_profile {
 typedef u8 spd_raw_data[256];
 
 u16 spd_ddr3_calc_crc(u8 *spd, int len);
+u16 spd_ddr3_calc_unique_crc(u8 *spd, int len);
 int spd_decode_ddr3(dimm_attr * dimm, spd_raw_data spd_data);
 int dimm_is_registered(enum spd_dimm_type type);
 void dram_print_spd_ddr3(const dimm_attr * dimm);



More information about the coreboot-gerrit mailing list