Matt DeVillier has uploaded a new change for review. ( https://review.coreboot.org/19958 )
Change subject: haswell: add CBMEM_MEMINFO table when initing RAM ......................................................................
haswell: add CBMEM_MEMINFO table when initing RAM
Populate a memory_info struct with PEI and SPD data, in order to inject the CBMEM_INFO table necessary to populate a type17 SMBIOS table.
On Broadwell, this is done by the MRC binary, but the older Haswell MRC binary doesn't populate the pei_data struct with all the info needed, so we have to pull it from the SPD.
Some values are hardcoded based on platform specifications.
Change-Id: Iea837d23f2c9c1c943e0db28cf81b265f054e9d1 Signed-off-by: Matt DeVillier matt.devillier@gmail.com --- M src/cpu/intel/haswell/romstage.c M src/northbridge/intel/haswell/raminit.c M src/northbridge/intel/haswell/raminit.h 3 files changed, 53 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/58/19958/1
diff --git a/src/cpu/intel/haswell/romstage.c b/src/cpu/intel/haswell/romstage.c index c6765c7..ac45ee6 100644 --- a/src/cpu/intel/haswell/romstage.c +++ b/src/cpu/intel/haswell/romstage.c @@ -245,6 +245,8 @@ #endif }
+ setup_sdram_meminfo(params->pei_data); + romstage_handoff_init(wake_from_s3);
post_code(0x3f); diff --git a/src/northbridge/intel/haswell/raminit.c b/src/northbridge/intel/haswell/raminit.c index 469c4f2..5e38b59 100644 --- a/src/northbridge/intel/haswell/raminit.c +++ b/src/northbridge/intel/haswell/raminit.c @@ -21,6 +21,7 @@ #include <cbfs.h> #include <halt.h> #include <ip_checksum.h> +#include <memory_info.h> #include <northbridge/intel/common/mrc_cache.h> #include <pc80/mc146818rtc.h> #include <device/pci_def.h> @@ -171,3 +172,52 @@
report_memory_config(); } + +void setup_sdram_meminfo(struct pei_data *pei_data) +{ + u32 addr_decoder_common, addr_decode_ch[2]; + struct memory_info* mem_info; + struct dimm_info *dimm; + int ddr_frequency; + int dimm_size; + int i; + int dimm_cnt = 0; + + mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(struct memory_info)); + memset(mem_info, 0, sizeof(struct memory_info)); + + addr_decoder_common = MCHBAR32(0x5000); + addr_decode_ch[0] = MCHBAR32(0x5004); + addr_decode_ch[1] = MCHBAR32(0x5008); + + ddr_frequency = (MCHBAR32(0x5e04) * 13333 * 2 + 50)/100; + + for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) { + u32 ch_conf = addr_decode_ch[i]; + dimm_size = ((ch_conf >> 0) & 0xff) * 256; + + if (dimm_size) { + dimm_cnt++; + dimm = &mem_info->dimm[i]; + dimm->dimm_size = dimm_size; + dimm->ddr_type = 3; // DRAM + dimm->ddr_frequency = ddr_frequency; + dimm->rank_per_dimm = 1; + dimm->channel_num = i; + dimm->dimm_num = 0; + dimm->bank_locator = i * 2; + memcpy(dimm->serial, // bytes 122-125 in SPD + &pei_data->spd_data[i][122], // same for all modules so use first + sizeof(uint8_t) * 4); // since known good + memcpy(dimm->module_part_number, // bytes 128-145 in SPD + &pei_data->spd_data[0][128], // same for all modules so use first + sizeof(uint8_t) * 18); // since known good + dimm->mod_id = + (pei_data->spd_data[0][118] << 8) | // bytes 117/118 (LSB/MSB) + (pei_data->spd_data[0][117] & 0xFF); + dimm->mod_type = 3; //SPD_SODIMM + dimm->bus_width = 0x3; //64-bit + } + } + mem_info->dimm_cnt = dimm_cnt; +} diff --git a/src/northbridge/intel/haswell/raminit.h b/src/northbridge/intel/haswell/raminit.h index d02b72d..b42fcf8 100644 --- a/src/northbridge/intel/haswell/raminit.h +++ b/src/northbridge/intel/haswell/raminit.h @@ -19,6 +19,7 @@ #include "pei_data.h"
void sdram_initialize(struct pei_data *pei_data); +void setup_sdram_meminfo(struct pei_data *pei_data); int fixup_haswell_errata(void); /* save_mrc_data() must be called after cbmem has been initialized. */ void save_mrc_data(struct pei_data *pei_data);