summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubrata Banik <subrata.banik@intel.com>2017-08-30 18:29:33 +0530
committerSubrata Banik <subrata.banik@intel.com>2017-09-01 02:55:45 +0000
commita281c0f1bf7b6b84c4e1f7739c52044299ae0be5 (patch)
treef1c7467908bdab3da7fd1f945f3790b9fc726746
parentce90c78d7f27e41275deb36b5dea2787ffced8bf (diff)
soc/intel/cannonlake: Perform 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@intel.com> Reviewed-on: https://review.coreboot.org/21235 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r--src/soc/intel/cannonlake/include/soc/iomap.h5
-rw-r--r--src/soc/intel/cannonlake/include/soc/systemagent.h3
-rw-r--r--src/soc/intel/cannonlake/memmap.c112
3 files changed, 114 insertions, 6 deletions
diff --git a/src/soc/intel/cannonlake/include/soc/iomap.h b/src/soc/intel/cannonlake/include/soc/iomap.h
index 82c57bc56b..698c51028b 100644
--- a/src/soc/intel/cannonlake/include/soc/iomap.h
+++ b/src/soc/intel/cannonlake/include/soc/iomap.h
@@ -65,8 +65,9 @@
#define HECI1_BASE_ADDRESS 0xFEDA2000
-/* CPU Trace reserved memory size */
-#define TRACE_MEMORY_SIZE 0x8000000 /* 128MiB */
+/* PTT registers */
+#define PTT_TXT_BASE_ADDRESS 0xfed30800
+#define PTT_PRESENT 0x00070000
/*
* I/O port address space
diff --git a/src/soc/intel/cannonlake/include/soc/systemagent.h b/src/soc/intel/cannonlake/include/soc/systemagent.h
index 1902314482..da83c381a0 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 8b487f6b83..8f842c0c5c 100644
--- a/src/soc/intel/cannonlake/memmap.c
+++ b/src/soc/intel/cannonlake/memmap.c
@@ -15,10 +15,16 @@
*/
#include <arch/io.h>
#include <cbmem.h>
+#include <chip.h>
#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
#include <fsp/util.h>
+#include <intelblocks/systemagent.h>
#include <soc/bootblock.h>
+#include <soc/pci_devs.h>
#include <soc/systemagent.h>
+#include <stdlib.h>
static void *top_of_ram_register(void)
{
@@ -34,15 +40,113 @@ void clear_cbmem_top(void)
write32(top_of_ram_register(), 0);
}
+static bool is_ptt_enable(void)
+{
+ if ((read32((void *)PTT_TXT_BASE_ADDRESS) & PTT_PRESENT) ==
+ PTT_PRESENT)
+ return true;
+
+ return false;
+}
+
+/*
+ * 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 uintptr_t calculate_dram_base(void)
+{
+ const struct soc_intel_cannonlake_config *config;
+ const struct device *dev;
+ uintptr_t dram_base;
+ uintptr_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 -= sa_get_tseg_size();
+
+ /* Get DPR size */
+ if (IS_ENABLED(CONFIG_SA_ENABLE_DPR))
+ dram_base -= sa_get_dpr_size();
+
+ 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);
}