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@gmail.com> Reviewed-on: http://review.coreboot.org/4537 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
parent
d7813436b3
commit
4c37e58ea5
|
@ -48,6 +48,46 @@ int dimm_is_registered(enum spd_dimm_type type)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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
|
* \brief Decode the raw SPD data
|
||||||
*
|
*
|
||||||
|
@ -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 spd_decode_ddr3(dimm_attr * dimm, spd_raw_data spd)
|
||||||
{
|
{
|
||||||
int nCRC, i, ret;
|
int ret;
|
||||||
u16 crc, spd_crc;
|
u16 crc, spd_crc;
|
||||||
u8 *ptr = spd;
|
|
||||||
u8 ftb_divisor, ftb_dividend, capacity_shift, bus_width, sdram_width;
|
u8 ftb_divisor, ftb_dividend, capacity_shift, bus_width, sdram_width;
|
||||||
u8 reg8;
|
u8 reg8;
|
||||||
u32 mtb; /* medium time base */
|
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;
|
dimm->dram_type = SPD_MEMORY_TYPE_SDRAM_DDR3;
|
||||||
|
|
||||||
/* Find the number of bytes covered by CRC */
|
crc = spd_ddr3_calc_crc(spd, sizeof(spd));
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Compare with the CRC in the SPD */
|
/* Compare with the CRC in the SPD */
|
||||||
spd_crc = (spd[127] << 8) + spd[126];
|
spd_crc = (spd[127] << 8) + spd[126];
|
||||||
/* Verify the CRC is correct */
|
/* Verify the CRC is correct */
|
||||||
|
|
|
@ -170,6 +170,7 @@ enum spd_status {
|
||||||
|
|
||||||
typedef u8 spd_raw_data[256];
|
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 spd_decode_ddr3(dimm_attr * dimm, spd_raw_data spd_data);
|
||||||
int dimm_is_registered(enum spd_dimm_type type);
|
int dimm_is_registered(enum spd_dimm_type type);
|
||||||
void dram_print_spd_ddr3(const dimm_attr * dimm);
|
void dram_print_spd_ddr3(const dimm_attr * dimm);
|
||||||
|
|
Loading…
Reference in New Issue