[coreboot-gerrit] New patch to review for coreboot: 70e5138 device/dram/ddr3: Move CRC calculation in a separate function

Alexandru Gagniuc (mr.nuke.me@gmail.com) gerrit at coreboot.org
Tue Dec 17 19:13:41 CET 2013


Alexandru Gagniuc (mr.nuke.me at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4537

-gerrit

commit 70e5138fba96b0dfcd8f265ac0b180f251346d97
Author: Alexandru Gagniuc <mr.nuke.me at gmail.com>
Date:   Tue Dec 17 13:08:01 2013 -0500

    device/dram/ddr3: Move CRC calculation in a separate function
    
    Calculating the CRC of a SPD may be useful by itself, so split that
    part of the code in a separate function.
    
    Change-Id: I6c20d3db380551865126fd890e89de6b06359207
    Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
---
 src/device/dram/ddr3.c         | 62 ++++++++++++++++++++++++++++--------------
 src/include/device/dram/ddr3.h |  1 +
 2 files changed, 43 insertions(+), 20 deletions(-)

diff --git a/src/device/dram/ddr3.c b/src/device/dram/ddr3.c
index d98de91..9b4f490 100644
--- a/src/device/dram/ddr3.c
+++ b/src/device/dram/ddr3.c
@@ -49,6 +49,46 @@ int dimm_is_registered(enum spd_dimm_type type)
 }
 
 /**
+ * \brief Calculate the CRC of a DDR3 SPD
+ *
+ * @param spd pointer to raw SPD data
+ * @param len length of data in SPD
+ *
+ * @return the CRC of the SPD data, or 0 when spd data is truncated.
+ */
+u16 spd_ddr3_calc_crc(u8 *spd, int len)
+{
+	int n_crc, i;
+	u8 *ptr;
+	u16 crc;
+
+	/* Find the number of bytes covered by CRC */
+	if (spd[0] & 0x80) {
+		n_crc = 117;
+	} else {
+		n_crc = 126;
+	}
+
+	if (len < n_crc)
+		/* 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;
+}
+
+/**
  * \brief Decode the raw SPD data
  *
  * Decodes a raw SPD data from a DDR3 DIMM, and organizes it into a
@@ -68,9 +108,8 @@ int dimm_is_registered(enum spd_dimm_type type)
  */
 int spd_decode_ddr3(dimm_attr * dimm, spd_raw_data spd)
 {
-	int nCRC, i, ret;
+	int ret;
 	u16 crc, spd_crc;
-	u8 *ptr = spd;
 	u8 ftb_divisor, ftb_dividend, capacity_shift, bus_width, sdram_width;
 	u8 reg8;
 	u32 mtb;		/* medium time base */
@@ -88,24 +127,7 @@ int spd_decode_ddr3(dimm_attr * dimm, spd_raw_data spd)
 	}
 	dimm->dram_type = SPD_MEMORY_TYPE_SDRAM_DDR3;
 
-	/* Find the number of bytes covered by CRC */
-	if (spd[0] & 0x80) {
-		nCRC = 117;
-	} else {
-		nCRC = 126;
-	}
-
-	/* Compute the CRC */
-	crc = 0;
-	while (--nCRC >= 0) {
-		crc = crc ^ (int)*ptr++ << 8;
-		for (i = 0; i < 8; ++i)
-			if (crc & 0x8000) {
-				crc = crc << 1 ^ 0x1021;
-			} else {
-				crc = crc << 1;
-			}
-	}
+	crc = spd_ddr3_calc_crc(spd, sizeof(spd));
 	/* Compare with the CRC in the SPD */
 	spd_crc = (spd[127] << 8) + spd[126];
 	/* Verify the CRC is correct */
diff --git a/src/include/device/dram/ddr3.h b/src/include/device/dram/ddr3.h
index 53a42ee..b19c51c 100644
--- a/src/include/device/dram/ddr3.h
+++ b/src/include/device/dram/ddr3.h
@@ -170,6 +170,7 @@ enum spd_status {
 
 typedef u8 spd_raw_data[256];
 
+u16 spd_ddr3_calc_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