[coreboot-gerrit] Patch set updated for coreboot: nb/intel/sandybridge/raminit: always use mrccache
Patrick Rudolph (siro@das-labor.org)
gerrit at coreboot.org
Sun Mar 13 12:54:45 CET 2016
Patrick Rudolph (siro at das-labor.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14082
-gerrit
commit c2e0c74e3d86566ae8ba6ca7c0a2d08d087c007f
Author: Patrick Rudolph <siro at das-labor.org>
Date: Sun Mar 13 11:07:45 2016 +0100
nb/intel/sandybridge/raminit: always use mrccache
Always use MRC cache if possible.
Added a CRC array to make sure the DIMMs haven't been replaced.
In case one of the CRCs doesn't match, start RAM training.
Should speed up boot time.
Test system:
* Gigabyte GA-B75M-D3H
* Intel Pentium CPU G2130
Test result:
Doesn't work ! Needs to find out why MRC cache is always empty.
Change-Id: I974c5bce70692a706410180c2a512eb071364be0
Signed-off-by: Patrick Rudolph <siro at das-labor.org>
---
src/northbridge/intel/sandybridge/raminit.c | 71 ++++++++++++++++++++---------
1 file changed, 50 insertions(+), 21 deletions(-)
diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c
index 0b27fe5..39f6f88 100644
--- a/src/northbridge/intel/sandybridge/raminit.c
+++ b/src/northbridge/intel/sandybridge/raminit.c
@@ -135,6 +135,7 @@ struct ram_rank_timings {
struct ramctr_timing_st;
typedef struct ramctr_timing_st {
+ u16 spd_crc[NUM_CHANNELS][NUM_SLOTS];
int mobile;
u16 cas_supported;
@@ -377,6 +378,7 @@ static void dram_find_spds_ddr3(spd_raw_data * spd, dimm_info * dimm,
dram_print_spd_ddr3(&dimm->dimm[channel][slot]);
dimms++;
+ ctrl->spd_crc[channel][slot] = spd_ddr3_calc_crc(spd[spd_slot], sizeof(spd_raw_data));
ctrl->rank_mirror[channel][slot * 2] = 0;
ctrl->rank_mirror[channel][slot * 2 + 1] = dimm->dimm[channel][slot].flags.pins_mirrored;
ctrl->channel_size_mb[channel] += dimm->dimm[channel][slot].size_mb;
@@ -3943,6 +3945,10 @@ void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck,
{
int me_uma_size;
int cbmem_was_inited;
+ int fast_boot;
+ ramctr_timing ctrl;
+ struct mrc_data_container *mrc_cache;
+ ramctr_timing *ctrl_cached;
dimm_info info;
MCHBAR32(0x5f00) |= 1;
@@ -3971,32 +3977,54 @@ void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck,
halt();
}
- ramctr_timing ctrl;
-
memset(&ctrl, 0, sizeof (ctrl));
early_pch_init_native();
early_thermal_init();
- ctrl.mobile = mobile;
- ctrl.tCK = min_tck;
-
- /* FIXME: for non-S3 we should be able to use timing caching with
- proper verification. Right now we use timings only for S3 case.
- */
- if (s3resume) {
- struct mrc_data_container *mrc_cache;
-
- mrc_cache = find_current_mrc_cache();
- if (!mrc_cache || mrc_cache->mrc_data_size < sizeof (ctrl)) {
+ /* try to find timings in MRC cache */
+ mrc_cache = find_current_mrc_cache();
+ if (!mrc_cache || mrc_cache->mrc_data_size < sizeof (ctrl)) {
+ if (s3resume) {
/* Failed S3 resume, reset to come up cleanly */
outb(0x6, 0xcf9);
halt();
}
- memcpy(&ctrl, mrc_cache->mrc_data, sizeof (ctrl));
+ ctrl_cached = NULL;
+ } else {
+ ctrl_cached = (ramctr_timing *)mrc_cache->mrc_data;
+ }
+
+ /* verify MRC cache for fast boot */
+ if (ctrl_cached) {
+ fast_boot = 1;
+
+ /* check SPD CRC16 to make sure the DIMMs haven't been replaced */
+ fast_boot &= ctrl_cached->spd_crc[0][0] ==
+ spd_ddr3_calc_crc(spds[0], sizeof(spd_raw_data));
+
+ fast_boot &= ctrl_cached->spd_crc[0][1] ==
+ spd_ddr3_calc_crc(spds[1], sizeof(spd_raw_data));
+
+ fast_boot &= ctrl_cached->spd_crc[1][0] ==
+ spd_ddr3_calc_crc(spds[2], sizeof(spd_raw_data));
+
+ fast_boot &= ctrl_cached->spd_crc[1][1] ==
+ spd_ddr3_calc_crc(spds[3], sizeof(spd_raw_data));
+ } else {
+ fast_boot = 0;
}
- if (!s3resume) {
+
+ if (fast_boot) {
+ memcpy(&ctrl, ctrl_cached, sizeof (ctrl));
+ printk(BIOS_DEBUG, "Using stored timings. Skipping RAM training.\n");
+ } else {
+ ctrl.mobile = mobile;
+ ctrl.tCK = min_tck;
+
+ printk(BIOS_DEBUG, "No valid stored timings found. Starting RAM training.\n");
+
/* Get DDR3 SPD data */
dram_find_spds_ddr3(spds, &info, &ctrl);
@@ -4009,7 +4037,7 @@ void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck,
/* Set MCU frequency */
dram_freq(&ctrl);
- if (!s3resume) {
+ if (!fast_boot) {
/* Calculate timings */
dram_timing(&ctrl);
}
@@ -4052,7 +4080,7 @@ void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck,
udelay(1);
- if (s3resume) {
+ if (fast_boot) {
restore_timings(&ctrl);
} else {
/* Do jedec ddr3 reset sequence */
@@ -4090,7 +4118,7 @@ void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck,
write_controller_mr(&ctrl);
- if (!s3resume) {
+ if (!fast_boot) {
channel_test(&ctrl);
}
@@ -4106,7 +4134,7 @@ void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck,
/* Zone config */
dram_zones(&ctrl, 0);
- if (!s3resume)
+ if (!fast_boot)
quick_ram_check();
intel_early_me_status();
@@ -4116,7 +4144,7 @@ void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck,
report_memory_config();
cbmem_was_inited = !cbmem_recovery(s3resume);
- if (!s3resume)
+ if (!fast_boot)
save_timings(&ctrl);
if (s3resume && !cbmem_was_inited) {
/* Failed S3 resume, reset to come up cleanly */
@@ -4124,7 +4152,8 @@ void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck,
halt();
}
- fill_smbios17(&info, (1000 << 8) / ctrl.tCK);
+ if (!fast_boot)
+ fill_smbios17(&info, (1000 << 8) / ctrl.tCK);
}
#define HOST_BRIDGE PCI_DEVFN(0, 0)
More information about the coreboot-gerrit
mailing list