aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/apollolake/romstage.c
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2018-04-18 01:05:25 -0600
committerAaron Durbin <adurbin@chromium.org>2018-04-27 18:48:10 +0000
commit5c9df70031b7d14c01b8bf261510cc9a8828eabc (patch)
treedd995f67f6551026a5591377dcf19edf7a79dbc0 /src/soc/intel/apollolake/romstage.c
parent9b41bae92129e579f2fbd003aa7e5e7b971cb881 (diff)
soc/intel/apollolake: enable cache-as-ram paging for glk
Add support and enalbe cache-as-ram paging for glk to work around a cache-as-ram corruption issue. glk executes verstage, romstage, and FSP-M directly out of cache-as-ram (just like apl). However, the front end on glk is very agressive about pulling cache lines into L1I for potential execution. When the snoops hit in the L1D and the cache lines are dirty the processor writes the line back. However, there is no backing store for the dirty lines to go. As such when the line is pulled back in the value is all 0xff's, corrupting cache-as-ram. To fix the issue one needs to enable paging with NX (no execute) permissions which prevents the above actions from happening because the TLB will indicate that shouldn't be fetched into the instruction cache since data will be marked no execute. The generated page tables are added to cbfs and only added to the COREBOOT cbfs as they are only consumed in the early cache-as-ram stages. The page tables generated with: $ go run util/x86/x86_page_tables.go \ --iomap_file=src/soc/intel/apollolake/glk_page_map.txt \ --metadata_base_address=0xfef00000 \ --pdpt_output_c_file=src/soc/intel/apollolake/pdpt.c \ --pt_output_c_file=src/soc/intel/apollolake/pt.c Merged address space: 00000000d0000000 -- 00000000fef00000 UC NX : 375 big 256 small 00000000fef00000 -- 00000000fef20000 WB NX : 0 big 32 small 00000000fef20000 -- 00000000fefc0000 WB : 0 big 160 small 00000000fefc0000 -- 00000000ff000000 WB NX : 0 big 64 small 00000000ff000000 -- 0000000100000000 WP : 8 big 0 small Total Pages of page tables: 5 Pages linked using base address of 0xfef00000. BUG=b:72728953 Change-Id: Icde9cc0bf5079bb5821f4e59eb61e939c13d7062 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://review.coreboot.org/25719 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Furquan Shaikh <furquan@google.com>
Diffstat (limited to 'src/soc/intel/apollolake/romstage.c')
-rw-r--r--src/soc/intel/apollolake/romstage.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/soc/intel/apollolake/romstage.c b/src/soc/intel/apollolake/romstage.c
index 6a2007e937..bccfc16ba6 100644
--- a/src/soc/intel/apollolake/romstage.c
+++ b/src/soc/intel/apollolake/romstage.c
@@ -27,6 +27,7 @@
#include <compiler.h>
#include <console/console.h>
#include <cpu/x86/mtrr.h>
+#include <cpu/x86/pae.h>
#include <device/pci_def.h>
#include <device/resource.h>
#include <intelblocks/lpc_lib.h>
@@ -41,6 +42,7 @@
#include <reset.h>
#include <soc/cpu.h>
#include <soc/iomap.h>
+#include <soc/meminit.h>
#include <soc/systemagent.h>
#include <soc/pci_devs.h>
#include <soc/pm.h>
@@ -246,6 +248,13 @@ asmlinkage void car_stage_entry(void)
tseg_base = (uintptr_t)smm_base;
postcar_frame_add_mtrr(&pcf, tseg_base, smm_size, MTRR_TYPE_WRBACK);
+ /* Ensure TSEG has mappings. */
+ if (IS_ENABLED(CONFIG_PAGING_IN_CACHE_AS_RAM)) {
+ if (paging_identity_map_addr(tseg_base, smm_size, PAT_WB))
+ printk(BIOS_ERR, "Unable to map TSEG: %lx--%lx\n",
+ tseg_base, tseg_base + smm_size);
+ }
+
run_postcar_phase(&pcf);
}
@@ -330,6 +339,40 @@ static void parse_devicetree_setting(FSPM_UPD *m_upd)
#endif
}
+static void prepare_fspm_pages(void)
+{
+ const size_t mib128 = 128 * MiB;
+ uintptr_t base;
+ /* All in units of MiB */
+ size_t mem_sz;
+ size_t iohole_sz;
+ size_t low_mem_sz;
+
+ mem_sz = memory_in_system_in_mib();
+
+ if (!mem_sz) {
+ printk(BIOS_ERR, "No memory in system! FSP will hang...\n");
+ return;
+ }
+
+ iohole_sz = iohole_in_mib();
+
+ /* Mark pages as WB where FSP will write. One region will be in cbmem,
+ but it's not clear what else FSP is writing to. Try to make the best
+ calculation. */
+ low_mem_sz = 4 * (GiB / MiB) - iohole_sz;
+
+ if (low_mem_sz > mem_sz)
+ low_mem_sz = mem_sz;
+
+ /* Assume all accesses are within 128MiB of the crude low memory
+ calculation above. */
+ base = low_mem_sz * MiB - mib128;
+ if (paging_identity_map_addr(base, mib128, PAT_WB))
+ printk(BIOS_ERR, "Unable to map %lx--%lx\n", base,
+ base + mib128);
+}
+
void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
{
struct region_device rdev;
@@ -382,6 +425,9 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
}
car_set_var(fsp_version, version);
+
+ if (IS_ENABLED(CONFIG_PAGING_IN_CACHE_AS_RAM))
+ prepare_fspm_pages();
}
__weak