summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/intel/fsp2_0/Makefile.inc2
-rw-r--r--src/lib/Makefile.inc1
-rw-r--r--src/lib/ext_stage_cache.c1
-rw-r--r--src/soc/intel/apollolake/Kconfig6
-rw-r--r--src/soc/intel/apollolake/cpu.c8
-rw-r--r--src/soc/intel/apollolake/include/soc/smm.h4
-rw-r--r--src/soc/intel/apollolake/memmap.c32
-rw-r--r--src/soc/intel/apollolake/romstage.c15
8 files changed, 63 insertions, 6 deletions
diff --git a/src/drivers/intel/fsp2_0/Makefile.inc b/src/drivers/intel/fsp2_0/Makefile.inc
index 3986fe68d1..beeec7cee9 100644
--- a/src/drivers/intel/fsp2_0/Makefile.inc
+++ b/src/drivers/intel/fsp2_0/Makefile.inc
@@ -37,6 +37,8 @@ ramstage-$(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM) += stage_cache.c
ramstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c
ramstage-y += util.c
+postcar-$(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM) += stage_cache.c
+
CPPFLAGS_common += -I$(src)/drivers/intel/fsp2_0/include
# Add FSP blobs into cbfs. SoC code may supply additional options with
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index 394491c769..67f8364aa8 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -159,6 +159,7 @@ ramstage-$(CONFIG_REG_SCRIPT) += reg_script.c
ifeq ($(CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM),y)
ramstage-y += ext_stage_cache.c
romstage-y += ext_stage_cache.c
+postcar-y += ext_stage_cache.c
else
ramstage-$(CONFIG_RELOCATABLE_RAMSTAGE) += cbmem_stage_cache.c
romstage-$(CONFIG_RELOCATABLE_RAMSTAGE) += cbmem_stage_cache.c
diff --git a/src/lib/ext_stage_cache.c b/src/lib/ext_stage_cache.c
index 770097f666..2a991889f4 100644
--- a/src/lib/ext_stage_cache.c
+++ b/src/lib/ext_stage_cache.c
@@ -126,3 +126,4 @@ static void stage_cache_setup(int is_recovery)
ROMSTAGE_CBMEM_INIT_HOOK(stage_cache_setup)
RAMSTAGE_CBMEM_INIT_HOOK(stage_cache_setup)
+POSTCAR_CBMEM_INIT_HOOK(stage_cache_setup)
diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig
index 3a23dbd0d2..6c178c31d4 100644
--- a/src/soc/intel/apollolake/Kconfig
+++ b/src/soc/intel/apollolake/Kconfig
@@ -26,6 +26,7 @@ config CPU_SPECIFIC_OPTIONS
select SOC_INTEL_COMMON_NHLT
# Misc options
select C_ENVIRONMENT_BOOTBLOCK
+ select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM if RELOCATABLE_RAMSTAGE
select COLLECT_TIMESTAMPS
select COMMON_FADT
select GENERIC_GPIO_LIB
@@ -34,7 +35,6 @@ config CPU_SPECIFIC_OPTIONS
select MMCONF_SUPPORT
select MMCONF_SUPPORT_DEFAULT
select NO_FIXED_XIP_ROM_SIZE
- select NO_STAGE_CACHE
select NO_XIP_EARLY_STAGES
select PARALLEL_MP
select PCIEXP_ASPM
@@ -254,4 +254,8 @@ config SPI_FLASH_INCLUDE_ALL_DRIVERS
bool
default n
+config SMM_RESERVED_SIZE
+ hex
+ default 0x100000
+
endif
diff --git a/src/soc/intel/apollolake/cpu.c b/src/soc/intel/apollolake/cpu.c
index f3cf050415..e67842c369 100644
--- a/src/soc/intel/apollolake/cpu.c
+++ b/src/soc/intel/apollolake/cpu.c
@@ -102,19 +102,23 @@ static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,
{
void *smm_base;
size_t smm_size;
+ void *handler_base;
+ size_t handler_size;
/* All range registers are aligned to 4KiB */
const uint32_t rmask = ~((1 << 12) - 1);
/* Initialize global tracking state. */
smm_region(&smm_base, &smm_size);
+ smm_subregion(SMM_SUBREGION_HANDLER, &handler_base, &handler_size);
+
relo_attrs.smbase = (uint32_t)smm_base;
relo_attrs.smrr_base = relo_attrs.smbase | MTRR_TYPE_WRBACK;
relo_attrs.smrr_mask = ~(smm_size - 1) & rmask;
relo_attrs.smrr_mask |= MTRR_PHYS_MASK_VALID;
- *perm_smbase = relo_attrs.smbase;
- *perm_smsize = smm_size - CONFIG_SMM_RESERVED_SIZE;
+ *perm_smbase = (uintptr_t)handler_base;
+ *perm_smsize = handler_size;
*smm_save_state_size = sizeof(em64t100_smm_state_save_area_t);
}
diff --git a/src/soc/intel/apollolake/include/soc/smm.h b/src/soc/intel/apollolake/include/soc/smm.h
index 7a9846eea2..740d02b114 100644
--- a/src/soc/intel/apollolake/include/soc/smm.h
+++ b/src/soc/intel/apollolake/include/soc/smm.h
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <soc/gpio.h>
+#include <fsp/memmap.h>
/* These helpers are for performing SMM relocation. */
void southbridge_clear_smi_status(void);
@@ -35,7 +36,4 @@ void southbridge_smm_enable_smi(void);
/* Mainboard handler for GPI SMIs*/
void mainboard_smi_gpi_handler(const struct gpi_status *sts);
-/* Fills in the arguments for the entire SMM region covered by chipset
- * protections. e.g. TSEG. */
-void smm_region(void **start, size_t *size);
#endif
diff --git a/src/soc/intel/apollolake/memmap.c b/src/soc/intel/apollolake/memmap.c
index ea6f447d43..cccbffd40d 100644
--- a/src/soc/intel/apollolake/memmap.c
+++ b/src/soc/intel/apollolake/memmap.c
@@ -24,6 +24,7 @@
#define __SIMPLE_DEVICE__
#include <arch/io.h>
+#include <assert.h>
#include <cbmem.h>
#include <device/pci.h>
#include <soc/northbridge.h>
@@ -52,3 +53,34 @@ void smm_region(void **start, size_t *size)
*start = (void *)smm_region_start();
*size = smm_region_size();
}
+
+int smm_subregion(int sub, void **start, size_t *size)
+{
+ uintptr_t sub_base;
+ size_t sub_size;
+ const size_t cache_size = CONFIG_SMM_RESERVED_SIZE;
+
+ sub_base = smm_region_start();
+ sub_size = smm_region_size();
+
+ assert(sub_size > CONFIG_SMM_RESERVED_SIZE);
+
+ switch (sub) {
+ case SMM_SUBREGION_HANDLER:
+ /* Handler starts at the base of TSEG. */
+ sub_size -= cache_size;
+ break;
+ case SMM_SUBREGION_CACHE:
+ /* External cache is in the middle of TSEG. */
+ sub_base += sub_size - cache_size;
+ sub_size = cache_size;
+ break;
+ default:
+ return -1;
+ }
+
+ *start = (void *)sub_base;
+ *size = sub_size;
+
+ return 0;
+}
diff --git a/src/soc/intel/apollolake/romstage.c b/src/soc/intel/apollolake/romstage.c
index b9733defa3..2384ceb1cf 100644
--- a/src/soc/intel/apollolake/romstage.c
+++ b/src/soc/intel/apollolake/romstage.c
@@ -29,6 +29,7 @@
#include <device/pci_def.h>
#include <device/resource.h>
#include <fsp/api.h>
+#include <fsp/memmap.h>
#include <fsp/util.h>
#include <soc/iomap.h>
#include <soc/northbridge.h>
@@ -105,6 +106,9 @@ asmlinkage void car_stage_entry(void)
uintptr_t top_of_ram;
bool s3wake;
struct chipset_power_state *ps = car_get_var_ptr(&power_state);
+ void *smm_base;
+ size_t smm_size;
+ uintptr_t tseg_base;
timestamp_add_now(TS_START_ROMSTAGE);
@@ -135,6 +139,17 @@ asmlinkage void car_stage_entry(void)
postcar_frame_add_mtrr(&pcf, -CONFIG_ROM_SIZE, CONFIG_ROM_SIZE,
MTRR_TYPE_WRPROT);
+ /*
+ * Cache the TSEG region at the top of ram. This region is
+ * not restricted to SMM mode until SMM has been relocated.
+ * By setting the region to cacheable it provides faster access
+ * when relocating the SMM handler as well as using the TSEG
+ * region for other purposes.
+ */
+ smm_region(&smm_base, &smm_size);
+ tseg_base = (uintptr_t)smm_base;
+ postcar_frame_add_mtrr(&pcf, tseg_base, smm_size, MTRR_TYPE_WRBACK);
+
run_postcar_phase(&pcf);
}