diff options
author | Johnny Lin <johnny_lin@wiwynn.com> | 2020-09-28 22:38:31 +0800 |
---|---|---|
committer | Angel Pons <th3fanbus@gmail.com> | 2020-10-08 12:09:26 +0000 |
commit | 7581352759ed3553f42b5356aaaa9759ec1c43b9 (patch) | |
tree | 97d0128b663efb5130f3b774b0c28ad3be48fd54 /src/soc/intel/xeon_sp/cpx/romstage.c | |
parent | b734ae2e8a1b9d7bca23f97b2da08c7817b8972a (diff) |
soc/intel/xeon_sp/cpx: Add save_dimm_info for SMBIOS type 17
For now only implement for one socket and some of the fields
are hard-coded for DDR4 including memory device type, data width
and ECC support.
Change-Id: I3cb72d18027d972140828970206834ff55b72022
Signed-off-by: Johnny Lin <johnny_lin@wiwynn.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/45798
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Jonathan Zhang <jonzhang@fb.com>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Diffstat (limited to 'src/soc/intel/xeon_sp/cpx/romstage.c')
-rw-r--r-- | src/soc/intel/xeon_sp/cpx/romstage.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/src/soc/intel/xeon_sp/cpx/romstage.c b/src/soc/intel/xeon_sp/cpx/romstage.c index a198c993f3..6f47a30234 100644 --- a/src/soc/intel/xeon_sp/cpx/romstage.c +++ b/src/soc/intel/xeon_sp/cpx/romstage.c @@ -1,9 +1,19 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include <assert.h> #include <arch/romstage.h> +#include <console/console.h> +#include <cbmem.h> #include <fsp/api.h> +#include <fsp/util.h> +#include <hob_iiouds.h> +#include <hob_memmap.h> +#include <soc/ddr.h> #include <soc/romstage.h> #include <soc/pci_devs.h> +#include <soc/intel/common/smbios.h> +#include <string.h> + #include "chip.h" void __weak mainboard_memory_init_params(FSPM_UPD *mupd) @@ -11,6 +21,86 @@ void __weak mainboard_memory_init_params(FSPM_UPD *mupd) /* Default weak implementation */ } +static const struct SystemMemoryMapHob *get_system_memory_map(void) +{ + size_t hob_size; + const uint8_t mem_hob_guid[16] = FSP_SYSTEM_MEMORYMAP_HOB_GUID; + const struct SystemMemoryMapHob **memmap_addr; + + memmap_addr = (const struct SystemMemoryMapHob **) + fsp_find_extension_hob_by_guid(mem_hob_guid, &hob_size); + /* hob_size is the size of the 8-byte address not the hob data */ + assert(memmap_addr != NULL && hob_size != 0); + /* assert the pointer to the hob is not NULL */ + assert(*memmap_addr != NULL); + + return *memmap_addr; +} + +/* 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; + 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)); + 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]; + dest_dimm->max_speed_mts = + get_max_memory_speed(src_dimm.commonTck); + dest_dimm->configured_speed_mts = hob->memFreq; + 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); + index++; + } + } + } + + /* Save available DIMM information */ + mem_info->dimm_cnt = index; + printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt); +} + void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) { FSPM_CONFIG *m_cfg = &mupd->FspmConfig; |