[coreboot-gerrit] New patch to review for coreboot: Skylake: update cbmem_top

Aaron Durbin (adurbin@chromium.org) gerrit at coreboot.org
Fri Aug 14 16:07:57 CEST 2015


Aaron Durbin (adurbin at chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11239

-gerrit

commit 4418147cb971f41b512493e1c1fd854616d32aba
Author: Rizwan Qureshi <rizwan.qureshi at intel.com>
Date:   Thu Jul 23 17:40:32 2015 +0530

    Skylake: update cbmem_top
    
    cbmem_top was using  CHIPSET_RESERVED_MEM_BYTES to w/a unknown memory
    regions reserved by fsp for chipset use. With that being removed, the
    function needs to properly walk though the memory map resulted from fsp
    memory init to find out the usable address for cbmem root.
    Refer the FSP 1.3.0 Integartion guide for more details on the Memory
    Map.
    
    systemagent should also use the same mechanism to create the reserved
    RAM resource.
    
    BRANCH=None
    BUG=None
    TEST=Build and Boot kunimitsu (FAB3)
    CQ-DEPEND=CL:*226035,CL:*226045,CL:291573
    
    Original-Change-Id: Id0954cf8e6388e549c7d4df67b468572b5bea539
    Original-Signed-off-by: Rizwan Qureshi <rizwan.qureshi at intel.com>
    Original-Reviewed-on: https://chromium-review.googlesource.com/291611
    Original-Tested-by: Wenkai Du <wenkai.du at intel.com>
    Original-Reviewed-by: Aaron Durbin <adurbin at chromium.org>
    Original-Commit-Queue: Robbie Zhang <robbie.zhang at intel.com>
    
    Change-Id: I4e716170f40936081ce9d4878bf74c75f469f78d
    Signed-off-by: Rizwan Qureshi <rizwan.qureshi at intel.com>
---
 src/soc/intel/skylake/include/soc/msr.h         |  4 +-
 src/soc/intel/skylake/include/soc/systemagent.h |  6 ++
 src/soc/intel/skylake/memmap.c                  | 86 ++++++++++++++++++++-----
 src/soc/intel/skylake/smmrelocate.c             |  4 +-
 src/soc/intel/skylake/systemagent.c             | 45 ++++---------
 5 files changed, 94 insertions(+), 51 deletions(-)

diff --git a/src/soc/intel/skylake/include/soc/msr.h b/src/soc/intel/skylake/include/soc/msr.h
index 3903757..4239b36 100644
--- a/src/soc/intel/skylake/include/soc/msr.h
+++ b/src/soc/intel/skylake/include/soc/msr.h
@@ -54,8 +54,8 @@
 #define IA32_PLATFORM_DCA_CAP		0x1f8
 #define MSR_POWER_CTL			0x1fc
 #define MSR_LT_LOCK_MEMORY		0x2e7
-#define UNCORE_EMRR_PHYS_BASE_MSR	0x2f4
-#define UNCORE_EMRR_PHYS_MASK_MSR	0x2f5
+#define UNCORE_PRMRR_PHYS_BASE_MSR	0x2f4
+#define UNCORE_PRMRR_PHYS_MASK_MSR	0x2f5
 #define IA32_MC0_STATUS			0x401
 #define SMM_FEATURE_CONTROL_MSR		0x4e0
 #define  SMM_CPU_SAVE_EN		(1 << 1)
diff --git a/src/soc/intel/skylake/include/soc/systemagent.h b/src/soc/intel/skylake/include/soc/systemagent.h
index 6bb5c66..59221c7 100644
--- a/src/soc/intel/skylake/include/soc/systemagent.h
+++ b/src/soc/intel/skylake/include/soc/systemagent.h
@@ -120,7 +120,13 @@
 /* Data is passed through bits 31:0 of the data register. */
 #define BIOS_MAILBOX_DATA			0x5da0
 
+/* CPU Trace reserved memory size */
+#define TRACE_MEMORY_SIZE	0x8000000	/* 128MiB */
+
 /* System Agent identification */
 u8 systemagent_revision(void);
 
+/* Top of 32bit usable memory */
+u32 top_of_32bit_ram(void);
+
 #endif
diff --git a/src/soc/intel/skylake/memmap.c b/src/soc/intel/skylake/memmap.c
index 494b259..0dc46a9 100644
--- a/src/soc/intel/skylake/memmap.c
+++ b/src/soc/intel/skylake/memmap.c
@@ -20,7 +20,11 @@
 
 #include <arch/io.h>
 #include <cbmem.h>
+#include <chip.h>
+#include <console/console.h>
+#include <device/device.h>
 #include <device/pci.h>
+#include <soc/msr.h>
 #include <soc/pci_devs.h>
 #include <soc/romstage.h>
 #include <soc/smm.h>
@@ -108,6 +112,71 @@ int smm_subregion(int sub, void **start, size_t *size)
 	return 0;
 }
 
+/*
+ * Host Memory Map:
+ *
+ * +--------------------------+ TOUUD
+ * |                          |
+ * +--------------------------+ 4GiB
+ * |     PCI Address Space    |
+ * +--------------------------+ TOLUD (also maps into MC address space)
+ * |     iGD                  |
+ * +--------------------------+ BDSM
+ * |     GTT                  |
+ * +--------------------------+ BGSM
+ * |     TSEG                 |
+ * +--------------------------+ TSEGMB
+ * |   DMA Protected Region   |
+ * +--------------------------+ DPR
+ * |    PRM (C6DRAM/SGX)      |
+ * +--------------------------+ PRMRR
+ * |     Trace Memory         |
+ * +--------------------------+ top_of_ram
+ * |     Reserved - FSP/CBMEM |
+ * +--------------------------+ TOLUM
+ * |     Usage DRAM           |
+ * +--------------------------+ 0
+ *
+ * Some of the base registers above can be equal making the size of those
+ * regions 0. The reason is because the memory controller internally subtracts
+ * the base registers from each other to determine sizes of the regions. In
+ * other words, the memory map is in a fixed order no matter what.
+ */
+
+u32 top_of_32bit_ram(void)
+{
+	msr_t prmrr_base;
+	u32 top_of_ram;
+	const struct device *dev;
+	const struct soc_intel_skylake_config *config;
+
+	/*
+	 * Check if Tseg has been initialized, we will use this as a flag
+	 * to check if the MRC is done, and only then continue to read the
+	 * PRMMR_BASE MSR. The system hangs if PRMRR_BASE MSR is read before
+	 * PRMRR_MASK MSR lock bit is set.
+	 */
+	if (smm_region_start() == 0)
+		return 0;
+
+	dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_ROOT, 0));
+	config = dev->chip_info;
+
+	/*
+	 * On Skylake, cbmem_top is offset down from PRMRR_BASE by reserved
+	 * memory (128MiB) for CPU trace if enabled, then reserved memory (4KB)
+	 * for PTT if enabled. PTT is in fact not used on Skylake platforms.
+	 * Refer to Fsp Integration Guide for the memory mapping layout.
+	 */
+	prmrr_base = rdmsr(UNCORE_PRMRR_PHYS_BASE_MSR);
+	top_of_ram = prmrr_base.lo;
+
+	if (config->ProbelessTrace)
+		top_of_ram -= TRACE_MEMORY_SIZE;
+
+	return top_of_ram;
+}
+
 void *cbmem_top(void)
 {
 	/*
@@ -117,7 +186,7 @@ void *cbmem_top(void)
 	 *     |         (TSEG)          |
 	 *     +-------------------------+  SMM base (aligned)
 	 *     |                         |
-	 *     | Chipset Reserved Memory |  Length: Multiple of CONFIG_TSEG_SIZE
+	 *     | Chipset Reserved Memory |
 	 *     |                         |
 	 *     +-------------------------+  top_of_ram (aligned)
 	 *     |                         |
@@ -137,19 +206,6 @@ void *cbmem_top(void)
 	 *     |                         |
 	 *     +-------------------------+
 	 */
-
-	uintptr_t top_of_ram = smm_region_start();
-
-	/*
-	 * Subtract DMA Protected Range size if enabled and align to a multiple
-	 * of TSEG size.
-	 */
-	u32 dpr = pci_read_config32(SA_DEV_ROOT, DPR);
-	if (dpr & DPR_EPM) {
-		top_of_ram -= (dpr & DPR_SIZE_MASK) << 16;
-		top_of_ram = ALIGN_DOWN(top_of_ram, mmap_region_granluarity());
-	}
-
-	return (void *)top_of_ram;
+	return (void *)top_of_32bit_ram();
 }
 
diff --git a/src/soc/intel/skylake/smmrelocate.c b/src/soc/intel/skylake/smmrelocate.c
index 2f75c2e..4b6f1c4 100644
--- a/src/soc/intel/skylake/smmrelocate.c
+++ b/src/soc/intel/skylake/smmrelocate.c
@@ -54,8 +54,8 @@ static inline void write_uncore_emrr(struct smm_relocation_params *relo_params)
 	       "Writing UNCORE_EMRR. base = 0x%08x, mask=0x%08x\n",
 	       relo_params->uncore_emrr_base.lo,
 	       relo_params->uncore_emrr_mask.lo);
-	wrmsr(UNCORE_EMRR_PHYS_BASE_MSR, relo_params->uncore_emrr_base);
-	wrmsr(UNCORE_EMRR_PHYS_MASK_MSR, relo_params->uncore_emrr_mask);
+	wrmsr(UNCORE_PRMRR_PHYS_BASE_MSR, relo_params->uncore_emrr_base);
+	wrmsr(UNCORE_PRMRR_PHYS_MASK_MSR, relo_params->uncore_emrr_mask);
 }
 
 static void update_save_state(int cpu,
diff --git a/src/soc/intel/skylake/systemagent.c b/src/soc/intel/skylake/systemagent.c
index a1bcfdc..1fe3304 100644
--- a/src/soc/intel/skylake/systemagent.c
+++ b/src/soc/intel/skylake/systemagent.c
@@ -163,33 +163,6 @@ static void mc_add_fixed_mmio_resources(device_t dev)
 	}
 }
 
-/*
- * Host Memory Map:
- *
- * +--------------------------+ TOUUD
- * |                          |
- * +--------------------------+ 4GiB
- * |     PCI Address Space    |
- * +--------------------------+ TOLUD (also maps into MC address space)
- * |     iGD                  |
- * +--------------------------+ BDSM
- * |     GTT                  |
- * +--------------------------+ BGSM
- * |     TSEG                 |
- * +--------------------------+ TSEGMB
- * |   DMA Protected Region   |
- * +--------------------------+ DPR
- * |     Reserved - FSP       |
- * +--------------------------+ RSVFSP
- * |     Usage DRAM           |
- * +--------------------------+ 0
- *
- * Some of the base registers above can be equal making the size of those
- * regions 0. The reason is because the memory controller internally subtracts
- * the base registers from each other to determine sizes of the regions. In
- * other words, the memory map is in a fixed order no matter what.
- */
-
 struct map_entry {
 	int reg;
 	int is_64_bit;
@@ -313,8 +286,9 @@ static void mc_add_dram_resources(device_t dev)
 	/*
 	 * These are the host memory ranges that should be added:
 	 * - 0 -> 0xa0000: cacheable
-	 * - 0xc0000 -> TSEG : cacheable
-	 * - TESG -> BGSM: cacheable with standard MTRRs and reserved
+	 * - 0xc0000 -> top_of_ram : cacheable
+	 * - top_of_ram -> TSEG - DPR: uncacheable
+	 * - TESG - DPR -> BGSM: cacheable with standard MTRRs and reserved
 	 * - BGSM -> TOLUD: not cacheable with standard MTRRs and reserved
 	 * - 4GiB -> TOUUD: cacheable
 	 *
@@ -347,12 +321,19 @@ static void mc_add_dram_resources(device_t dev)
 	size_k = (0xa0000 >> 10) - base_k;
 	ram_resource(dev, index++, base_k, size_k);
 
-	/* 0xc0000 -> TSEG - DPR */
+	/* 0xc0000 -> top_of_ram */
 	base_k = 0xc0000 >> 10;
-	size_k = (unsigned long)(mc_values[TSEG_REG] >> 10) - base_k;
-	size_k -= dpr_size >> 10;
+	size_k = (top_of_32bit_ram() >> 10) - base_k;
 	ram_resource(dev, index++, base_k, size_k);
 
+	/* top_of_ram -> TSEG - DPR */
+	resource = new_resource(dev, index++);
+	resource->base = top_of_32bit_ram();
+	resource->size = mc_values[TSEG_REG] - dpr_size - resource->base;
+	resource->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+			  IORESOURCE_STORED | IORESOURCE_RESERVE |
+			  IORESOURCE_ASSIGNED;
+
 	/* TSEG - DPR -> BGSM */
 	resource = new_resource(dev, index++);
 	resource->base = mc_values[TSEG_REG] - dpr_size;



More information about the coreboot-gerrit mailing list