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>
This commit is contained in:
Arthur Heymans 2018-01-22 01:26:53 +01:00 committed by Patrick Georgi
parent f7dc972fde
commit 97b337b252
4 changed files with 30 additions and 3 deletions

View File

@ -71,6 +71,30 @@ u8 spd_ddr2_calc_checksum(u8 *spd, int len)
return c; return c;
} }
/**
* \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. * \brief Return size of SPD.
* *

View File

@ -46,7 +46,7 @@ int spd_dimm_is_registered_ddr3(enum spd_dimm_type type)
return 0; return 0;
} }
static u16 crc16(const u8 *ptr, int n_crc) u16 ddr3_crc16(const u8 *ptr, int n_crc)
{ {
int i; int i;
u16 crc = 0; u16 crc = 0;
@ -87,7 +87,7 @@ u16 spd_ddr3_calc_crc(u8 *spd, int len)
/* Not enough bytes available to get the CRC */ /* Not enough bytes available to get the CRC */
return 0; 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 */ /* Not enough bytes available to get the CRC */
return 0; return 0;
return crc16(&spd[117], 11); return ddr3_crc16(&spd[117], 11);
} }
/** /**

View File

@ -67,4 +67,6 @@ enum spd_status {
SPD_STATUS_INVALID_FIELD, SPD_STATUS_INVALID_FIELD,
}; };
u16 ddr3_crc16(const u8 *ptr, int n_crc);
#endif /* DEVICE_DRAM_COMMON_H */ #endif /* DEVICE_DRAM_COMMON_H */

View File

@ -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 dram_print_spd_ddr2(const struct dimm_attr_ddr2_st *dimm);
void normalize_tck(u32 *tclk); void normalize_tck(u32 *tclk);
u8 spd_get_msbs(u8 c); u8 spd_get_msbs(u8 c);
u16 spd_ddr2_calc_unique_crc(const u8 *spd, int len);
#endif /* DEVICE_DRAM_DDR2L_H */ #endif /* DEVICE_DRAM_DDR2L_H */