123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- /*
- * Copyright 2008-2014 Freescale Semiconductor, Inc.
- *
- * SPDX-License-Identifier: GPL-2.0
- */
- #include <common.h>
- #include <ddr_spd.h>
- /* used for ddr1 and ddr2 spd */
- static int
- spd_check(const u8 *buf, u8 spd_rev, u8 spd_cksum)
- {
- unsigned int cksum = 0;
- unsigned int i;
- /*
- * Check SPD revision supported
- * Rev 1.X or less supported by this code
- */
- if (spd_rev >= 0x20) {
- printf("SPD revision %02X not supported by this code\n",
- spd_rev);
- return 1;
- }
- if (spd_rev > 0x13) {
- printf("SPD revision %02X not verified by this code\n",
- spd_rev);
- }
- /*
- * Calculate checksum
- */
- for (i = 0; i < 63; i++) {
- cksum += *buf++;
- }
- cksum &= 0xFF;
- if (cksum != spd_cksum) {
- printf("SPD checksum unexpected. "
- "Checksum in SPD = %02X, computed SPD = %02X\n",
- spd_cksum, cksum);
- return 1;
- }
- return 0;
- }
- unsigned int
- ddr1_spd_check(const ddr1_spd_eeprom_t *spd)
- {
- const u8 *p = (const u8 *)spd;
- return spd_check(p, spd->spd_rev, spd->cksum);
- }
- unsigned int
- ddr2_spd_check(const ddr2_spd_eeprom_t *spd)
- {
- const u8 *p = (const u8 *)spd;
- return spd_check(p, spd->spd_rev, spd->cksum);
- }
- /*
- * CRC16 compute for DDR3 SPD
- * Copied from DDR3 SPD spec.
- */
- static int
- crc16(char *ptr, int count)
- {
- int crc, i;
- crc = 0;
- while (--count >= 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 & 0xffff;
- }
- unsigned int
- ddr3_spd_check(const ddr3_spd_eeprom_t *spd)
- {
- char *p = (char *)spd;
- int csum16;
- int len;
- char crc_lsb; /* byte 126 */
- char crc_msb; /* byte 127 */
- /*
- * SPD byte0[7] - CRC coverage
- * 0 = CRC covers bytes 0~125
- * 1 = CRC covers bytes 0~116
- */
- len = !(spd->info_size_crc & 0x80) ? 126 : 117;
- csum16 = crc16(p, len);
- crc_lsb = (char) (csum16 & 0xff);
- crc_msb = (char) (csum16 >> 8);
- if (spd->crc[0] == crc_lsb && spd->crc[1] == crc_msb) {
- return 0;
- } else {
- printf("SPD checksum unexpected.\n"
- "Checksum lsb in SPD = %02X, computed SPD = %02X\n"
- "Checksum msb in SPD = %02X, computed SPD = %02X\n",
- spd->crc[0], crc_lsb, spd->crc[1], crc_msb);
- return 1;
- }
- }
- unsigned int ddr4_spd_check(const struct ddr4_spd_eeprom_s *spd)
- {
- char *p = (char *)spd;
- int csum16;
- int len;
- char crc_lsb; /* byte 126 */
- char crc_msb; /* byte 127 */
- len = 126;
- csum16 = crc16(p, len);
- crc_lsb = (char) (csum16 & 0xff);
- crc_msb = (char) (csum16 >> 8);
- if (spd->crc[0] != crc_lsb || spd->crc[1] != crc_msb) {
- printf("SPD checksum unexpected.\n"
- "Checksum lsb in SPD = %02X, computed SPD = %02X\n"
- "Checksum msb in SPD = %02X, computed SPD = %02X\n",
- spd->crc[0], crc_lsb, spd->crc[1], crc_msb);
- return 1;
- }
- p = (char *)((ulong)spd + 128);
- len = 126;
- csum16 = crc16(p, len);
- crc_lsb = (char) (csum16 & 0xff);
- crc_msb = (char) (csum16 >> 8);
- if (spd->mod_section.uc[126] != crc_lsb ||
- spd->mod_section.uc[127] != crc_msb) {
- printf("SPD checksum unexpected.\n"
- "Checksum lsb in SPD = %02X, computed SPD = %02X\n"
- "Checksum msb in SPD = %02X, computed SPD = %02X\n",
- spd->mod_section.uc[126],
- crc_lsb, spd->mod_section.uc[127],
- crc_msb);
- return 1;
- }
- return 0;
- }
|