aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur Heymans <arthur@aheymans.xyz>2018-01-22 01:26:53 +0100
committerPatrick Georgi <pgeorgi@google.com>2018-04-09 09:31:11 +0000
commit97b337b252fe67f8ffb7a98f70f08835513920ba (patch)
tree393392768e234b0b99c0b909e5ce1502a64c2b10
parentf7dc972fde66d93143c3f6927087c13ae74a4828 (diff)
device/dram/ddr2.c: Add methods to compute to identify dram
DDR2 DIMMs are uniquely defined by SPD byte 64 till 72 and 93 till 98. Compute a crc16 over that data to provide a solid way to check DIMM identify. Reuse the crc16 function from ddr3.c to do this. Change-Id: I3c0c42786197f9b4eb3e42261c10ff5e4266120f Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/23345 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
-rw-r--r--src/device/dram/ddr2.c24
-rw-r--r--src/device/dram/ddr3.c6
-rw-r--r--src/include/device/dram/common.h2
-rw-r--r--src/include/device/dram/ddr2.h1
4 files changed, 30 insertions, 3 deletions
diff --git a/src/device/dram/ddr2.c b/src/device/dram/ddr2.c
index 921679c584..0d395c4315 100644
--- a/src/device/dram/ddr2.c
+++ b/src/device/dram/ddr2.c
@@ -72,6 +72,30 @@ u8 spd_ddr2_calc_checksum(u8 *spd, int len)
}
/**
+ * \brief Calculate the CRC of a DDR2 SPD unique identifier
+ *
+ * @param spd pointer to raw SPD data
+ * @param len length of data in SPD
+ *
+ * @return the CRC of SPD data bytes 64..72 and 93..98, or 0
+ * when spd data is truncated.
+ */
+u16 spd_ddr2_calc_unique_crc(const u8 *spd, int len)
+{
+ u8 id_bytes[15];
+ int i, j = 0;
+ if (len < 98)
+ /* Not enough bytes available to get the CRC */
+ return 0;
+ for (i = 64; i <= 72; i++)
+ id_bytes[j++] = spd[i];
+ for (i = 93; i <= 98; i++)
+ id_bytes[j++] = spd[i];
+
+ return ddr3_crc16(id_bytes, 15);
+}
+
+/**
* \brief Return size of SPD.
*
* Returns size of SPD. Usually 128 Byte.
diff --git a/src/device/dram/ddr3.c b/src/device/dram/ddr3.c
index 87aa3c5362..67f30092ea 100644
--- a/src/device/dram/ddr3.c
+++ b/src/device/dram/ddr3.c
@@ -46,7 +46,7 @@ int spd_dimm_is_registered_ddr3(enum spd_dimm_type type)
return 0;
}
-static u16 crc16(const u8 *ptr, int n_crc)
+u16 ddr3_crc16(const u8 *ptr, int n_crc)
{
int i;
u16 crc = 0;
@@ -87,7 +87,7 @@ u16 spd_ddr3_calc_crc(u8 *spd, int len)
/* Not enough bytes available to get the CRC */
return 0;
- return crc16(spd, n_crc);
+ return ddr3_crc16(spd, n_crc);
}
/**
@@ -104,7 +104,7 @@ u16 spd_ddr3_calc_unique_crc(u8 *spd, int len)
/* Not enough bytes available to get the CRC */
return 0;
- return crc16(&spd[117], 11);
+ return ddr3_crc16(&spd[117], 11);
}
/**
diff --git a/src/include/device/dram/common.h b/src/include/device/dram/common.h
index 47023704fe..31cdb2bb5b 100644
--- a/src/include/device/dram/common.h
+++ b/src/include/device/dram/common.h
@@ -67,4 +67,6 @@ enum spd_status {
SPD_STATUS_INVALID_FIELD,
};
+u16 ddr3_crc16(const u8 *ptr, int n_crc);
+
#endif /* DEVICE_DRAM_COMMON_H */
diff --git a/src/include/device/dram/ddr2.h b/src/include/device/dram/ddr2.h
index 4aad1bcd8f..9bbbfe9652 100644
--- a/src/include/device/dram/ddr2.h
+++ b/src/include/device/dram/ddr2.h
@@ -179,5 +179,6 @@ int spd_decode_ddr2(struct dimm_attr_ddr2_st *dimm, u8 spd[SPD_SIZE_MAX_DDR2]);
void dram_print_spd_ddr2(const struct dimm_attr_ddr2_st *dimm);
void normalize_tck(u32 *tclk);
u8 spd_get_msbs(u8 c);
+u16 spd_ddr2_calc_unique_crc(const u8 *spd, int len);
#endif /* DEVICE_DRAM_DDR2L_H */