src/northbridge/amd/amdmct: Add option to override bad SPD checksum

Certain DIMMs, for example DIMMs on which the EEPROM has been modified
by the end user, may not contain a valid SPD checksum.  While this is
not a normal condition, it may be useful to allow a checksum override
while memory timing parameters are being altered, e.g. in the course
of overclocking or underclocking, or when recovering from a bad SPD
write.

This is an advanced level feature primarily useful for debugging
and development.

Change-Id: Ia743a13348d0a6e5e4dfffa04ed9582e0f7f3dad
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
Reviewed-on: http://review.coreboot.org/11987
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
This commit is contained in:
Timothy Pearson 2015-06-11 16:14:15 -05:00 committed by Martin Roth
parent 861f920cdf
commit f3b9fd3265
2 changed files with 11 additions and 2 deletions

View File

@ -1456,7 +1456,7 @@ restartinit:
} }
} }
if (NodesWmem == 0) { if (NodesWmem == 0) {
printk(BIOS_DEBUG, "No Nodes?!\n"); printk(BIOS_ALERT, "Unable to detect valid memory on any nodes. Halting!\n");
goto fatalexit; goto fatalexit;
} }
@ -3892,13 +3892,14 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat,
read_spd_bytes(pMCTstat, pDCTstat, i); read_spd_bytes(pMCTstat, pDCTstat, i);
crc_status = crcCheck(pDCTstat, i); crc_status = crcCheck(pDCTstat, i);
} }
if (crc_status) { /* CRC is OK */ if ((crc_status) || (SPDCtrl == 2)) { /* CRC is OK */
byte = pDCTstat->spd_data.spd_bytes[i][SPD_TYPE]; byte = pDCTstat->spd_data.spd_bytes[i][SPD_TYPE];
if (byte == JED_DDR3SDRAM) { if (byte == JED_DDR3SDRAM) {
/*Dimm is 'Present'*/ /*Dimm is 'Present'*/
pDCTstat->DIMMValid |= 1 << i; pDCTstat->DIMMValid |= 1 << i;
} }
} else { } else {
printk(BIOS_WARNING, "Node %d DIMM %d: SPD checksum invalid\n", pDCTstat->Node_ID, i);
pDCTstat->DIMMSPDCSE = 1 << i; pDCTstat->DIMMSPDCSE = 1 << i;
if (SPDCtrl == 0) { if (SPDCtrl == 0) {
pDCTstat->ErrStatus |= 1 << SB_DIMMChkSum; pDCTstat->ErrStatus |= 1 << SB_DIMMChkSum;

View File

@ -146,6 +146,14 @@ static u16 mctGet_NVbits(u8 index)
case NV_SPDCHK_RESTRT: case NV_SPDCHK_RESTRT:
val = 0; /* Exit current node initialization if any DIMM has SPD checksum error */ val = 0; /* Exit current node initialization if any DIMM has SPD checksum error */
//val = 1; /* Ignore faulty SPD checksum (DIMM will still be disabled), continue current node intialization */ //val = 1; /* Ignore faulty SPD checksum (DIMM will still be disabled), continue current node intialization */
//val = 2; /* Override faulty SPD checksum (DIMM will be enabled), continue current node intialization */
if (get_option(&nvram, "dimm_spd_checksum") == CB_SUCCESS)
val = nvram & 0x3;
if (val > 2)
val = 2;
break; break;
case NV_DQSTrainCTL: case NV_DQSTrainCTL:
//val = 0; /*Skip dqs training */ //val = 0; /*Skip dqs training */