[coreboot-gerrit] Patch set updated for coreboot: skylake: Add FSP 2.0 support in romstage

Rizwan Qureshi (rizwan.qureshi@intel.com) gerrit at coreboot.org
Tue Aug 30 13:12:18 CEST 2016


Rizwan Qureshi (rizwan.qureshi at intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16315

-gerrit

commit 54769191bde6ecba0de471974f148b7f6de3b7d2
Author: Barnali Sarkar <barnali.sarkar at intel.com>
Date:   Wed Aug 24 20:48:46 2016 +0530

    skylake: Add FSP 2.0 support in romstage
    
    Set up stack and MTRRs after Dram initialization. This
    set up code is present in FSP1.1 driver, copy and reuse
    stack.c.
    
    Populate SoC related Memory related params.
    
    Make sure FSP_M binary is properly relocated to the base where
    it is placed in CBFS. i.e., make it XIP.
    
    TEST=Build and boot kunimitsu, dram initialization done.
    ramstage is loaded.
    
    Change-Id: I8d943e29b6e118986189166d92c7891ab6642193
    Signed-off-by: Rizwan Qureshi <rizwan.qureshi at intel.com>
---
 src/soc/intel/skylake/Makefile.inc                 |   2 +
 src/soc/intel/skylake/chip.h                       |   4 +
 src/soc/intel/skylake/include/fsp20/soc/romstage.h |   9 +-
 src/soc/intel/skylake/memmap.c                     |   1 +
 src/soc/intel/skylake/romstage/romstage_fsp20.c    |  83 +++++++++-
 src/soc/intel/skylake/stack.c                      | 168 +++++++++++++++++++++
 6 files changed, 260 insertions(+), 7 deletions(-)

diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc
index aa3da61..80562e4 100644
--- a/src/soc/intel/skylake/Makefile.inc
+++ b/src/soc/intel/skylake/Makefile.inc
@@ -42,6 +42,7 @@ romstage-y += pei_data.c
 romstage-y += pmutil.c
 romstage-$(CONFIG_PLATFORM_USES_FSP2_0) += reset.c
 romstage-y += smbus_common.c
+romstage-$(CONFIG_PLATFORM_USES_FSP2_0) += stack.c
 romstage-y += tsc_freq.c
 romstage-$(CONFIG_UART_DEBUG) += uart_debug.c
 
@@ -104,6 +105,7 @@ CPPFLAGS_common += -I$(src)/vendorcode/intel/fsp/fsp1_1/skylake
 else
 CPPFLAGS_common += -I$(src)/soc/intel/skylake/include/fsp20
 CPPFLAGS_common += -I$(src)/vendorcode/intel/fsp/fsp2_0/skykabylake
+$(CONFIG_FSP_M_CBFS)-options := --xip
 endif
 
 # Currently used for microcode path.
diff --git a/src/soc/intel/skylake/chip.h b/src/soc/intel/skylake/chip.h
index a4dee51..62e28e6 100644
--- a/src/soc/intel/skylake/chip.h
+++ b/src/soc/intel/skylake/chip.h
@@ -359,6 +359,10 @@ struct soc_intel_skylake_config {
 	 * 011b - VR specific command sent for both MPS IMPV8 & PS4 exit issue
 	*/
 	u8 SendVrMbxCmd;
+
+	/* Enable/Disable VMX feature */
+	u8 VmxEnable;
+
 	/* Statically clock gate 8254 PIT. */
 	u8 clock_gate_8254;
 
diff --git a/src/soc/intel/skylake/include/fsp20/soc/romstage.h b/src/soc/intel/skylake/include/fsp20/soc/romstage.h
index d48ac67..ce3c7b4 100644
--- a/src/soc/intel/skylake/include/fsp20/soc/romstage.h
+++ b/src/soc/intel/skylake/include/fsp20/soc/romstage.h
@@ -22,9 +22,16 @@
 
 asmlinkage void *car_stage_c_entry(void);
 void mainboard_memory_init_params(struct FSPM_UPD *mupd);
-
 void systemagent_early_init(void);
 int smbus_read_byte(unsigned device, unsigned address);
 int early_spi_read_wpsr(u8 *sr);
+void *setup_stack_and_mtrrs(void);
 
+/* Board type */
+enum board_type {
+	BOARD_TYPE_MOBILE	= 0,
+	BOARD_TYPE_DESKTOP	= 1,
+	BOARD_TYPE_ULT_ULX	= 5,
+	BOARD_TYPE_SERVER	= 7
+};
 #endif /* _SOC_ROMSTAGE_H_ */
diff --git a/src/soc/intel/skylake/memmap.c b/src/soc/intel/skylake/memmap.c
index 96debfd..6af1371 100644
--- a/src/soc/intel/skylake/memmap.c
+++ b/src/soc/intel/skylake/memmap.c
@@ -21,6 +21,7 @@
 #include <device/pci.h>
 #include <soc/msr.h>
 #include <soc/pci_devs.h>
+#include <soc/romstage.h>
 #include <soc/smm.h>
 #include <soc/systemagent.h>
 #include <stdlib.h>
diff --git a/src/soc/intel/skylake/romstage/romstage_fsp20.c b/src/soc/intel/skylake/romstage/romstage_fsp20.c
index 8a15a69..57b2a52 100644
--- a/src/soc/intel/skylake/romstage/romstage_fsp20.c
+++ b/src/soc/intel/skylake/romstage/romstage_fsp20.c
@@ -13,29 +13,100 @@
  * GNU General Public License for more details.
  */
 
+#include <arch/cpu.h>
+#include <arch/early_variables.h>
+#include <arch/io.h>
+#include <arch/symbols.h>
+#include <assert.h>
+#include <cpu/x86/mtrr.h>
+#include <cbmem.h>
+#include <chip.h>
 #include <console/console.h>
+#include <device/pci_def.h>
 #include <fsp/util.h>
+#include <soc/pci_devs.h>
+#include <soc/pm.h>
 #include <soc/romstage.h>
+#include <timestamp.h>
+#include <vboot/vboot_common.h>
 
 asmlinkage void *car_stage_c_entry(void)
 {
-	bool s3wake = false;
+	bool s3wake;
+	void *top_of_stack;
+	struct chipset_power_state *ps;
+
 	console_init();
-	/* TODO: Add fill_powerstate and determine sleep state. */
+
+	/* Program MCHBAR, DMIBAR, GDXBAR and EDRAMBAR */
+	systemagent_early_init();
+
+	ps = fill_power_state();
+	timestamp_add_now(TS_START_ROMSTAGE);
+	s3wake = ps->prev_sleep_state == ACPI_S3;
 	fsp_memory_init(s3wake);
-	return NULL;
+
+	top_of_stack = setup_stack_and_mtrrs();
+	return top_of_stack;
 }
+
 static void soc_memory_init_params(struct FSP_M_CONFIG *m_cfg)
 {
-	/* TODO: Fill SoC specific Memory init Params */
-}
+	const struct device *dev;
+	const struct soc_intel_skylake_config *config;
+	int i;
+	uint32_t mask = 0;
 
-void platform_fsp_memory_init_params_cb(struct FSPM_UPD *mupd){
+	/* Set the parameters for MemoryInit */
+	dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0));
+	config = dev->chip_info;
+	/*
+	 * Set IGD stolen size to 64MB.  The FBC hardware for skylake does not
+	 * have access to the bios_reserved range so it always assumes 8MB is
+	 * used and so the kernel will avoid the last 8MB of the stolen window.
+	 * With the default stolen size of 32MB(-8MB) there is not enough space
+	 * for FBC to work with a high resolution panel.
+	 */
+	m_cfg->IgdDvmt50PreAlloc = 2;
+	m_cfg->MmioSize = 0x800; /* 2GB in MB */
+	m_cfg->TsegSize = CONFIG_SMM_TSEG_SIZE;
+	m_cfg->IedSize = CONFIG_IED_REGION_SIZE;
+	m_cfg->ProbelessTrace = config->ProbelessTrace;
+	m_cfg->EnableTraceHub = config->EnableTraceHub;
+	if (vboot_recovery_mode_enabled())
+		m_cfg->SaGv = 0; /* Disable SaGv in recovery mode. */
+	else
+		m_cfg->SaGv = config->SaGv;
+	m_cfg->UserBd = BOARD_TYPE_ULT_ULX;
+	m_cfg->RMT = config->Rmt;
+	m_cfg->DdrFreqLimit = config->DdrFreqLimit;
+	m_cfg->VmxEnable = config->VmxEnable;
+	for (i = 0; i < ARRAY_SIZE(config->PcieRpEnable); i++) {
+		if (config->PcieRpEnable[i])
+			mask |= (1<<i);
+	}
+	m_cfg->PcieRpEnableMask = mask;
+}
 
+void platform_fsp_memory_init_params_cb(struct FSPM_UPD *mupd)
+{
 	struct FSP_M_CONFIG *m_cfg = &mupd->FspmConfig;
+	struct FSP_M_TEST_CONFIG *m_t_cfg = &mupd->FspmTestConfig;
 
 	soc_memory_init_params(m_cfg);
+
+	/* Enable DMI Virtual Channel for ME */
+	m_t_cfg->DmiVcm = 0x01;
+
+	/* Enable Sending DID to ME */
+	m_t_cfg->SendDidMsg = 0x01;
+	m_t_cfg->DidInitStat = 0x01;
+
 	mainboard_memory_init_params(mupd);
+
+	/* Reserve enough memory under TOLUD to save CBMEM header */
+	mupd->FspmArchUpd.BootLoaderTolumSize = cbmem_overhead_size();
+
 }
 
 __attribute__((weak)) void mainboard_memory_init_params(struct FSPM_UPD *mupd)
diff --git a/src/soc/intel/skylake/stack.c b/src/soc/intel/skylake/stack.c
new file mode 100644
index 0000000..4b934a1
--- /dev/null
+++ b/src/soc/intel/skylake/stack.c
@@ -0,0 +1,168 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <cbmem.h>
+#include <console/console.h>
+#include <cpu/x86/mtrr.h>
+#include <fsp/memmap.h>
+#include <soc/romstage.h>
+#include <stdlib.h>
+#include <program_loading.h>
+#include <soc/intel/common/util.h>
+
+static inline void *stack_push32(void *stack, uint32_t value)
+{
+	uint32_t *stack32 = stack;
+
+	stack32 = &stack32[-1];
+	*stack32 = value;
+	return stack32;
+}
+
+/*
+ * setup_stack_and_mtrrs() determines the stack to use after
+ * cache-as-ram is torn down as well as the MTRR settings to use.
+ */
+void *setup_stack_and_mtrrs(void)
+{
+	size_t alignment;
+	uint32_t aligned_ram;
+	uint32_t mtrr_mask_upper;
+	uint32_t max_mtrrs;
+	uint32_t num_mtrrs;
+	uint32_t *slot;
+	unsigned long top_of_stack;
+
+	/* Display the MTTRs */
+	soc_display_mtrrs();
+
+	/* Top of stack needs to be aligned to a 8-byte boundary. */
+	top_of_stack = romstage_ram_stack_top();
+	slot = (void *)top_of_stack;
+	num_mtrrs = 0;
+	max_mtrrs = soc_get_variable_mtrr_count(NULL);
+
+	/*
+	 * The upper bits of the MTRR mask need to set according to the number
+	 * of physical address bits.
+	 */
+	mtrr_mask_upper = (1 << ((cpuid_eax(0x80000008) & 0xff) - 32)) - 1;
+	alignment = mmap_region_granularity();
+	aligned_ram = ALIGN_DOWN(romstage_ram_stack_bottom(), alignment);
+
+	/*
+	 * The order for each MTRR is value then base with upper 32-bits of
+	 * each value coming before the lower 32-bits. The reasoning for
+	 * this ordering is to create a stack layout like the following:
+	 *
+	 *  +36: MTRR mask 1 63:32
+	 *  +32: MTRR mask 1 31:0
+	 *  +28: MTRR base 1 63:32
+	 *  +24: MTRR base 1 31:0
+	 *  +20: MTRR mask 0 63:32
+	 *  +16: MTRR mask 0 31:0
+	 *  +12: MTRR base 0 63:32
+	 *   +8: MTRR base 0 31:0
+	 *   +4: Number of MTRRs to setup (described above)
+	 *   +0: Number of variable MTRRs to clear
+	 */
+
+	/* Cache RAM as WB from 0 -> CACHE_TMP_RAMTOP. */
+	slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */
+	slot = stack_push32(slot, ~(CACHE_TMP_RAMTOP - 1) | MTRR_PHYS_MASK_VALID);
+	slot = stack_push32(slot, 0); /* upper base */
+	slot = stack_push32(slot, 0 | MTRR_TYPE_WRBACK);
+	num_mtrrs++;
+
+	/*
+	 *     +-------------------------+  Top of RAM (aligned)
+	 *     | System Management Mode  |
+	 *     |      code and data      |  Length: CONFIG_TSEG_SIZE
+	 *     |         (TSEG)          |
+	 *     +-------------------------+  SMM base (aligned)
+	 *     |                         |
+	 *     | Chipset Reserved Memory |  Length: Multiple of CONFIG_TSEG_SIZE
+	 *     |                         |
+	 *     +-------------------------+  top_of_ram (aligned)
+	 *     |                         |
+	 *     |       CBMEM Root        |
+	 *     |                         |
+	 *     +-------------------------+
+	 *     |                         |
+	 *     |   FSP Reserved Memory   |
+	 *     |                         |
+	 *     +-------------------------+
+	 *     |                         |
+	 *     |  Various CBMEM Entries  |
+	 *     |                         |
+	 *     +-------------------------+  top_of_stack (8 byte aligned)
+	 *     |                         |
+	 *     |   stack (CBMEM Entry)   |
+	 *     |                         |
+	 *     +-------------------------+
+	 */
+
+	/*
+	 * Cache the stack and the other CBMEM entries as well as part or all
+	 * of the FSP reserved memory region.
+	 */
+	slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */
+	slot = stack_push32(slot, ~(alignment - 1) | MTRR_PHYS_MASK_VALID);
+	slot = stack_push32(slot, 0); /* upper base */
+	slot = stack_push32(slot, aligned_ram | MTRR_TYPE_WRBACK);
+	num_mtrrs++;
+
+	if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) {
+		void *smm_base;
+		size_t smm_size;
+		uint32_t tseg_base;
+
+		/*
+		 * Cache the TSEG region at the top of ram. This region is not
+		 * restricted to SMM mode until SMM has been relocated. By setting
+		 * the region to cacheable it provides faster access when relocating
+		 * the SMM handler as well as using the TSEG region for other purposes.
+		 */
+		smm_region(&smm_base, &smm_size);
+		tseg_base = (uint32_t)smm_base;
+		slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */
+		slot = stack_push32(slot, ~(alignment - 1) | MTRR_PHYS_MASK_VALID);
+		slot = stack_push32(slot, 0); /* upper base */
+		slot = stack_push32(slot, tseg_base | MTRR_TYPE_WRBACK);
+		num_mtrrs++;
+	}
+	/* Cache the ROM as WP just below 4GiB. */
+	slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */
+	slot = stack_push32(slot, ~(CONFIG_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID);
+	slot = stack_push32(slot, 0); /* upper base */
+	slot = stack_push32(slot, ~(CONFIG_ROM_SIZE - 1) | MTRR_TYPE_WRPROT);
+	num_mtrrs++;
+
+	/* Validate the MTRR usage */
+	if (num_mtrrs > max_mtrrs) {
+		printk(BIOS_ERR, "MTRRs: max = %d, used = %d, available=%d",
+			max_mtrrs, num_mtrrs, max_mtrrs - num_mtrrs);
+		die("ERROR - MTRR use count incorrect!\n");
+	}
+
+	/*
+	 * Save the number of MTRRs to setup and clear.  Return the stack
+	 * location pointing to the number of MTRRs.
+	 */
+	slot = stack_push32(slot, num_mtrrs);
+	slot = stack_push32(slot, max_mtrrs);
+	return slot;
+}



More information about the coreboot-gerrit mailing list