nb/amd/mct_ddr3: Cache whether ECC is allowed at the platform level

Certain AMD platforms, such as those using the SP5100 southbridge,
contain a very poorly documented bug related to LPC ROM access,
which is triggered by repeated (hundreds or more) rapid calls to
get_option().  This bug manifests as a complete system deadlock
in ramstage device configuration, requiring standby power to be
removed from the system to release the deadlock.

Cache the platform ECC status to avoid repeated calls to get_option()
in the lane count detection logic.

Change-Id: I8b48c523218ccc8c113319957d6eca2d15e1070f
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
Reviewed-on: https://review.coreboot.org/14273
Tested-by: build bot (Jenkins)
Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
Timothy Pearson 2016-04-06 16:10:38 -05:00
parent 3503b3f730
commit c5c3d76127
2 changed files with 9 additions and 3 deletions

View File

@ -336,9 +336,8 @@ uint8_t is_ecc_enabled(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTs
{ {
uint8_t ecc_enabled = 1; uint8_t ecc_enabled = 1;
if (!mctGet_NVbits(NV_ECC_CAP) || !mctGet_NVbits(NV_ECC)) { if (!pMCTstat->try_ecc)
return 0; ecc_enabled = 0;
}
if (pDCTstat->NodePresent && pDCTstat->DIMMValid) { if (pDCTstat->NodePresent && pDCTstat->DIMMValid) {
if (!(pDCTstat->Status & (1 << SB_ECCDIMMs))) { if (!(pDCTstat->Status & (1 << SB_ECCDIMMs))) {
@ -2659,6 +2658,12 @@ static void mctAutoInitMCT_D(struct MCTStatStruc *pMCTstat,
uint8_t s3resume = acpi_is_wakeup_s3(); uint8_t s3resume = acpi_is_wakeup_s3();
restartinit: restartinit:
if (!mctGet_NVbits(NV_ECC_CAP) || !mctGet_NVbits(NV_ECC))
pMCTstat->try_ecc = 0;
else
pMCTstat->try_ecc = 1;
mctInitMemGPIOs_A_D(); /* Set any required GPIOs*/ mctInitMemGPIOs_A_D(); /* Set any required GPIOs*/
if (s3resume) { if (s3resume) {
printk(BIOS_DEBUG, "mctAutoInitMCT_D: mct_ForceNBPState0_En_Fam15\n"); printk(BIOS_DEBUG, "mctAutoInitMCT_D: mct_ForceNBPState0_En_Fam15\n");

View File

@ -300,6 +300,7 @@ struct MCTStatStruc {
u32 SysLimit; /* LIMIT[39:8] (system address)*/ u32 SysLimit; /* LIMIT[39:8] (system address)*/
uint32_t TSCFreq; uint32_t TSCFreq;
uint16_t nvram_checksum; uint16_t nvram_checksum;
uint8_t try_ecc;
} __attribute__((packed)); } __attribute__((packed));
/*============================================================================= /*=============================================================================