diff options
Diffstat (limited to 'src/soc/intel')
-rw-r--r-- | src/soc/intel/skylake/include/soc/msr.h | 4 | ||||
-rw-r--r-- | src/soc/intel/skylake/include/soc/systemagent.h | 6 | ||||
-rw-r--r-- | src/soc/intel/skylake/memmap.c | 86 | ||||
-rw-r--r-- | src/soc/intel/skylake/smmrelocate.c | 4 | ||||
-rw-r--r-- | 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 390375703e..4239b36996 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 6bb5c66d2a..59221c7754 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 494b259455..0dc46a9c8c 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 2f75c2eebf..4b6f1c4b60 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 a1bcfdcf71..1fe330480e 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; |