soc/intel/xeon_sp: Share save_dimm_info among Xeon-SP SoCs

TEST=Build and boot on archercity CRB
No changes in boot log and 'dmidecode' result under centos

TEST=Build and boot on avenuecity CRB
It will add DMI type 16,17,19,20

Change-Id: I2f5b7a4ffabed033d54d4724b3c41246503166fe
Signed-off-by: Jincheng Li <jincheng.li@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/83325
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
Jincheng Li 2024-07-01 14:09:37 +08:00 committed by Lean Sheng Tan
parent dc8123a775
commit c19e32e69d
10 changed files with 165 additions and 172 deletions

View File

@ -6,6 +6,7 @@ subdirs-y += ../../../../cpu/intel/turbo
subdirs-y += ../../../../cpu/intel/microcode
romstage-y += romstage.c soc_util.c
romstage-y += ../dimm.c
romstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c
romstage-$(CONFIG_DISPLAY_HOBS) += hob_display.c

View File

@ -22,7 +22,7 @@ void __weak mainboard_memory_init_params(FSPM_UPD *mupd)
/* Default weak implementation */
}
static uint8_t get_error_correction_type(const uint8_t RasModesEnabled)
uint8_t get_error_correction_type(const uint8_t RasModesEnabled)
{
switch (RasModesEnabled) {
case CH_INDEPENDENT:
@ -41,85 +41,6 @@ static uint8_t get_error_correction_type(const uint8_t RasModesEnabled)
}
}
/* Save the DIMM information for SMBIOS table 17 */
void save_dimm_info(void)
{
struct dimm_info *dest_dimm;
struct memory_info *mem_info;
const struct SystemMemoryMapHob *hob;
MEMMAP_DIMM_DEVICE_INFO_STRUCT src_dimm;
int dimm_max, index = 0, num_dimms = 0;
uint32_t vdd_voltage;
hob = get_system_memory_map();
assert(hob);
/*
* Allocate CBMEM area for DIMM information used to populate SMBIOS
* table 17
*/
mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
if (!mem_info) {
printk(BIOS_ERR, "CBMEM entry for DIMM info missing\n");
return;
}
memset(mem_info, 0, sizeof(*mem_info));
/* According to Dear Customer Letter it's 1.12 TB per processor. */
mem_info->max_capacity_mib = 1.12 * MiB * CONFIG_MAX_SOCKET;
mem_info->number_of_devices = CONFIG_DIMM_MAX;
mem_info->ecc_type = get_error_correction_type(hob->RasModesEnabled);
dimm_max = ARRAY_SIZE(mem_info->dimm);
vdd_voltage = get_ddr_voltage(hob->DdrVoltage);
/* For now only implement for one socket and hard-coded for DDR4 */
for (int ch = 0; ch < MAX_CH; ch++) {
for (int dimm = 0; dimm < MAX_IMC; dimm++) {
src_dimm = hob->Socket[0].ChannelInfo[ch].DimmInfo[dimm];
if (src_dimm.Present) {
if (index >= dimm_max) {
printk(BIOS_WARNING, "Too many DIMMs info for %s.\n",
__func__);
return;
}
dest_dimm = &mem_info->dimm[index];
dimm_info_fill(dest_dimm,
src_dimm.DimmSize << 6,
0x1a, /* hard-coded memory device type as DDR4 */
hob->memFreq, /* replaced by configured_speed_mts */
src_dimm.NumRanks,
ch, /* for mainboard locator string override */
dimm, /* for mainboard locator string override */
(const char *)&src_dimm.PartNumber[0],
sizeof(src_dimm.PartNumber),
(const uint8_t *)&src_dimm.serialNumber[0],
64, /* hard-coded for DDR4 data width */
vdd_voltage,
true, /* hard-coded as ECC supported */
src_dimm.VendorID,
src_dimm.actKeyByte2,
0,
get_max_memory_speed(src_dimm.commonTck));
index++;
num_dimms++;
} else if (mainboard_dimm_slot_exists(0, ch, dimm)) {
if (index >= dimm_max) {
printk(BIOS_WARNING, "Too many DIMMs info for %s.\n",
__func__);
return;
}
dest_dimm = &mem_info->dimm[index];
dest_dimm->dimm_size = 0;
dest_dimm->channel_num = ch;
dest_dimm->dimm_num = dimm;
index++;
}
}
}
/* Save available DIMM slot information */
mem_info->dimm_cnt = index;
printk(BIOS_DEBUG, "%d out of %d DIMMs found\n", num_dimms, mem_info->dimm_cnt);
}
void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
{
FSP_M_CONFIG *m_cfg = &mupd->FspmConfig;
@ -188,3 +109,19 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
/* Adjust the "cold boot required" flag in CMOS. */
soc_set_mrc_cold_boot_flag(!mupd->FspmArchUpd.NvsBufferPtr);
}
uint32_t get_max_capacity_mib(void)
{
/* According to Dear Customer Letter it's 1.12 TB per processor. */
return 1.12 * MiB * CONFIG_MAX_SOCKET;
}
uint8_t get_max_dimm_count(void)
{
return MAX_IMC;
}
uint8_t get_dram_type(const struct SystemMemoryMapHob *hob)
{
return MEMORY_TYPE_DDR4;
}

View File

@ -0,0 +1,88 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <console/console.h>
#include <smbios.h>
#include <soc/ddr.h>
#include <soc/intel/common/smbios.h>
#include <soc/romstage.h>
#include <soc/util.h>
#include <spd.h>
void save_dimm_info(void)
{
const struct SystemMemoryMapHob *hob = get_system_memory_map();
assert(hob != NULL);
/*
* Allocate CBMEM area for DIMM information used to populate SMBIOS
* table 17
*/
struct memory_info *mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
if (mem_info == NULL) {
printk(BIOS_ERR, "CBMEM entry for DIMM info missing\n");
return;
}
memset(mem_info, 0, sizeof(*mem_info));
mem_info->max_capacity_mib = get_max_capacity_mib();
mem_info->number_of_devices = CONFIG_DIMM_MAX;
mem_info->ecc_type = get_error_correction_type(hob->RasModesEnabled);
int dimm_max = ARRAY_SIZE(mem_info->dimm);
uint32_t vdd_voltage = get_ddr_millivolt(hob->DdrVoltage);
int slot_index = 0;
const int max_dimm_count = get_max_dimm_count();
int dimm_num = 0;
for (int skt = 0; skt < CONFIG_MAX_SOCKET; skt++) {
for (int ch = 0; ch < MAX_CH; ch++) {
for (int dimm = 0; dimm < max_dimm_count; dimm++) {
if (slot_index >= dimm_max) {
printk(BIOS_WARNING, "Too many DIMMs info for %s.\n",
__func__);
return;
}
struct dimm_info *dest_dimm;
MEMMAP_DIMM_DEVICE_INFO_STRUCT src_dimm =
hob->Socket[skt].ChannelInfo[ch].DimmInfo[dimm];
if (src_dimm.Present) {
dest_dimm = &mem_info->dimm[slot_index++];
dest_dimm->dimm_size = (src_dimm.DimmSize << 6);
dest_dimm->soc_num = skt;
dest_dimm->channel_num = ch;
dest_dimm->dimm_num = dimm;
} else if (mainboard_dimm_slot_exists(skt, ch, dimm)) {
dest_dimm = &mem_info->dimm[slot_index++];
dest_dimm->dimm_size = 0;
dest_dimm->soc_num = skt;
dest_dimm->channel_num = ch;
dest_dimm->dimm_num = dimm;
continue;
} else
continue;
uint8_t mem_dev_type = get_dram_type(hob);
uint16_t data_width = 64;
dimm_info_fill(
dest_dimm, src_dimm.DimmSize << 6, mem_dev_type,
hob->memFreq, /* replaced by configured_speed_mts */
src_dimm.NumRanks,
ch, /* for mainboard locator string override */
dimm, /* for mainboard locator string override */
(const char *)&src_dimm.PartNumber[0],
sizeof(src_dimm.PartNumber),
(const uint8_t *)&src_dimm.serialNumber[0], data_width,
vdd_voltage, true, /* hard-coded as ECC supported */
src_dimm.VendorID, src_dimm.actKeyByte2, 0,
get_max_memory_speed(src_dimm.commonTck));
dimm_num++;
}
}
}
mem_info->dimm_cnt = slot_index; /* Number of DIMM slots found */
printk(BIOS_DEBUG, "%d slots and %d installed DIMMs found\n", slot_index, dimm_num);
}

View File

@ -12,6 +12,7 @@ subdirs-y += ../../../../cpu/intel/microcode
romstage-y += romstage.c
romstage-y += soc_util.c
romstage-y += soc_iio.c
romstage-y += ../dimm.c
romstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c
ramstage-y += chip.c

View File

@ -2,7 +2,10 @@
#include <console/console.h>
#include <soc/config.h>
#include <smbios.h>
#include <spd.h>
#include <soc/romstage.h>
#include <soc/soc_util.h>
static uint8_t get_mmcfg_base_upd_index(const uint64_t base_addr)
{
@ -66,3 +69,28 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
/* Board level settings */
mainboard_memory_init_params(mupd);
}
uint8_t get_error_correction_type(const uint8_t RasModesEnabled)
{
//TODO: to update later
return MEMORY_ARRAY_ECC_UNKNOWN;
}
uint32_t get_max_capacity_mib(void)
{
//TODO: to update later.
return 4 * MiB * CONFIG_MAX_SOCKET;
}
uint8_t get_max_dimm_count(void)
{
return MAX_DIMM;
}
uint8_t get_dram_type(const struct SystemMemoryMapHob *hob)
{
if (hob->DramType == SPD_MEMORY_TYPE_DDR5_SDRAM)
return MEMORY_TYPE_DDR5;
return MEMORY_TYPE_DDR4;
}

View File

@ -4,10 +4,15 @@
#define _SOC_ROMSTAGE_H_
#include <fsp/api.h>
#include <soc/soc_util.h>
/* These functions are weak and can be overridden by a mainboard functions. */
void mainboard_memory_init_params(FSPM_UPD * mupd);
void mainboard_rtc_failed(void);
uint32_t get_max_capacity_mib(void);
uint8_t get_error_correction_type(const uint8_t RasModesEnabled);
uint8_t get_max_dimm_count(void);
uint8_t get_dram_type(const struct SystemMemoryMapHob *hob);
void save_dimm_info(void);
void mainboard_ewl_check(void);
void mainboard_fsp_error_handle(void);

View File

@ -4,8 +4,12 @@
#include <intelblocks/rtc.h>
#include <console/console.h>
#include <fsp/util.h>
#include <smbios.h>
#include <soc/ddr.h>
#include <soc/intel/common/smbios.h>
#include <soc/romstage.h>
#include <soc/util.h>
#include <spd.h>
void mainboard_romstage_entry(void)
{
@ -35,7 +39,7 @@ __weak void mainboard_memory_init_params(FSPM_UPD *mupd)
__weak void mainboard_rtc_failed(void)
{
}
__weak void save_dimm_info(void) { }
__weak void mainboard_ewl_check(void) { }
/* mainboard can override this function for their own handling, such as writing a BMC SEL. */

View File

@ -24,3 +24,5 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
m_cfg->VTdConfig.CoherencySupport = config->coherency_support;
m_cfg->VTdConfig.ATS = config->ats_support;
}
void save_dimm_info(void) {}

View File

@ -9,6 +9,7 @@ subdirs-y += ../../../../cpu/x86/tsc
subdirs-y += ../../../../cpu/intel/microcode
romstage-y += romstage.c soc_util.c
romstage-y += ../dimm.c
romstage-$(CONFIG_DISPLAY_HOBS) += hob_display.c
romstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c

View File

@ -18,7 +18,6 @@
#include <soc/romstage.h>
#include <soc/pci_devs.h>
#include <soc/soc_pch.h>
#include <soc/intel/common/smbios.h>
#include <string.h>
#include <soc/config.h>
#include <soc/soc_util.h>
@ -251,7 +250,7 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
pch_disable_hda();
}
static uint8_t get_error_correction_type(const uint8_t RasModesEnabled)
uint8_t get_error_correction_type(const uint8_t RasModesEnabled)
{
switch (RasModesEnabled) {
case CH_INDEPENDENT:
@ -270,94 +269,21 @@ static uint8_t get_error_correction_type(const uint8_t RasModesEnabled)
}
}
/* Save the DIMM information for SMBIOS table 17 */
void save_dimm_info(void)
uint8_t get_max_dimm_count(void)
{
struct dimm_info *dest_dimm;
struct memory_info *mem_info;
const struct SystemMemoryMapHob *hob;
MEMMAP_DIMM_DEVICE_INFO_STRUCT src_dimm;
int dimm_max, dimm_num = 0;
int index = 0;
uint8_t mem_dev_type;
uint16_t data_width;
uint32_t vdd_voltage;
hob = get_system_memory_map();
assert(hob != NULL);
/*
* Allocate CBMEM area for DIMM information used to populate SMBIOS
* table 17
*/
mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
if (mem_info == NULL) {
printk(BIOS_ERR, "CBMEM entry for DIMM info missing\n");
return;
}
memset(mem_info, 0, sizeof(*mem_info));
/* According to EDS doc#611488, it's 4 TB per processor. */
mem_info->max_capacity_mib = 4 * MiB * CONFIG_MAX_SOCKET;
mem_info->number_of_devices = CONFIG_DIMM_MAX;
mem_info->ecc_type = get_error_correction_type(hob->RasModesEnabled);
dimm_max = ARRAY_SIZE(mem_info->dimm);
vdd_voltage = get_ddr_millivolt(hob->DdrVoltage);
for (int soc = 0; soc < CONFIG_MAX_SOCKET; soc++) {
for (int ch = 0; ch < MAX_CH; ch++) {
for (int dimm = 0; dimm < MAX_DIMM; dimm++) {
if (index >= dimm_max) {
printk(BIOS_WARNING, "Too many DIMMs info for %s.\n",
__func__);
return;
}
src_dimm = hob->Socket[soc].ChannelInfo[ch].DimmInfo[dimm];
if (src_dimm.Present) {
dest_dimm = &mem_info->dimm[index];
index++;
} else if (mainboard_dimm_slot_exists(soc, ch, dimm)) {
dest_dimm = &mem_info->dimm[index];
index++;
/* Save DIMM Locator information for SMBIOS Type 17 */
dest_dimm->dimm_size = 0;
dest_dimm->soc_num = soc;
dest_dimm->channel_num = ch;
dest_dimm->dimm_num = dimm;
continue;
} else {
/* Ignore DIMM that isn't present and doesn't exist on
the board. */
continue;
}
dest_dimm->soc_num = soc;
if (hob->DramType == SPD_MEMORY_TYPE_DDR5_SDRAM) {
/* hard-coded memory device type as DDR5 */
mem_dev_type = 0x22;
data_width = 64;
} else {
/* hard-coded memory device type as DDR4 */
mem_dev_type = 0x1A;
data_width = 64;
}
dimm_info_fill(
dest_dimm, src_dimm.DimmSize << 6, mem_dev_type,
hob->memFreq, /* replaced by configured_speed_mts */
src_dimm.NumRanks,
ch, /* for mainboard locator string override */
dimm, /* for mainboard locator string override */
(const char *)&src_dimm.PartNumber[0],
sizeof(src_dimm.PartNumber),
(const uint8_t *)&src_dimm.serialNumber[0], data_width,
vdd_voltage, true, /* hard-coded as ECC supported */
src_dimm.VendorID, src_dimm.actKeyByte2, 0,
get_max_memory_speed(src_dimm.commonTck));
dimm_num++;
}
}
}
mem_info->dimm_cnt = index; /* Number of DIMM slots found */
printk(BIOS_DEBUG, "%d Installed DIMMs found\n", dimm_num);
return MAX_DIMM;
}
uint8_t get_dram_type(const struct SystemMemoryMapHob *hob)
{
if (hob->DramType == SPD_MEMORY_TYPE_DDR5_SDRAM)
return MEMORY_TYPE_DDR5;
return MEMORY_TYPE_DDR4;
}
uint32_t get_max_capacity_mib(void)
{
/* According to EDS doc#611488, it's 4 TB per processor. */
return 4 * MiB * CONFIG_MAX_SOCKET;
}