soc/intel: skl,cnl,icl: rely on TOLUM as cbmem_top returned by FSP

Instead of doing our own calculations, rely on TOLUM returned by FSP
for cbmem_top. This (hopefully) saves us from making mistakes in weird
calculations of offsets and alignments.

Further this makes it easier to implement e.g. SGX PRMRR size selection
via Kconfig as we do not have to make any assumptions about alignments
but can simply pass (valid) values to FSP.

Tested successfully on X11SSM-F

Change-Id: If66a00d1320917bc68afb32c19db0e24c6732812
Signed-off-by: Michael Niewöhner <foss@mniewoehner.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/36136
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Michael Niewöhner 2019-10-19 11:57:05 +02:00 committed by Nico Huber
parent 1644e48985
commit 68da45479f
10 changed files with 33 additions and 547 deletions

View File

@ -300,3 +300,9 @@ const void *fsp_find_nv_storage_data(size_t *size)
{
return fsp_find_extension_hob_by_guid(fsp_nv_storage_guid, size);
}
void fsp_find_bootloader_tolum(struct range_entry *re)
{
if (fsp_find_range_hob(re, fsp_bootloader_tolum_guid))
die("9.3: FSP_BOOTLOADER_TOLUM_HOB missing!\n");
}

View File

@ -16,12 +16,6 @@
#include <console/console.h>
#include <fsp/util.h>
void fsp_find_bootloader_tolum(struct range_entry *re)
{
if (fsp_find_range_hob(re, fsp_bootloader_tolum_guid))
die("9.3: FSP_BOOTLOADER_TOLUM_HOB missing!\n");
}
void fsp_verify_memory_init_hobs(void)
{
struct range_entry fsp_mem;

View File

@ -19,9 +19,8 @@
#include <stdint.h>
struct ebda_config {
uint32_t signature; /* 0x00 - EBDA signature */
uint32_t tolum_base; /* 0x04 - coreboot memory start */
uint32_t reserved_mem_size; /* 0x08 - chipset reserved memory size */
uint32_t signature; /* EBDA signature */
uint32_t cbmem_top; /* coreboot memory start */
};
#endif

View File

@ -15,141 +15,15 @@
*/
#include <arch/romstage.h>
#include <arch/ebda.h>
#include <cbmem.h>
#include <console/console.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/smm.h>
#include <device/device.h>
#include <device/pci.h>
#include <fsp/util.h>
#include <intelblocks/ebda.h>
#include <intelblocks/systemagent.h>
#include <soc/pci_devs.h>
#include <soc/systemagent.h>
#include <stdlib.h>
#include "chip.h"
static bool is_ptt_enable(void)
{
if ((read32((void *)PTT_TXT_BASE_ADDRESS) & PTT_PRESENT) ==
PTT_PRESENT)
return true;
return false;
}
/* Calculate PTT size */
static size_t get_ptt_size(void)
{
/* Allocate 4KB for PTT if enabled */
return is_ptt_enable() ? 4*KiB : 0;
}
/* Calculate ME Stolen size */
static size_t get_imr_size(void)
{
size_t imr_size;
/* ME stolen memory */
imr_size = MCHBAR32(IMRLIMIT) - MCHBAR32(IMRBASE);
return imr_size;
}
/* Calculate PRMRR size based on user input PRMRR size and alignment */
static size_t get_prmrr_size(uintptr_t dram_base,
const struct soc_intel_cannonlake_config *config)
{
uintptr_t prmrr_base = dram_base;
size_t prmrr_size;
prmrr_size = config->PrmrrSize;
/* Allocate PRMRR memory for C6DRAM */
if (!prmrr_size) {
if (config->enable_c6dram)
prmrr_size = 1*MiB;
else
return 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 -= prmrr_size;
if (prmrr_size >= 32*MiB)
prmrr_base = ALIGN_DOWN(prmrr_base, 128*MiB);
else
prmrr_base = ALIGN_DOWN(prmrr_base, 16*MiB);
/* PRMRR Area Size */
prmrr_size = dram_base - prmrr_base;
return prmrr_size;
}
/* Calculate Intel Traditional Memory size based on GSM, DSM, TSEG and DPR. */
static size_t calculate_traditional_mem_size(uintptr_t dram_base,
const struct device *dev)
{
uintptr_t traditional_mem_base = dram_base;
size_t traditional_mem_size;
if (dev->enabled) {
/* Read BDSM from Host Bridge */
traditional_mem_base -= sa_get_dsm_size();
/* Read BGSM from Host Bridge */
traditional_mem_base -= sa_get_gsm_size();
}
/* Get TSEG size */
traditional_mem_base -= sa_get_tseg_size();
/* Get DPR size */
if (CONFIG(SA_ENABLE_DPR))
traditional_mem_base -= sa_get_dpr_size();
/* Traditional Area Size */
traditional_mem_size = dram_base - traditional_mem_base;
return traditional_mem_size;
}
/*
* Calculate Intel Reserved Memory size based on
* PRMRR size, Me stolen memory and PTT selection.
*/
static size_t calculate_reserved_mem_size(uintptr_t dram_base,
const struct device *dev)
{
uintptr_t reserve_mem_base = dram_base;
size_t reserve_mem_size;
const struct soc_intel_cannonlake_config *config;
config = config_of(dev);
/* Get PRMRR size */
reserve_mem_base -= get_prmrr_size(reserve_mem_base, config);
/* Get Tracehub size */
reserve_mem_base -= get_imr_size();
/* Get PTT size */
reserve_mem_base -= get_ptt_size();
/* Traditional Area Size */
reserve_mem_size = dram_base - reserve_mem_base;
return reserve_mem_size;
}
/*
* Fill up memory layout information
*
* Host Memory Map:
*
* +--------------------------+ TOUUD
@ -181,37 +55,12 @@ static size_t calculate_reserved_mem_size(uintptr_t dram_base,
* 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(size_t *reserved_mem_size)
{
uintptr_t dram_base;
const struct device *dev;
dev = pcidev_on_root(SA_DEV_SLOT_IGD, 0);
if (!dev)
die_with_post_code(POST_HW_INIT_FAILURE,
"ERROR - IGD device not found!");
/* Read TOLUD from Host Bridge offset */
dram_base = sa_get_tolud_base();
/* Get Intel Traditional Memory Range Size */
dram_base -= calculate_traditional_mem_size(dram_base, dev);
/* Get Intel Reserved Memory Range Size */
*reserved_mem_size = calculate_reserved_mem_size(dram_base, dev);
dram_base -= *reserved_mem_size;
return dram_base;
}
/* Fill up memory layout information */
void fill_soc_memmap_ebda(struct ebda_config *cfg)
{
size_t chipset_mem_size;
struct range_entry tolum;
cfg->tolum_base = calculate_dram_base(&chipset_mem_size);
cfg->reserved_mem_size = chipset_mem_size;
fsp_find_bootloader_tolum(&tolum);
cfg->cbmem_top = range_entry_end(&tolum);
}
void cbmem_top_init(void)
@ -253,5 +102,5 @@ void *cbmem_top_chipset(void)
retrieve_ebda_object(&ebda_cfg);
return (void *)(uintptr_t)ebda_cfg.tolum_base;
return (void *)(uintptr_t)ebda_cfg.cbmem_top;
}

View File

@ -76,18 +76,12 @@ void enable_pam_region(void);
void enable_power_aware_intr(void);
/* API to get TOLUD base address */
uintptr_t sa_get_tolud_base(void);
/* API to get DSM size */
size_t sa_get_dsm_size(void);
/* API to get GSM base address */
uintptr_t sa_get_gsm_base(void);
/* API to get GSM size */
size_t sa_get_gsm_size(void);
/* API to get TSEG base address */
uintptr_t sa_get_tseg_base(void);
/* API to get TSEG size */
size_t sa_get_tseg_size(void);
/* API to get DPR size */
size_t sa_get_dpr_size(void);
/*
* SoC overrides
*

View File

@ -139,63 +139,12 @@ uintptr_t sa_get_tolud_base(void)
return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, TOLUD), 1*MiB);
}
static uint16_t sa_get_ggc_reg(void)
{
return pci_read_config16(SA_DEV_ROOT, GGC);
}
/*
* Internal Graphics Pre-allocated Memory - As per Intel FSP UPD Header
* definition, size of memory preallocatred for internal graphics can be
* configured based on below lists:
*
* 0x00:0MB, 0x01:32MB, 0x02:64MB, 0x03:96MB, 0x04:128MB, 0x05:160MB,
* 0xF0:4MB, 0xF1:8MB, 0xF2:12MB, 0xF3:16MB, 0xF4:20MB, 0xF5:24MB, 0xF6:28MB,
* 0xF7:32MB, 0xF8:36MB, 0xF9:40MB, 0xFA:44MB, 0xFB:48MB, 0xFC:52MB, 0xFD:56MB,
* 0xFE:60MB
*
* Today all existing SoCs(except Cannonlake) are supported under intel
* common code block design may not need to use any other values than 0x0-0x05
* for GFX DSM range. DSM memory ranges between 0xF0-0xF6 are majorly for
* early SoC samples and validation requirement. This code block to justify
* all differnet possible ranges that FSP may support for a platform.
*/
size_t sa_get_dsm_size(void)
{
uint32_t prealloc_memory;
uint16_t ggc;
ggc = sa_get_ggc_reg();
prealloc_memory = (ggc & G_GMS_MASK) >> G_GMS_OFFSET;
if (prealloc_memory < 0xF0)
return prealloc_memory * 32*MiB;
else
return (prealloc_memory - 0xEF) * 4*MiB;
}
uintptr_t sa_get_gsm_base(void)
{
/* All regions concerned for have 1 MiB alignment. */
return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, BGSM), 1*MiB);
}
size_t sa_get_gsm_size(void)
{
uint8_t ggms;
ggms = (sa_get_ggc_reg() & G_GGMS_MASK) >> G_GGMS_OFFSET;
/*
* Size of GSM: 0x0: No Preallocated Memory 0x1: 2MB Memory
* 0x2: 4MB Memory 0x3: 8MB Memory
*/
if (ggms)
return 1*MiB << ggms;
else
return 0;
}
uintptr_t sa_get_tseg_base(void)
{
/* All regions concerned for have 1 MiB alignment. */
@ -206,23 +155,3 @@ size_t sa_get_tseg_size(void)
{
return sa_get_gsm_base() - sa_get_tseg_base();
}
/*
* Get DPR size in case CONFIG_SA_ENABLE_DPR is selected by SoC.
*/
size_t sa_get_dpr_size(void)
{
uintptr_t dpr_reg;
size_t size = 0;
/*
* DMA Protected Range can be reserved below TSEG for PCODE patch
* or TXT/BootGuard related data. Rather than report a base address
* the DPR register reports the TOP of the region, which is the same
* as TSEG base. The region size is reported in MiB in bits 11:4.
*/
dpr_reg = pci_read_config32(SA_DEV_ROOT, DPR);
if (dpr_reg & DPR_EPM)
size = (dpr_reg & DPR_SIZE_MASK) << 16;
return size;
}

View File

@ -19,9 +19,8 @@
#include <stdint.h>
struct ebda_config {
uint32_t signature; /* 0x00 - EBDA signature */
uint32_t tolum_base; /* 0x04 - coreboot memory start */
uint32_t reserved_mem_size; /* 0x08 - chipset reserved memory size */
uint32_t signature; /* EBDA signature */
uint32_t cbmem_top; /* coreboot memory start */
};
#endif

View File

@ -14,121 +14,15 @@
*/
#include <arch/romstage.h>
#include <arch/ebda.h>
#include <cbmem.h>
#include <console/console.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/smm.h>
#include <device/device.h>
#include <device/pci.h>
#include <fsp/util.h>
#include <intelblocks/ebda.h>
#include <intelblocks/systemagent.h>
#include <soc/pci_devs.h>
#include <soc/soc_chip.h>
#include <soc/systemagent.h>
#include <stdlib.h>
/* Calculate ME Stolen size */
static size_t get_imr_size(void)
{
size_t imr_size;
/* ME stolen memory */
imr_size = MCHBAR32(IMRLIMIT) - MCHBAR32(IMRBASE);
return imr_size;
}
/* Calculate PRMRR size based on user input PRMRR size and alignment */
static size_t get_prmrr_size(uintptr_t dram_base,
const struct soc_intel_icelake_config *config)
{
uintptr_t prmrr_base = dram_base;
size_t prmrr_size;
prmrr_size = config->PrmrrSize;
/* Allocate PRMRR memory for C6DRAM */
if (!prmrr_size) {
if (config->enable_c6dram)
prmrr_size = 1*MiB;
else
return 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 -= prmrr_size;
if (prmrr_size >= 32*MiB)
prmrr_base = ALIGN_DOWN(prmrr_base, 128*MiB);
else
prmrr_base = ALIGN_DOWN(prmrr_base, 16*MiB);
/* PRMRR Area Size */
prmrr_size = dram_base - prmrr_base;
return prmrr_size;
}
/* Calculate Intel Traditional Memory size based on GSM, DSM, TSEG and DPR. */
static size_t calculate_traditional_mem_size(uintptr_t dram_base,
const struct device *dev)
{
uintptr_t traditional_mem_base = dram_base;
size_t traditional_mem_size;
if (dev->enabled) {
/* Read BDSM from Host Bridge */
traditional_mem_base -= sa_get_dsm_size();
/* Read BGSM from Host Bridge */
traditional_mem_base -= sa_get_gsm_size();
}
/* Get TSEG size */
traditional_mem_base -= sa_get_tseg_size();
/* Get DPR size */
if (CONFIG(SA_ENABLE_DPR))
traditional_mem_base -= sa_get_dpr_size();
/* Traditional Area Size */
traditional_mem_size = dram_base - traditional_mem_base;
return traditional_mem_size;
}
/*
* Calculate Intel Reserved Memory size based on
* PRMRR size, Me stolen memory and PTT selection.
*/
static size_t calculate_reserved_mem_size(uintptr_t dram_base,
const struct device *dev)
{
uintptr_t reserve_mem_base = dram_base;
size_t reserve_mem_size;
const struct soc_intel_icelake_config *config;
config = config_of(dev);
/* Get PRMRR size */
reserve_mem_base -= get_prmrr_size(reserve_mem_base, config);
/* Get Tracehub size */
reserve_mem_base -= get_imr_size();
/* Traditional Area Size */
reserve_mem_size = dram_base - reserve_mem_base;
return reserve_mem_size;
}
/*
* Fill up memory layout information
*
* Host Memory Map:
*
* +--------------------------+ TOUUD
@ -160,37 +54,12 @@ static size_t calculate_reserved_mem_size(uintptr_t dram_base,
* 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(size_t *reserved_mem_size)
{
uintptr_t dram_base;
const struct device *dev;
dev = pcidev_on_root(SA_DEV_SLOT_IGD, 0);
if (!dev)
die_with_post_code(POST_HW_INIT_FAILURE,
"ERROR - IGD device not found!");
/* Read TOLUD from Host Bridge offset */
dram_base = sa_get_tolud_base();
/* Get Intel Traditional Memory Range Size */
dram_base -= calculate_traditional_mem_size(dram_base, dev);
/* Get Intel Reserved Memory Range Size */
*reserved_mem_size = calculate_reserved_mem_size(dram_base, dev);
dram_base -= *reserved_mem_size;
return dram_base;
}
/* Fill up memory layout information */
void fill_soc_memmap_ebda(struct ebda_config *cfg)
{
size_t chipset_mem_size;
struct range_entry tolum;
cfg->tolum_base = calculate_dram_base(&chipset_mem_size);
cfg->reserved_mem_size = chipset_mem_size;
fsp_find_bootloader_tolum(&tolum);
cfg->cbmem_top = range_entry_end(&tolum);
}
void cbmem_top_init(void)
@ -232,5 +101,5 @@ void *cbmem_top_chipset(void)
retrieve_ebda_object(&ebda_cfg);
return (void *)(uintptr_t)ebda_cfg.tolum_base;
return (void *)(uintptr_t)ebda_cfg.cbmem_top;
}

View File

@ -19,9 +19,8 @@
#include <stdint.h>
struct ebda_config {
uint32_t signature; /* 0x00 - EBDA signature */
uint32_t tolum_base; /* 0x04 - coreboot memory start */
uint32_t reserved_mem_size; /* 0x08 - chipset reserved memory size */
uint32_t signature; /* EBDA signature */
uint32_t cbmem_top; /* coreboot memory start */
};
#endif

View File

@ -15,148 +15,15 @@
*/
#include <arch/romstage.h>
#include <arch/ebda.h>
#include <device/mmio.h>
#include <cbmem.h>
#include <console/console.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/smm.h>
#include <device/device.h>
#include <device/pci.h>
#include <fsp/util.h>
#include <intelblocks/ebda.h>
#include <intelblocks/systemagent.h>
#include <soc/msr.h>
#include <soc/pci_devs.h>
#include <soc/systemagent.h>
#include <stdlib.h>
#include "chip.h"
static bool is_ptt_enable(void)
{
if ((read32((void *)PTT_TXT_BASE_ADDRESS) & PTT_PRESENT) ==
PTT_PRESENT)
return true;
return false;
}
/* Calculate PTT size */
static size_t get_ptt_size(void)
{
/* Allocate 4KB for PTT if enabled */
return is_ptt_enable() ? 4*KiB : 0;
}
/* Calculate Trace Hub size */
static size_t get_tracehub_size(uintptr_t dram_base,
const struct soc_intel_skylake_config *config)
{
uintptr_t tracehub_base = dram_base;
size_t tracehub_size = 0;
if (!config->ProbelessTrace)
return 0;
/* GDXC MOT */
tracehub_base -= GDXC_MOT_MEMORY_SIZE;
/* Round down to natural boundary according to PSMI size */
tracehub_base = ALIGN_DOWN(tracehub_base, PSMI_BUFFER_AREA_SIZE);
/* GDXC IOT */
tracehub_base -= GDXC_IOT_MEMORY_SIZE;
/* PSMI buffer area */
tracehub_base -= PSMI_BUFFER_AREA_SIZE;
/* Tracehub Area Size */
tracehub_size = dram_base - tracehub_base;
return tracehub_size;
}
/* Calculate PRMRR size based on user input PRMRR size and alignment */
static size_t get_prmrr_size(uintptr_t dram_base,
const struct soc_intel_skylake_config *config)
{
uintptr_t prmrr_base = dram_base;
size_t prmrr_size = config->PrmrrSize;
if (!prmrr_size)
return 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 -= prmrr_size;
if (prmrr_size >= 32*MiB)
prmrr_base = ALIGN_DOWN(prmrr_base, 128*MiB);
/* PRMRR Area Size */
prmrr_size = dram_base - prmrr_base;
return prmrr_size;
}
/* Calculate Intel Traditional Memory size based on GSM, DSM, TSEG and DPR. */
static size_t calculate_traditional_mem_size(uintptr_t dram_base)
{
const struct device *igd_dev = pcidev_path_on_root(SA_DEVFN_IGD);
uintptr_t traditional_mem_base = dram_base;
size_t traditional_mem_size;
if (igd_dev && igd_dev->enabled) {
/* Read BDSM from Host Bridge */
traditional_mem_base -= sa_get_dsm_size();
/* Read BGSM from Host Bridge */
traditional_mem_base -= sa_get_gsm_size();
}
/* Get TSEG size */
traditional_mem_base -= sa_get_tseg_size();
/* Get DPR size */
if (CONFIG(SA_ENABLE_DPR))
traditional_mem_base -= sa_get_dpr_size();
/* Traditional Area Size */
traditional_mem_size = dram_base - traditional_mem_base;
return traditional_mem_size;
}
/*
* Calculate Intel Reserved Memory size based on
* PRMRR size, Trace Hub config and PTT selection.
*/
static size_t calculate_reserved_mem_size(uintptr_t dram_base)
{
const struct device *dev = pcidev_path_on_root(SA_DEVFN_ROOT);
uintptr_t reserve_mem_base = dram_base;
size_t reserve_mem_size;
const struct soc_intel_skylake_config *config;
config = config_of(dev);
/* Get PRMRR size */
reserve_mem_base -= get_prmrr_size(reserve_mem_base, config);
/* Get Tracehub size */
reserve_mem_base -= get_tracehub_size(reserve_mem_base, config);
/* Get PTT size */
reserve_mem_base -= get_ptt_size();
/* Traditional Area Size */
reserve_mem_size = dram_base - reserve_mem_base;
return reserve_mem_size;
}
/*
* Fill up memory layout information
*
* Host Memory Map:
*
* +--------------------------+ TOUUD
@ -174,8 +41,8 @@ static size_t calculate_reserved_mem_size(uintptr_t dram_base)
* +--------------------------+ DPR
* | PRM (C6DRAM/SGX) |
* +--------------------------+ PRMRR
* | Trace Memory |
* +--------------------------+ Probless Trace
* | ME Stolen Memory |
* +--------------------------+ ME Stolen
* | PTT |
* +--------------------------+ top_of_ram
* | Reserved - FSP/CBMEM |
@ -188,31 +55,12 @@ static size_t calculate_reserved_mem_size(uintptr_t dram_base)
* 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(size_t *reserved_mem_size)
{
uintptr_t dram_base;
/* Read TOLUD from Host Bridge offset */
dram_base = sa_get_tolud_base();
/* Get Intel Traditional Memory Range Size */
dram_base -= calculate_traditional_mem_size(dram_base);
/* Get Intel Reserved Memory Range Size */
*reserved_mem_size = calculate_reserved_mem_size(dram_base);
dram_base -= *reserved_mem_size;
return dram_base;
}
/* Fill up memory layout information */
void fill_soc_memmap_ebda(struct ebda_config *cfg)
{
size_t chipset_mem_size;
struct range_entry tolum;
cfg->tolum_base = calculate_dram_base(&chipset_mem_size);
cfg->reserved_mem_size = chipset_mem_size;
fsp_find_bootloader_tolum(&tolum);
cfg->cbmem_top = range_entry_end(&tolum);
}
void cbmem_top_init(void)
@ -254,5 +102,5 @@ void *cbmem_top_chipset(void)
retrieve_ebda_object(&ebda_cfg);
return (void *)(uintptr_t)ebda_cfg.tolum_base;
return (void *)(uintptr_t)ebda_cfg.cbmem_top;
}