Patrick Rudolph (siro@das-labor.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13852
-gerrit
commit 1b23f80902ae38ae9b597d582750b5a927bffbfc Author: Patrick Rudolph siro@das-labor.org Date: Sun Feb 28 15:24:04 2016 +0100
nb/intel/sandybridge/raminit: Fill SMBIOS type17 info
Fill minimal info required for SMBIOS type 17. Report DIMM size, channel, rank and DDR speed. Allows dmidecode to print the current RAM configuration.
Move report_memory_config() to make sure cbmem is initialized to prevent system hang.
Test system: * Gigabyte GA-B75M-D3H * Intel Pentium CPU G2130 * Linux 4.3 * dmidecode 3.0
Change-Id: I4e5f772d68484b9cb178ca8a1d63ad99839f3993 Signed-off-by: Patrick Rudolph siro@das-labor.org --- src/northbridge/intel/sandybridge/raminit.c | 60 ++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 9 deletions(-)
diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c index 40089e2..eb21933 100644 --- a/src/northbridge/intel/sandybridge/raminit.c +++ b/src/northbridge/intel/sandybridge/raminit.c @@ -27,6 +27,8 @@ #include <timestamp.h> #include <pc80/mc146818rtc.h> #include <device/pci_def.h> +#include <memory_info.h> +#include <smbios.h> #include "raminit_native.h" #include "sandybridge.h" #include <delay.h> @@ -239,22 +241,36 @@ static void toggle_io_reset(void) { static void report_memory_config(void) { u32 addr_decoder_common, addr_decode_ch[NUM_CHANNELS]; - int i; + struct memory_info *mem_info; + int channel; + uint16_t ddr_freq; + struct dimm_info *dimm;
addr_decoder_common = MCHBAR32(0x5000); addr_decode_ch[0] = MCHBAR32(0x5004); addr_decode_ch[1] = MCHBAR32(0x5008);
- printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n", - (MCHBAR32(0x5e04) * 13333 * 2 + 50) / 100); + /* + * Allocate CBMEM area for DIMM information used to populate SMBIOS + * table 17 + */ + mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info)); + printk(BIOS_DEBUG, "CBMEM entry for DIMM info: 0x%p\n", mem_info); + if (mem_info) + memset(mem_info, 0, sizeof(*mem_info)); + + ddr_freq = (MCHBAR32(0x5e04) * 13333 * 2 + 50) / 100; + + printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n", ddr_freq); printk(BIOS_DEBUG, "memcfg channel assignment: A: %d, B % d, C % d\n", addr_decoder_common & 3, (addr_decoder_common >> 2) & 3, (addr_decoder_common >> 4) & 3);
- for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) { - u32 ch_conf = addr_decode_ch[i]; - printk(BIOS_DEBUG, "memcfg channel[%d] config (%8.8x):\n", i, - ch_conf); + for (channel = 0; channel < ARRAY_SIZE(addr_decode_ch); channel++) { + u32 ch_conf = addr_decode_ch[channel]; + + printk(BIOS_DEBUG, "memcfg channel[%d] config (%8.8x):\n", + channel, ch_conf); printk(BIOS_DEBUG, " ECC %s\n", ecc_decoder[(ch_conf >> 24) & 3]); printk(BIOS_DEBUG, " enhanced interleave mode %s\n", @@ -271,6 +287,32 @@ static void report_memory_config(void) ((ch_conf >> 20) & 1) ? 16 : 8, ((ch_conf >> 18) & 1) ? "dual" : "single", ((ch_conf >> 16) & 1) ? ", selected" : ""); + + if (!mem_info) + continue; + + if ((ch_conf >> 0) & 0xff) { + dimm = &mem_info->dimm[mem_info->dimm_cnt]; + dimm->ddr_type = MEMORY_TYPE_DDR3; + dimm->ddr_frequency = ddr_freq; + dimm->dimm_size = ((ch_conf >> 0) & 0xff) * 256; + dimm->channel_num = channel; + dimm->rank_per_dimm = ((ch_conf >> 17) & 1) + 1; + dimm->dimm_num = 0; + dimm->bus_width = ((ch_conf >> 19) & 1) ? 16 : 8; + mem_info->dimm_cnt++; + } + if ((ch_conf >> 8) & 0xff) { + dimm = &mem_info->dimm[mem_info->dimm_cnt]; + dimm->ddr_type = MEMORY_TYPE_DDR3; + dimm->ddr_frequency = ddr_freq; + dimm->dimm_size = ((ch_conf >> 8) & 0xff) * 256; + dimm->channel_num = channel; + dimm->rank_per_dimm = ((ch_conf >> 18) & 1) + 1; + dimm->dimm_num = 1; + dimm->bus_width = ((ch_conf >> 20) & 1) ? 16 : 8; + mem_info->dimm_cnt++; + } } }
@@ -4055,8 +4097,6 @@ void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck, intel_early_me_init_done(ME_INIT_STATUS_SUCCESS); intel_early_me_status();
- report_memory_config(); - cbmem_was_inited = !cbmem_recovery(s3resume); if (!s3resume) save_timings(&ctrl); @@ -4065,6 +4105,8 @@ void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck, outb(0x6, 0xcf9); halt(); } + + report_memory_config(); }
#define HOST_BRIDGE PCI_DEVFN(0, 0)