diff options
author | Aaron Durbin <adurbin@chromium.org> | 2018-04-18 01:00:27 -0600 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2018-04-25 15:32:56 +0000 |
commit | 0f35af8f4293d004d634c24fe029287b598326e9 (patch) | |
tree | 0ebd81f209a967a73b7be37ea6b21d5e5b5cc207 /src/cpu | |
parent | cfb1680a88fb0a869ad7cb7dfccf27120af98d15 (diff) |
arch/x86: add support for cache-as-ram paging
Processors, such as glk, need to have paging enabled while
in cache-as-ram mode because the front end is agressive about
fetching lines into the L1I cache. If the line is dirty and in
the L1D then it writes it back to "memory". However, in this case
there is no backing store so the cache-as-ram data that was written
back transforms to all 0xff's when read back in causing corruption.
In order to mitigate the failure add x86 architecture support for
enabling paging while in cache-as-ram mode. A Kconfig variable,
NUM_CAR_PAGE_TABLE_PAGES, determines the number of pages to carve
out for page tables within the cache-as-ram region. Additionally,
the page directory pointer table is also carved out of cache-as-ram.
Both areas are allocated from the persist-across-stages region
of cache-as-ram so all stages utilizing cache-as-ram don't corrupt
the page tables.
The two paging-related areas are loaded by calling
paging_enable_for_car() with the names of cbfs files to load the
initial paging structures from.
BUG=b:72728953
Change-Id: I7ea6e3e7be94a0ef9fd3205ce848e539bfbdcb6e
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://review.coreboot.org/25717
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
Reviewed-by: Justin TerAvest <teravest@chromium.org>
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/x86/pae/pgtbl.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/cpu/x86/pae/pgtbl.c b/src/cpu/x86/pae/pgtbl.c index cd03547ef8..c272b2da1c 100644 --- a/src/cpu/x86/pae/pgtbl.c +++ b/src/cpu/x86/pae/pgtbl.c @@ -13,6 +13,7 @@ * GNU General Public License for more details. */ +#include <cbfs.h> #include <compiler.h> #include <console/console.h> #include <cpu/cpu.h> @@ -22,6 +23,7 @@ #include <cpu/x86/pae.h> #include <rules.h> #include <string.h> +#include <symbols.h> void paging_enable_pae_cr3(uintptr_t cr3) { @@ -169,3 +171,48 @@ void paging_set_default_pat(void) PAT_ENCODE(UC_MINUS, 6) | PAT_ENCODE(WT, 7); paging_set_pat(pat); } + +static int read_from_cbfs(const char *name, void *buf, size_t size) +{ + struct cbfsf fh; + struct region_device rdev; + size_t rdev_sz; + + if (cbfs_boot_locate(&fh, name, NULL)) + return -1; + + cbfs_file_data(&rdev, &fh); + + rdev_sz = region_device_sz(&rdev); + + if (size < rdev_sz) { + printk(BIOS_ERR, "%s region too small to load: %zx < %zx\n", + name, size, rdev_sz); + return -1; + } + + if (rdev_readat(&rdev, buf, 0, rdev_sz) != rdev_sz) + return -1; + + return 0; +} + +int paging_enable_for_car(const char *pdpt_name, const char *pt_name) +{ + if (!ENV_CACHE_AS_RAM) + return -1; + + if (read_from_cbfs(pdpt_name, _pdpt, _pdpt_size)) { + printk(BIOS_ERR, "Couldn't load pdpt\n"); + return -1; + } + + if (read_from_cbfs(pt_name, _pagetables, _pagetables_size)) { + printk(BIOS_ERR, "Couldn't load page tables\n"); + return -1; + } + + paging_enable_pae_cr3((uintptr_t)_pdpt); + + return 0; +} |