Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/43971 )
Change subject: nb/intel/*: Fill in SMBIOS type 16 on SND/HSW ......................................................................
nb/intel/*: Fill in SMBIOS type 16 on SND/HSW
Fill in the maximum DRAM capacity and slot count read from CAPID_A registers on Sandy Bridge and Haswell.
While the register isn't part of the Core Series datasheet, it can be found in the corresponding "Intel Open Source Graphics Programmer's Reference" datasheets.
Change-Id: I6e2346de1ffe52e8685276acbdbf25755f4cc162 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/northbridge/intel/haswell/hostbridge_regs.h M src/northbridge/intel/haswell/raminit.c M src/northbridge/intel/sandybridge/hostbridge_regs.h M src/northbridge/intel/sandybridge/raminit.c 4 files changed, 64 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/71/43971/1
diff --git a/src/northbridge/intel/haswell/hostbridge_regs.h b/src/northbridge/intel/haswell/hostbridge_regs.h index f5fa54a..70e15b7 100644 --- a/src/northbridge/intel/haswell/hostbridge_regs.h +++ b/src/northbridge/intel/haswell/hostbridge_regs.h @@ -60,7 +60,11 @@ #define SKPAD 0xdc /* Scratchpad Data */
#define CAPID0_A 0xe4 +#define CAPID_ECCDIS (1 << 25) #define VTD_DISABLE (1 << 23) +#define CAPID_DDPCD (1 << 14) +#define CAPID_PDCD (1 << 12) +#define CAPID_DDRSZ(x) (((x) >> 19) & 0x3)
#define CAPID0_B 0xe8
diff --git a/src/northbridge/intel/haswell/raminit.c b/src/northbridge/intel/haswell/raminit.c index 5d67954..9b192d6 100644 --- a/src/northbridge/intel/haswell/raminit.c +++ b/src/northbridge/intel/haswell/raminit.c @@ -170,6 +170,20 @@ report_memory_config(); }
+static uint32_t soc_systemagent_max_chan_capacity_mib(u8 capid0_a_ddrsz) +{ + switch (capid0_a_ddrsz) { + case 1: + return 8192; + case 2: + return 2048; + case 3: + return 512; + default: + return 16384; + } +} + void setup_sdram_meminfo(struct pei_data *pei_data) { u32 addr_decode_ch[2]; @@ -221,4 +235,12 @@ } } mem_info->dimm_cnt = dimm_cnt; + const uint32_t capida = pci_read_config32(HOST_BRIDGE, CAPID0_A); + const u8 ddrsz = CAPID_DDRSZ(capida); + + mem_info->ecc_capable = !(capida & CAPID_ECCDIS); + mem_info->max_capacity_mib = soc_systemagent_max_chan_capacity_mib(ddrsz) * + (!(capida & CAPID_PDCD) + 1); + mem_info->number_of_devices = (!(capida & CAPID_DDPCD) + 1) * + (!(capida & CAPID_PDCD) + 1); } diff --git a/src/northbridge/intel/sandybridge/hostbridge_regs.h b/src/northbridge/intel/sandybridge/hostbridge_regs.h index 00d37d4..2d2fcff 100644 --- a/src/northbridge/intel/sandybridge/hostbridge_regs.h +++ b/src/northbridge/intel/sandybridge/hostbridge_regs.h @@ -49,6 +49,11 @@ #define TOLUD 0xbc /* Top of Low Used Memory */
#define CAPID0_A 0xe4 /* Capabilities Register A */ +#define CAPID_ECCDIS (1 << 25) +#define CAPID_DDPCD (1 << 14) +#define CAPID_PDCD (1 << 12) +#define CAPID_DDRSZ(x) (((x) >> 19) & 0x3) + #define CAPID0_B 0xe8 /* Capabilities Register B */
#define SKPAD 0xdc /* Scratchpad Data */ diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c index 422067b..64571dc 100644 --- a/src/northbridge/intel/sandybridge/raminit.c +++ b/src/northbridge/intel/sandybridge/raminit.c @@ -54,6 +54,36 @@ memset(&ctrl->info.dimm[channel][0], 0, sizeof(ctrl->info.dimm[0])); }
+static uint32_t soc_systemagent_max_chan_capacity_mib(u8 capid0_a_ddrsz) +{ + switch (capid0_a_ddrsz) { + case 1: + return 8192; + case 2: + return 2048; + case 3: + return 512; + default: + return 16384; + } +} + +/* Fill cbmem with information for SMBIOS type 16 */ +static void fill_smbios16(void) +{ + struct memory_info *m = cbmem_find(CBMEM_ID_MEMINFO); + if (m == NULL) + return; + + const uint32_t capida = pci_read_config32(HOST_BRIDGE, CAPID0_A); + + m->ecc_capable = !(capida & CAPID_ECCDIS); + m->max_capacity_mib = soc_systemagent_max_chan_capacity_mib(CAPID_DDRSZ(capida)) * + (!(capida & CAPID_PDCD) + 1); + m->number_of_devices = (!(capida & CAPID_DDPCD) + 1) * + (!(capida & CAPID_PDCD) + 1); +} + /* Fill cbmem with information for SMBIOS type 17 */ static void fill_smbios17(ramctr_timing *ctrl) { @@ -385,8 +415,10 @@ system_reset(); }
- if (!s3resume) + if (!s3resume) { + fill_smbios16(); fill_smbios17(&ctrl); + } }
void perform_raminit(int s3resume)