diff options
author | Patrick Rudolph <patrick.rudolph@9elements.com> | 2020-05-01 18:31:48 +0200 |
---|---|---|
committer | Patrick Rudolph <siro@das-labor.org> | 2020-08-11 05:14:01 +0000 |
commit | d0581315869331c4e934368cbb535692b486ebbc (patch) | |
tree | 5ca9b74dc9b64d22e5f1b6e4672d24c2e225956f | |
parent | 173493784dd07ac1cbf055a0b26c55f9bd1f5a28 (diff) |
nb/intel/sandybridge/raminit: Add ECC debug code
* Add ECC test code when DEBUG_RAM_SETUP is enabled
* Move ECC scrubbing after set_scrambling_seed() to be able to observe
what has been cleared in the test routine. If clearing happens
before set_scrambling_seed the data is XORed with a different PRN.
Data read from memory will look random instead of all zeros.
* ECC scrubbing must happen after dram_dimm_set_mapping()
The ECC logic is set to "normal mode" in dram_dimm_set_mapping(). In
normal mode the ECC bits are calculated and stored on write
transactions.
* Move method out of try_init_dram_ddr3().
This satisfies point 2 and point 3 of the list above.
Change-Id: I76174ec962c9b0bb72852897586eb95d896d301e
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/40946
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
-rw-r--r-- | src/northbridge/intel/sandybridge/raminit.c | 31 | ||||
-rw-r--r-- | src/northbridge/intel/sandybridge/raminit_native.c | 3 |
2 files changed, 31 insertions, 3 deletions
diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c index 2728037ac9..06b4d1ec45 100644 --- a/src/northbridge/intel/sandybridge/raminit.c +++ b/src/northbridge/intel/sandybridge/raminit.c @@ -416,10 +416,41 @@ static void init_dram_ddr3(int s3resume, const u32 cpuid) set_scrambling_seed(&ctrl); + if (!s3resume && ctrl.ecc_enabled) + channel_scrub(&ctrl); + set_normal_operation(&ctrl); final_registers(&ctrl); + /* can't do this earlier because it needs to be done in normal operation */ + if (CONFIG(DEBUG_RAM_SETUP) && !s3resume && ctrl.ecc_enabled) { + uint32_t i, tseg = pci_read_config32(HOST_BRIDGE, TSEGMB); + + printk(BIOS_INFO, "RAMINIT: ECC scrub test on first channel up to 0x%x\n", + tseg); + + /* + * This test helps to debug the ECC scrubbing. + * It likely tests every channel/rank, as rank interleave and enhanced + * interleave are enabled, but there's no guarantee for it. + */ + + /* Skip first MB to avoid special case for A-seg and test up to TSEG */ + for (i = 1; i < tseg >> 20; i++) { + for (int j = 0; j < 1 * MiB; j += 4096) { + uintptr_t addr = i * MiB + j; + if (read32((u32 *)addr) == 0) + continue; + + printk(BIOS_ERR, "RAMINIT: ECC scrub: DRAM not cleared at" + " addr 0x%lx\n", addr); + break; + } + } + printk(BIOS_INFO, "RAMINIT: ECC scrub test done.\n"); + } + /* Zone config */ dram_zones(&ctrl, 0); diff --git a/src/northbridge/intel/sandybridge/raminit_native.c b/src/northbridge/intel/sandybridge/raminit_native.c index 62715a1c23..c23a5acff0 100644 --- a/src/northbridge/intel/sandybridge/raminit_native.c +++ b/src/northbridge/intel/sandybridge/raminit_native.c @@ -687,9 +687,6 @@ int try_init_dram_ddr3(ramctr_timing *ctrl, int fast_boot, int s3resume, int me_ err = channel_test(ctrl); if (err) return err; - - if (ctrl->ecc_enabled) - channel_scrub(ctrl); } /* Set MAD-DIMM registers */ |