[coreboot-gerrit] New patch to review for coreboot: Kabylake: [WIP] Save Memory Info HOB data in SMBIOS Table

Barnali Sarkar (barnali.sarkar@intel.com) gerrit at coreboot.org
Wed Feb 1 12:06:57 CET 2017


Barnali Sarkar (barnali.sarkar at intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18275

-gerrit

commit 1164fb2c5f6dfa7fd6cce6e9ee0f1c13229d5163
Author: Barnali Sarkar <barnali.sarkar at intel.com>
Date:   Wed Feb 1 16:25:04 2017 +0530

    Kabylake: [WIP] Save Memory Info HOB data in SMBIOS Table
    
    Extract SMBIOS memory information from FSP SMBIOS_MEM_INFO_HOB
    and save in cbmem.
    Add the MemInfoHob.h provided by FSP for aid in parsing the HOB.
    
    BUG=chrome-os-partner:61729
    BRANCH=none
    TEST=Build and boot KBLRVP
    
    Change-Id: I593d4ccb0d4866e99913a73c49b2f000b51827d1
    Signed-off-by: Barnali Sarkar <barnali.sarkar at intel.com>
    Signed-off-by: Rizwan Qureshi <rizwan.qureshi at intel.com>
---
 src/soc/intel/skylake/include/fsp20/soc/romstage.h |   5 +
 src/soc/intel/skylake/romstage/romstage_fsp20.c    |  86 ++++++-
 .../intel/fsp/fsp2_0/skykabylake/MemInfoHob.h      | 254 +++++++++++++++++++++
 3 files changed, 344 insertions(+), 1 deletion(-)

diff --git a/src/soc/intel/skylake/include/fsp20/soc/romstage.h b/src/soc/intel/skylake/include/fsp20/soc/romstage.h
index 41658e1..3db3a53 100644
--- a/src/soc/intel/skylake/include/fsp20/soc/romstage.h
+++ b/src/soc/intel/skylake/include/fsp20/soc/romstage.h
@@ -20,11 +20,16 @@
 #include <arch/cpu.h>
 #include <fsp/api.h>
 
+#pragma pack(push)
+#include <MemInfoHob.h>
+#pragma pack(pop)
+
 asmlinkage void *car_stage_c_entry(void);
 void mainboard_memory_init_params(FSPM_UPD *mupd);
 void systemagent_early_init(void);
 int smbus_read_byte(unsigned device, unsigned address);
 int early_spi_read_wpsr(u8 *sr);
+void save_dimm_info(void);
 /* Board type */
 enum board_type {
 	BOARD_TYPE_MOBILE	= 0,
diff --git a/src/soc/intel/skylake/romstage/romstage_fsp20.c b/src/soc/intel/skylake/romstage/romstage_fsp20.c
index e478890..175b386 100644
--- a/src/soc/intel/skylake/romstage/romstage_fsp20.c
+++ b/src/soc/intel/skylake/romstage/romstage_fsp20.c
@@ -26,10 +26,13 @@
 #include <device/pci_def.h>
 #include <fsp/util.h>
 #include <fsp/memmap.h>
+#include <memory_info.h>
+#include <smbios.h>
 #include <soc/msr.h>
 #include <soc/pci_devs.h>
 #include <soc/pm.h>
 #include <soc/romstage.h>
+#include <string.h>
 #include <timestamp.h>
 #include <vboot/vboot_common.h>
 
@@ -56,7 +59,7 @@ asmlinkage void *car_stage_c_entry(void)
 	s3wake = ps->prev_sleep_state == ACPI_S3;
 	fsp_memory_init(s3wake);
 	pmc_set_disb();
-
+	save_dimm_info();
 	if (postcar_frame_init(&pcf, ROMSTAGE_RAM_STACK_SIZE))
 		die("Unable to initialize postcar frame.\n");
 
@@ -187,3 +190,84 @@ __attribute__((weak)) void mainboard_memory_init_params(FSPM_UPD *mupd)
 {
 	/* Do nothing */
 }
+
+/* Save the DIMM information for SMBIOS table 17 */
+void save_dimm_info(void)
+{
+	int channel, dimm, dimm_max, index;
+	size_t hob_size;
+	const CONTROLLER_INFO *ctrlr_info;
+	const CHANNEL_INFO *channel_info;
+	const DIMM_INFO *src_dimm;
+	struct dimm_info *dest_dimm;
+	struct memory_info *mem_info;
+	const MEMORY_INFO_DATA_HOB *memory_info_hob;
+
+	/* Locate the memory info HOB, presence validated by raminit */
+	memory_info_hob = fsp_find_smbios_memory_info(&hob_size);
+
+	/*
+	 * 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));
+
+	/* Describe the first N DIMMs in the system */
+	index = 0;
+	dimm_max = ARRAY_SIZE(mem_info->dimm);
+	ctrlr_info = &memory_info_hob->Controller[0];
+	for (channel = 0; channel < ctrlr_info->ChannelCount; channel++) {
+		if (index >= dimm_max)
+			break;
+		channel_info = &ctrlr_info->Channel[channel];
+		for (dimm = 0; dimm < channel_info->DimmCount; dimm++) {
+			if (index >= dimm_max)
+				break;
+			src_dimm = &channel_info->Dimm[dimm];
+			dest_dimm = &mem_info->dimm[index];
+
+			if (!src_dimm->DimmCapacity)
+				continue;
+
+			/* Populate the DIMM information */
+			dest_dimm->dimm_size = src_dimm->DimmCapacity;
+			dest_dimm->ddr_type = memory_info_hob->DdrType;
+			dest_dimm->ddr_frequency =
+					memory_info_hob->Frequency;
+			dest_dimm->channel_num = channel_info->ChannelId;
+			dest_dimm->dimm_num = src_dimm->DimmId;
+			strncpy((char *)dest_dimm->module_part_number,
+					(char *)src_dimm->ModulePartNum,
+					sizeof(dest_dimm->module_part_number));
+
+			switch (memory_info_hob->DataWidth) {
+			case 8:
+				dest_dimm->bus_width = MEMORY_BUS_WIDTH_8;
+				break;
+			case 16:
+				dest_dimm->bus_width = MEMORY_BUS_WIDTH_16;
+				break;
+			case 32:
+				dest_dimm->bus_width = MEMORY_BUS_WIDTH_32;
+				break;
+			case 64:
+				dest_dimm->bus_width = MEMORY_BUS_WIDTH_64;
+				break;
+			case 128:
+				dest_dimm->bus_width = MEMORY_BUS_WIDTH_128;
+				break;
+			default:
+				printk(BIOS_ERR, "Incorrect DIMM Data Width");
+			}
+			index++;
+		}
+	}
+	mem_info->dimm_cnt = index;
+	printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
+}
+
diff --git a/src/vendorcode/intel/fsp/fsp2_0/skykabylake/MemInfoHob.h b/src/vendorcode/intel/fsp/fsp2_0/skykabylake/MemInfoHob.h
new file mode 100644
index 0000000..bdaf39b
--- /dev/null
+++ b/src/vendorcode/intel/fsp/fsp2_0/skykabylake/MemInfoHob.h
@@ -0,0 +1,254 @@
+/** @file
+  This file contains definitions required for creation of
+  Memory S3 Save data, Memory Info data and Memory Platform
+  data hobs.
+
+ @copyright
+  INTEL CONFIDENTIAL
+  Copyright 1999 - 2016 Intel Corporation.
+
+  The source code contained or described herein and all documents related to the
+  source code ("Material") are owned by Intel Corporation or its suppliers or
+  licensors. Title to the Material remains with Intel Corporation or its suppliers
+  and licensors. The Material may contain trade secrets and proprietary and
+  confidential information of Intel Corporation and its suppliers and licensors,
+  and is protected by worldwide copyright and trade secret laws and treaty
+  provisions. No part of the Material may be used, copied, reproduced, modified,
+  published, uploaded, posted, transmitted, distributed, or disclosed in any way
+  without Intel's prior express written permission.
+
+  No license under any patent, copyright, trade secret or other intellectual
+  property right is granted to or conferred upon you by disclosure or delivery
+  of the Materials, either expressly, by implication, inducement, estoppel or
+  otherwise. Any license under such intellectual property rights must be
+  express and approved by Intel in writing.
+
+  Unless otherwise agreed by Intel in writing, you may not remove or alter
+  this notice or any other notice embedded in Materials by Intel or
+  Intel's suppliers or licensors in any way.
+
+  This file contains an 'Intel Peripheral Driver' and is uniquely identified as
+  "Intel Reference Module" and is licensed for Intel CPUs and chipsets under
+  the terms of your license agreement with Intel or your vendor. This file may
+  be modified by the user, subject to additional terms of the license agreement.
+
+ at par Specification Reference:
+**/
+#ifndef _MEM_INFO_HOB_H_
+#define _MEM_INFO_HOB_H_
+
+#pragma pack (push, 1)
+
+extern EFI_GUID gSiMemoryS3DataGuid;
+extern EFI_GUID gSiMemoryInfoDataGuid;
+extern EFI_GUID gSiMemoryPlatformDataGuid;
+
+#define MAX_NODE        1
+#define MAX_CH          2
+#define MAX_DIMM        2
+
+///
+/// Host reset states from MRC.
+///
+#define  WARM_BOOT        2
+
+#define R_MC_CHNL_RANK_PRESENT  0x7C
+#define   B_RANK0_PRS           BIT0
+#define   B_RANK1_PRS           BIT1
+#define   B_RANK2_PRS           BIT4
+#define   B_RANK3_PRS           BIT5
+
+// @todo remove and use the MdePkg\Include\Pi\PiHob.h
+#if !defined(_PEI_HOB_H_) && !defined(__PI_HOB_H__)
+#ifndef __HOB__H__
+typedef struct _EFI_HOB_GENERIC_HEADER {
+  UINT16  HobType;
+  UINT16  HobLength;
+  UINT32  Reserved;
+} EFI_HOB_GENERIC_HEADER;
+
+typedef struct _EFI_HOB_GUID_TYPE {
+  EFI_HOB_GENERIC_HEADER  Header;
+  EFI_GUID                Name;
+  ///
+  /// Guid specific data goes here
+  ///
+} EFI_HOB_GUID_TYPE;
+#endif
+#endif
+
+///
+/// Defines taken from MRC so avoid having to include MrcInterface.h
+///
+
+//
+// Matches MAX_SPD_SAVE define in MRC
+//
+#ifndef MAX_SPD_SAVE
+#define MAX_SPD_SAVE 29
+#endif
+
+//
+// MRC version description.
+//
+typedef struct {
+  UINT8  Major;     ///< Major version number
+  UINT8  Minor;     ///< Minor version number
+  UINT8  Rev;       ///< Revision number
+  UINT8  Build;     ///< Build number
+} SiMrcVersion;
+
+//
+// Matches MrcDimmSts enum in MRC
+//
+#ifndef DIMM_ENABLED
+#define DIMM_ENABLED     0  // DIMM/rank Pair is enabled, presence will be detected.
+#endif
+#ifndef DIMM_DISABLED
+#define DIMM_DISABLED    1  // DIMM/rank Pair is disabled, regardless of presence.
+#endif
+#ifndef DIMM_PRESENT
+#define DIMM_PRESENT     2  // There is a DIMM present in the slot/rank pair and it will be used.
+#endif
+#ifndef DIMM_NOT_PRESENT
+#define DIMM_NOT_PRESENT 3  // There is no DIMM present in the slot/rank pair.
+#endif
+
+//
+// Matches MrcBootMode enum in MRC
+//
+#ifndef bmCold
+#define bmCold 0            // Cold boot
+#endif
+#ifndef bmWarm
+#define bmWarm 1            // Warm boot
+#endif
+#ifndef bmS3
+#define bmS3   2            // S3 resume
+#endif
+#ifndef bmFast
+#define bmFast 3            // Fast boot
+#endif
+
+//
+// Matches MrcDdrType enum in MRC
+//
+#ifndef MRC_DDR_TYPE_DDR4
+#define MRC_DDR_TYPE_DDR4     0
+#endif
+#ifndef MRC_DDR_TYPE_DDR3
+#define MRC_DDR_TYPE_DDR3     1
+#endif
+#ifndef MRC_DDR_TYPE_LPDDR3
+#define MRC_DDR_TYPE_LPDDR3   2
+#endif
+#ifndef MRC_DDR_TYPE_UNKNOWN
+#define MRC_DDR_TYPE_UNKNOWN  3
+#endif
+
+#define MAX_PROFILE_NUM 4 // number of memory profiles supported
+#define MAX_XMP_PROFILE_NUM 2 // number of XMP profiles supported
+
+//
+// DIMM timings
+//
+typedef struct {
+  UINT32 tCK;       ///< Memory cycle time, in femtoseconds.
+  UINT16 NMode;     ///< Number of tCK cycles for the channel DIMM's command rate mode.
+  UINT16 tCL;       ///< Number of tCK cycles for the channel DIMM's CAS latency.
+  UINT16 tCWL;      ///< Number of tCK cycles for the channel DIMM's minimum CAS write latency time.
+  UINT16 tFAW;      ///< Number of tCK cycles for the channel DIMM's minimum four activate window delay time.
+  UINT16 tRAS;      ///< Number of tCK cycles for the channel DIMM's minimum active to precharge delay time.
+  UINT16 tRCDtRP;   ///< Number of tCK cycles for the channel DIMM's minimum RAS# to CAS# delay time and Row Precharge delay time.
+  UINT16 tREFI;     ///< Number of tCK cycles for the channel DIMM's minimum Average Periodic Refresh Interval.
+  UINT16 tRFC;      ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
+  UINT16 tRFC2;     ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
+  UINT16 tRFC4;     ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time.
+  UINT16 tRPab;     ///< Number of tCK cycles for the channel DIMM's minimum row precharge delay time for all banks.
+  UINT16 tRRD;      ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time.
+  UINT16 tRRD_L;    ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for same bank groups.
+  UINT16 tRRD_S;    ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for different bank groups.
+  UINT16 tRTP;      ///< Number of tCK cycles for the channel DIMM's minimum internal read to precharge command delay time.
+  UINT16 tWR;       ///< Number of tCK cycles for the channel DIMM's minimum write recovery time.
+  UINT16 tWTR;      ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time.
+  UINT16 tWTR_L;    ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for same bank groups.
+  UINT16 tWTR_S;    ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for different bank groups.
+} MRC_CH_TIMING;
+
+///
+/// Memory SMBIOS & OC Memory Data Hob
+///
+typedef struct {
+  UINT8  Status;                            ///< See MrcDimmStatus for the definition of this field.
+  UINT8  DimmId;
+  UINT32 DimmCapacity;                      ///< DIMM size in MBytes.
+  UINT16 MfgId;
+  UINT8  ModulePartNum[20];                 ///< Module part number for DDR3 is 18 bytes however for DRR4 20 bytes as per JEDEC Spec, so reserving 20 bytes
+  UINT8  RankInDimm;                        ///< The number of ranks in this DIMM.
+  UINT8  SpdDramDeviceType;                 ///< Save SPD DramDeviceType information needed for SMBIOS structure creation.
+  UINT8  SpdModuleType;                     ///< Save SPD ModuleType information needed for SMBIOS structure creation.
+  UINT8  SpdModuleMemoryBusWidth;           ///< Save SPD ModuleMemoryBusWidth information needed for SMBIOS structure creation.
+  UINT8  SpdSave[MAX_SPD_SAVE];             ///< Save SPD Manufacturing information needed for SMBIOS structure creation.
+} DIMM_INFO;
+
+typedef struct {
+  UINT8         Status;                     ///< Indicates whether this channel should be used.
+  UINT8         ChannelId;
+  UINT8         DimmCount;                  ///< Number of valid DIMMs that exist in the channel.
+  MRC_CH_TIMING Timing[MAX_PROFILE_NUM];    ///< The channel timing values.
+  DIMM_INFO     Dimm[MAX_DIMM];             ///< Save the DIMM output characteristics.
+} CHANNEL_INFO;
+
+typedef struct {
+  UINT8            Status;                  ///< Indicates whether this controller should be used.
+  UINT16           DeviceId;                ///< The PCI device id of this memory controller.
+  UINT8            RevisionId;              ///< The PCI revision id of this memory controller.
+  UINT8            ChannelCount;            ///< Number of valid channels that exist on the controller.
+  CHANNEL_INFO     Channel[MAX_CH];         ///< The following are channel level definitions.
+} CONTROLLER_INFO;
+
+typedef struct {
+  EFI_HOB_GUID_TYPE EfiHobGuidType;
+  UINT8             Revision;
+  UINT16            DataWidth;
+  /** As defined in SMBIOS 3.0 spec
+    Section 7.18.2 and Table 75
+  **/
+  UINT8             DdrType;                ///< DDR type: DDR3, DDR4, or LPDDR3
+  UINT32            Frequency;              ///< The system's common memory controller frequency in MT/s.
+  /** As defined in SMBIOS 3.0 spec
+    Section 7.17.3 and Table 72
+  **/
+  UINT8             ErrorCorrectionType;
+
+  SiMrcVersion      Version;
+  UINT32            FreqMax;
+  BOOLEAN           EccSupport;
+  UINT8             MemoryProfile;
+  UINT32            TotalPhysicalMemorySize;
+  UINT32            DefaultXmptCK[MAX_XMP_PROFILE_NUM]; // Stores the tCK value read from SPD XMP profiles if they exist.
+  UINT8             XmpProfileEnable;                   // If XMP capable DIMMs are detected, this will indicate which XMP Profiles are common among all DIMMs.
+  UINT8             Ratio;
+  UINT8             RefClk;
+  UINT32            VddVoltage[MAX_PROFILE_NUM];
+  CONTROLLER_INFO   Controller[MAX_NODE];
+} MEMORY_INFO_DATA_HOB;
+
+///
+/// Memory Platform Data Hob
+///
+typedef struct {
+  UINT8             Revision;
+  UINT8             Reserved[3];
+  UINT32            BootMode;
+  UINT32            TsegSize;
+} MEMORY_PLATFORM_DATA;
+
+typedef struct {
+  EFI_HOB_GUID_TYPE    EfiHobGuidType;
+  MEMORY_PLATFORM_DATA Data;
+  UINT8                *Buffer;
+} MEMORY_PLATFORM_DATA_HOB;
+#pragma pack (pop)
+
+#endif // _MEM_INFO_HOB_H_



More information about the coreboot-gerrit mailing list