[coreboot-gerrit] Change in coreboot[master]: soc/intel/cannonlake: Usable dram top calculation based on HW registers

Subrata Banik (Code Review) gerrit at coreboot.org
Mon Aug 28 14:45:28 CEST 2017


Subrata Banik has uploaded this change for review. ( https://review.coreboot.org/21235


Change subject: soc/intel/cannonlake: Usable dram top calculation based on HW registers
......................................................................

soc/intel/cannonlake: Usable dram top calculation based on HW registers

This patch ensures that entire system memory calculation is done
based on host bridge registers.

BRANCH=none
BUG=b:63974384
TEST=Build and boot cannonlake RVP successfully with below configurations
1. Booting to OS with no UPD change
2. Enable ProbelessTrace UPD and boot to OS.
3. Enable PRMRR with size 1MB and boot to OS.
4. Enable PRMRR with size 32MB and boot to OS.
5. Enable PRMRR with size 2MB and unable to boot to OS due to
unsupported PRMRR size.
6. Enable C6 DRAM with PRMRR size 0MB and boot to OS.

Change-Id: I0a430a24f52cdf6e2517a49910b77ab08a199ca2
Signed-off-by: Subrata Banik <subrata.banik at intel.com>
---
M src/soc/intel/cannonlake/chip.h
M src/soc/intel/cannonlake/include/soc/systemagent.h
M src/soc/intel/cannonlake/memmap.c
3 files changed, 99 insertions(+), 4 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/35/21235/1

diff --git a/src/soc/intel/cannonlake/chip.h b/src/soc/intel/cannonlake/chip.h
index 48305fe..9b50846 100644
--- a/src/soc/intel/cannonlake/chip.h
+++ b/src/soc/intel/cannonlake/chip.h
@@ -186,6 +186,8 @@
 
 	/* Enable/Disable EIST. 1b:Enabled, 0b:Disabled */
 	uint8_t eist_enable;
+	/* Enable C6 DRAM */
+	uint8_t enable_c6dram;
 };
 
 typedef struct soc_intel_cannonlake_config config_t;
diff --git a/src/soc/intel/cannonlake/include/soc/systemagent.h b/src/soc/intel/cannonlake/include/soc/systemagent.h
index 1902314..da83c38 100644
--- a/src/soc/intel/cannonlake/include/soc/systemagent.h
+++ b/src/soc/intel/cannonlake/include/soc/systemagent.h
@@ -40,4 +40,7 @@
 #define MCH_DDR_POWER_LIMIT_LO	0x58e0
 #define MCH_DDR_POWER_LIMIT_HI	0x58e4
 
+#define IMRBASE			0x6A40
+#define IMRLIMIT		0x6A48
+
 #endif
diff --git a/src/soc/intel/cannonlake/memmap.c b/src/soc/intel/cannonlake/memmap.c
index 8b487f6..1b6e6da 100644
--- a/src/soc/intel/cannonlake/memmap.c
+++ b/src/soc/intel/cannonlake/memmap.c
@@ -34,15 +34,105 @@
 	write32(top_of_ram_register(), 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
+ * |     ME Stolen Memory     |
+ * +--------------------------+ ME Stolen
+ * |     PTT                  |
+ * +--------------------------+ 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.
+ */
+static u32 calculate_dram_base(void)
+{
+	const struct soc_intel_cannonlake_config *config;
+	const struct device *dev;
+	uint32_t dram_base;
+	uint32_t prmrr_base;
+	size_t prmrr_size;
+	size_t imr_size;
+
+	dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_IGD, 0));
+
+	/* Read TOLUD from Host Bridge offset */
+	dram_base = sa_get_tolud_base();
+
+	if (dev->enabled) {
+		/* Read BDSM from Host Bridge */
+		dram_base -= sa_get_dsm_size();
+
+		/* Read BGSM from Host Bridge */
+		dram_base -= sa_get_gsm_size();
+	}
+	/* Get TSEG size */
+	dram_base -= smm_region_size();
+
+	/* Get DPR size */
+	if (IS_ENABLED(CONFIG_SA_ENABLE_DPR))
+		dram_base -= sa_get_dpr_size();
+
+	dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_ROOT, 0));
+	config = dev->chip_info;
+	prmrr_size = config->PrmrrSize;
+
+	if (prmrr_size > 0) {
+		/*
+		 * PRMRR Sizes that are > 1MB and < 32MB are
+		 * not supported and will fail out.
+		 */
+		if ((prmrr_size > 1*MiB) && (prmrr_size < 32*MiB))
+			die("PRMRR Sizes that are > 1MB and < 32MB are not"
+					"supported!\n");
+
+		prmrr_base = dram_base - prmrr_size;
+		if (prmrr_size >= 32*MiB)
+			prmrr_base = ALIGN_DOWN(prmrr_base, 128*MiB);
+		dram_base = prmrr_base;
+	} else if (config->enable_c6dram && prmrr_size == 0) {
+		/* Allocate PRMRR memory for C6DRAM */
+		dram_base -= 1*MiB;
+	}
+
+	/* ME stolen memory */
+	imr_size = MCHBAR32(IMRLIMIT) - MCHBAR32(IMRBASE);
+	if (imr_size > 0)
+		dram_base -= imr_size;
+
+	if (is_ptt_enable())
+		dram_base -= 4*KiB; /* Allocate 4KB for PTT if enable */
+
+	return dram_base;
+}
+
 void cbmem_top_init(void)
 {
-	struct range_entry fsp_mem;
 	uintptr_t top;
 
-	if (fsp_find_reserved_memory(&fsp_mem))
-		die("Can't file top of ram.\n");
+	top = calculate_dram_base();
 
-	top = ALIGN_UP(range_entry_base(&fsp_mem), 16 * MiB);
 	write32(top_of_ram_register(), top);
 }
 

-- 
To view, visit https://review.coreboot.org/21235
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0a430a24f52cdf6e2517a49910b77ab08a199ca2
Gerrit-Change-Number: 21235
Gerrit-PatchSet: 1
Gerrit-Owner: Subrata Banik <subrata.banik at intel.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20170828/76ad43d2/attachment-0001.html>


More information about the coreboot-gerrit mailing list