diff options
-rw-r--r-- | src/soc/intel/cannonlake/include/soc/iomap.h | 5 | ||||
-rw-r--r-- | src/soc/intel/cannonlake/include/soc/systemagent.h | 3 | ||||
-rw-r--r-- | src/soc/intel/cannonlake/memmap.c | 112 |
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); } |