summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
}