summaryrefslogtreecommitdiff
path: root/src/soc/amd/common/fsp
diff options
context:
space:
mode:
authorNikolai Vyssotski <nikolai.vyssotski@amd.corp-partner.google.com>2021-04-28 18:09:29 -0500
committerFelix Held <felix-coreboot@felixheld.de>2021-06-13 09:55:30 +0000
commita289cdd59c7353830f81601d1a2fd5e34fddd7ad (patch)
tree8a5f73355a038640612739d32610b2b2ac8ed5c0 /src/soc/amd/common/fsp
parentbdb08188cbe3fba85dbeadadc469aa604394c293 (diff)
soc/amd/picasso: Move Type 17 DMI generation to common
Move dmi.c code to common/fsp to be shared among different SOCs. BUG=b:184124605 Change-Id: I46071556bbbbf6435d9e3724bba19e102bd02535 Signed-off-by: Nikolai Vyssotski <nikolai.vyssotski@amd.corp-partner.google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/52746 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
Diffstat (limited to 'src/soc/amd/common/fsp')
-rw-r--r--src/soc/amd/common/fsp/Makefile.inc1
-rw-r--r--src/soc/amd/common/fsp/dmi.c198
2 files changed, 199 insertions, 0 deletions
diff --git a/src/soc/amd/common/fsp/Makefile.inc b/src/soc/amd/common/fsp/Makefile.inc
index ff25eba387..8a5cef5ffe 100644
--- a/src/soc/amd/common/fsp/Makefile.inc
+++ b/src/soc/amd/common/fsp/Makefile.inc
@@ -2,6 +2,7 @@ ifeq ($(CONFIG_PLATFORM_USES_FSP2_0),y)
romstage-y += fsp_reset.c
ramstage-y += fsp_reset.c
ramstage-$(CONFIG_HAVE_ACPI_TABLES) += fsp-acpi.c
+ramstage-$(CONFIG_SOC_AMD_COMMON_FSP_DMI_TABLES) += dmi.c
subdirs-y += ./*
diff --git a/src/soc/amd/common/fsp/dmi.c b/src/soc/amd/common/fsp/dmi.c
new file mode 100644
index 0000000000..b3eb5746db
--- /dev/null
+++ b/src/soc/amd/common/fsp/dmi.c
@@ -0,0 +1,198 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/**
+ * This code was adapted from src/soc/amd/common/block/pi/amd_late_init.c
+ */
+
+#include <fsp/util.h>
+#include <memory_info.h>
+#include <console/console.h>
+#include <cbmem.h>
+#include <string.h>
+#include <ec/google/chromeec/ec.h>
+#include <bootstate.h>
+#include <lib.h>
+#include <dimm_info_util.h>
+#include <dmi_info.h>
+#include <device/dram/ddr4.h>
+
+/**
+ * Populate dimm_info using AGESA TYPE17_DMI_INFO.
+ */
+static void transfer_memory_info(const TYPE17_DMI_INFO *dmi17,
+ struct dimm_info *dimm)
+{
+ hexstrtobin(dmi17->SerialNumber, dimm->serial, sizeof(dimm->serial));
+
+ dimm->dimm_size = smbios_memory_size_to_mib(dmi17->MemorySize, dmi17->ExtSize);
+
+ dimm->ddr_type = dmi17->MemoryType;
+
+ dimm->configured_speed_mts = ddr4_speed_mhz_to_reported_mts(dmi17->ConfigSpeed);
+
+ dimm->max_speed_mts = ddr4_speed_mhz_to_reported_mts(dmi17->Speed);
+
+ dimm->rank_per_dimm = dmi17->Attributes;
+
+ dimm->mod_type = smbios_form_factor_to_spd_mod_type(dmi17->FormFactor);
+
+ dimm->bus_width =
+ smbios_bus_width_to_spd_width(dmi17->TotalWidth, dmi17->DataWidth);
+
+ dimm->mod_id = dmi17->ManufacturerIdCode;
+
+ dimm->bank_locator = 0;
+
+ strncpy((char *)dimm->module_part_number, dmi17->PartNumber,
+ sizeof(dimm->module_part_number) - 1);
+}
+
+static void print_dimm_info(const struct dimm_info *dimm)
+{
+ printk(BIOS_DEBUG,
+ "CBMEM_ID_MEMINFO:\n"
+ " dimm_size: %u\n"
+ " ddr_type: 0x%hx\n"
+ " ddr_frequency: %hu\n"
+ " rank_per_dimm: %hhu\n"
+ " channel_num: %hhu\n"
+ " dimm_num: %hhu\n"
+ " bank_locator: %hhu\n"
+ " mod_id: %hx\n"
+ " mod_type: 0x%hhx\n"
+ " bus_width: %hhu\n"
+ " serial: %02hhx%02hhx%02hhx%02hhx\n"
+ " module_part_number(%zu): %s\n",
+ dimm->dimm_size,
+ dimm->ddr_type,
+ dimm->ddr_frequency,
+ dimm->rank_per_dimm,
+ dimm->channel_num,
+ dimm->dimm_num,
+ dimm->bank_locator,
+ dimm->mod_id,
+ dimm->mod_type,
+ dimm->bus_width,
+ dimm->serial[0],
+ dimm->serial[1],
+ dimm->serial[2],
+ dimm->serial[3],
+ strlen((const char *)dimm->module_part_number),
+ (char *)dimm->module_part_number);
+}
+
+static void print_dmi_info(const TYPE17_DMI_INFO *dmi17)
+{
+ printk(BIOS_DEBUG,
+ "AGESA TYPE 17 DMI INFO:\n"
+ " Handle: %hu\n"
+ " TotalWidth: %hu\n"
+ " DataWidth: %hu\n"
+ " MemorySize: %hu\n"
+ " DeviceSet: %hhu\n"
+ " Speed: %hu\n"
+ " ManufacturerIdCode: %llx\n"
+ " Attributes: %hhu\n"
+ " ExtSize: %u\n"
+ " ConfigSpeed: %hu\n"
+ " MemoryType: 0x%x\n"
+ " FormFactor: 0x%x\n"
+ " DeviceLocator: %8s\n"
+ " BankLocator: %10s\n"
+ " SerialNumber(%zu): %9s\n"
+ " PartNumber(%zu): %19s\n",
+ dmi17->Handle,
+ dmi17->TotalWidth,
+ dmi17->DataWidth,
+ dmi17->MemorySize,
+ dmi17->DeviceSet,
+ dmi17->Speed,
+ dmi17->ManufacturerIdCode,
+ dmi17->Attributes,
+ dmi17->ExtSize,
+ dmi17->ConfigSpeed,
+ dmi17->MemoryType,
+ dmi17->FormFactor,
+ dmi17->DeviceLocator,
+ dmi17->BankLocator,
+ strlen((const char *)dmi17->SerialNumber),
+ dmi17->SerialNumber,
+ strlen((const char *)dmi17->PartNumber),
+ dmi17->PartNumber);
+}
+
+/**
+ * Marshalls dimm info from AMD_FSP_DMI_HOB into CBMEM_ID_MEMINFO
+ */
+static void prepare_dmi_17(void *unused)
+{
+ const DMI_INFO *dmi_table;
+ const TYPE17_DMI_INFO *type17_dmi_info;
+ struct memory_info *mem_info;
+ struct dimm_info *dimm_info;
+ char cbi_part_number[DIMM_INFO_PART_NUMBER_SIZE];
+ bool use_cbi_part_number = false;
+ size_t dimm_cnt = 0;
+ size_t amd_fsp_dmi_hob_size;
+ const EFI_GUID amd_fsp_dmi_hob_guid = AMD_FSP_DMI_HOB_GUID;
+
+ printk(BIOS_DEBUG, "Saving dimm info for smbios type 17\n");
+
+ /* Allocate meminfo in cbmem. */
+ mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(struct memory_info));
+ if (!mem_info) {
+ printk(BIOS_ERR,
+ "Failed to add memory info to CBMEM, DMI tables will be incomplete\n");
+ return;
+ }
+ memset(mem_info, 0, sizeof(struct memory_info));
+
+ /* Locate the memory info HOB. */
+ dmi_table = fsp_find_extension_hob_by_guid(
+ (const uint8_t *)&amd_fsp_dmi_hob_guid, &amd_fsp_dmi_hob_size);
+
+ if (dmi_table == NULL || amd_fsp_dmi_hob_size == 0) {
+ printk(BIOS_ERR,
+ "AMD_FSP_DMI_HOB not found, DMI table 17 will be incomplete\n");
+ return;
+ }
+ printk(BIOS_DEBUG, "AMD_FSP_DMI_HOB found\n");
+
+ if (CONFIG(EC_GOOGLE_CHROMEEC)) {
+ /* Prefer DRAM part number from CBI. */
+ if (google_chromeec_cbi_get_dram_part_num(
+ cbi_part_number, sizeof(cbi_part_number)) == 0) {
+ use_cbi_part_number = true;
+ } else {
+ printk(BIOS_ERR, "Could not obtain DRAM part number from CBI\n");
+ }
+ }
+
+ for (unsigned int channel = 0; channel < MAX_CHANNELS_PER_SOCKET; channel++) {
+ for (unsigned int dimm = 0; dimm < MAX_DIMMS_PER_CHANNEL; dimm++) {
+ type17_dmi_info = &dmi_table->T17[0][channel][dimm];
+ /* DIMMs that are present will have a non-zero
+ handle. */
+ if (type17_dmi_info->Handle == 0)
+ continue;
+ print_dmi_info(type17_dmi_info);
+ dimm_info = &mem_info->dimm[dimm_cnt];
+ dimm_info->channel_num = channel;
+ dimm_info->dimm_num = channel;
+ transfer_memory_info(type17_dmi_info, dimm_info);
+ if (use_cbi_part_number) {
+ /* mem_info is memset to 0 above, so it's
+ safe to assume module_part_number will be
+ null terminated */
+ strncpy((char *)dimm_info->module_part_number, cbi_part_number,
+ sizeof(dimm_info->module_part_number) - 1);
+ }
+ print_dimm_info(dimm_info);
+ dimm_cnt++;
+ }
+ }
+ mem_info->dimm_cnt = dimm_cnt;
+}
+
+/* AMD_FSP_DMI_HOB is initialized very late, so check it just in time for writing tables. */
+BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY, prepare_dmi_17, NULL);