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:
parent
dc8123a775
commit
c19e32e69d
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
88
src/soc/intel/xeon_sp/dimm.c
Normal file
88
src/soc/intel/xeon_sp/dimm.c
Normal 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);
|
||||
}
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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) {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user